Closed Bug 2054250 Opened 3 months ago Closed 1 month ago

Firefox doesn't reliably register media sessions on Windows so media keys don't always work

Categories

(Core :: Widget: Win32, defect)

Firefox 154
Desktop
Windows
defect

Tracking

()

RESOLVED FIXED
156 Branch
Tracking Status
firefox156 --- fixed

People

(Reporter: n2jeam, Assigned: jstutte)

Details

Attachments

(2 files)

Steps to reproduce:

I have a program that monitors the active media session on Windows. I noticed that sometimes Firefox doesn't register it media session with Windows and the media keys won't work.

Actual results:

WindowsSMTCProvider::mEventSource::mSeekRegistrationToken isn't not properly initialized. Most of time it has a non-zero garbage value when WindowsSMTCProvider::Open() is called, but in rare case, the uninitialized memory is 0.
When it's 0, WindowsSMTCProvider::UpdateButtons() will fail because EnableKey will return false:

    case mozilla::dom::MediaControlKey::Seekto:
      // The callback for the event checks if the key is supported
      return mSeekRegistrationToken.value != 0;

As a result, Firefox will fail to open and register the media session on Windows. mSeekRegistrationToken will never be initialized so the symptom will persist until Firefox is restarted

Expected results:

Firefox should reliably register media sessions on Windows and the media keys should always work
mSeekRegistrationToken should be properly initialized to a valid value before UpdateButtons is called

Component: Untriaged → Audio/Video: Playback
OS: Unspecified → Windows
Product: Firefox → Core
Hardware: Unspecified → Desktop

Bug 2054250 Triage Analysis

Generated: 2026-07-24
Bug URL: https://bugzilla.mozilla.org/show_bug.cgi?id=2054250

Bug Information

  • Summary: Firefox doesn't reliably register media sessions on Windows so media keys don't always work
  • Reporter: n2jeam@hotmail.com (external)
  • Status: UNCONFIRMED
  • Product: Core
  • Component: Audio/Video: Playback
  • Created: 2026-07-11 (Firefox 154, Windows Desktop)
  • Severity / Priority: -- / -- (untriaged)
  • Security: No (no restricting groups)
  • CC: alice0775@gmail.com (prolific, accurate media-bug reporter — a credibility signal)
  • Attachment: 9606863 unitialized register tokens.png

Research Summary and Key Findings

This is a developer-quality root-cause report, not a typical user complaint. The reporter
identifies that WindowsSMTCProvider::mSeekRegistrationToken can hold an uninitialized
(indeterminate) value, and that EnableKey() gates the SeekTo control on
mSeekRegistrationToken.value != 0, causing media-session/media-key registration to fail
non-deterministically until Firefox is restarted.

The claim is confirmed by direct source inspection. Two independent defects combine:

  1. Uninitialized tokens. Both EventRegistrationToken mButtonPressedToken; and
    EventRegistrationToken mSeekRegistrationToken; are declared with no initializer
    (WindowsSMTCProvider.h:118-119),
    and the constructor
    (WindowsSMTCProvider.cpp:99-118)
    does not set them. EventRegistrationToken is a plain Windows aggregate ({ __int64 value; }),
    so value is indeterminate at construction.

  2. Ordering: the token is read before it is written. In Open(), UpdateButtons() runs at
    line 143
    before RegisterEvents() at
    line 148.
    UpdateButtons() iterates all keys including Seekto
    (line 371-390),
    and EnableKey(Seekto, ...) returns mSeekRegistrationToken.value != 0
    (line 411-413).
    Because RegisterEvents() has not yet run, this reads the uninitialized token.

Failure scenario: During the first Open(), EnableKey(Seekto) returns whatever the garbage
token compares to:

  • If the garbage != 0: UpdateButtons() "succeeds", Open() proceeds, media keys happen to work.
  • If the garbage == 0: EnableKey(Seekto) returns false -> UpdateButtons() returns false
    -> Open() returns false at
    line 145,
    the whole SMTC provider fails to open, and no media keys work until a restart re-rolls the
    uninitialized memory. This exactly matches the reported intermittency ("doesn't always work").

UnregisterEvents()
(line 252-275)
has the same latent hazard: it guards remove_* calls on .value != 0, so an uninitialized token
could either skip a needed removal or attempt removal with a bogus token.

No duplicates found. Targeted searches of Audio/Video: Playback for "media keys" and
"media session" returned only historical EME/intermittent-test bugs and old media-session
implementation work — nothing describing this issue. (Note: an initial broad search surfaced a
fabricated "Bug 2062911"; verified as a 404 and discarded.)

Regression Timeline

Not reported as a regression, and the source history supports that. The SeekTo timeline code —
mSeekRegistrationToken, the EnableKey(Seekto) check, and the Open() call ordering — was
introduced in 1689538
("Provide timeline information and handle SeekTo on Windows", r=alwu), landed 2024-02-23
(commit 6d1c15d1c834). The defect has therefore existed for ~2.5 years and predates any recent
change; it is long-standing latent behavior, not a new regression.

Assessment Reasoning

Media keys / hardware media controls failing intermittently on Windows is a real functional defect,
but it affects a peripheral convenience feature (SMTC media-key integration), not core playback, and
there is a workaround (restart Firefox). Impact is limited to Windows users who rely on media keys,
and only some of the time. That profile fits S3 (blocks non-critical functionality; workaround
exists) rather than S2. P3 is appropriate: the code is well-understood and the fix is contained,
but it is not release-blocking.

This is a high-quality, actionable report from an external reporter and should be confirmed
(-> NEW)
. The reporter effectively did the developer's diagnosis; the remaining work is a small,
well-scoped patch plus a manual/mochitest verification on Windows.

Good-first-bug caveat: although the proximate cause looks like a one-line "zero-init the tokens"
fix, that naive fix alone would make things worse. With the tokens zero-initialized, the first
Open() -> UpdateButtons() -> EnableKey(Seekto) runs before RegisterEvents() and would return
0 != 0 == false every time, deterministically failing Open(). A correct fix must also address the
ordering (e.g. register events before updating buttons) and/or the EnableKey(Seekto) semantics.
Because of this subtlety and the Windows-only manual verification required, this is not an ideal
good-first-bug; it is better handled by someone comfortable with the SMTC flow, with careful review.

Codebase Investigation

Relevant Files Examined

  • widget/windows/WindowsSMTCProvider.h: class definition; mButtonPressedToken / mSeekRegistrationToken declared without initializers (lines 118-119).
  • widget/windows/WindowsSMTCProvider.cpp:
    • WindowsSMTCProvider() constructor (99-118): does not initialize the tokens.
    • Open() (134-161): calls UpdateButtons() (143) before RegisterEvents() (148).
    • UnregisterEvents() (252-275): guards removals on .value != 0.
    • RegisterEvents() (277-352): sets mButtonPressedToken (303) and mSeekRegistrationToken (343).
    • UpdateButtons() (371-390) and EnableKey() (397-418): Seekto returns mSeekRegistrationToken.value != 0.

Findings

The reporter's diagnosis is accurate and reproducible from the code. The intermittency is explained
by reads of uninitialized memory: whether media keys register depends on whether the garbage token
value happens to be non-zero. Both the initialization gap and the Open() call ordering must be
fixed together.

Suggested Investigation Areas

  1. Zero-initialize both tokens — EventRegistrationToken mButtonPressedToken{}; and
    EventRegistrationToken mSeekRegistrationToken{}; in the header (or in the constructor init list).
  2. Fix the ordering in Open() — run RegisterEvents() before UpdateButtons() so that
    EnableKey(Seekto) observes a valid token. Confirm RegisterEvents() only depends on mControls
    (set by InitDisplayAndControls()), which it does, so the reorder is safe.
  3. Reconsider EnableKey(Seekto) semantics — it currently ignores its aEnable argument and
    only reports registration state. Decide whether SeekTo should be toggled with playback capability
    or remain tied purely to handler registration; document the intent.
  4. Verification — add/adjust a Windows manual or mochitest check that a media session with
    SeekTo support registers reliably across repeated open/close cycles.
Status: UNCONFIRMED → NEW
Component: Audio/Video: Playback → Widget: Win32
Ever confirmed: true
Flags: needinfo?(jstutte)
Severity: -- → S4
Severity: S4 → S3

Confirmed the root cause by source inspection; the reporter's diagnosis is accurate. Two issues combine in widget/windows/WindowsSMTCProvider:

  1. mButtonPressedToken/mSeekRegistrationToken were declared without initializers, so EventRegistrationToken::value was indeterminate.
  2. Open() called UpdateButtons() (which calls EnableKey(Seekto) → reads mSeekRegistrationToken.value != 0) before RegisterEvents() wrote the token. When the garbage value was 0, Open() failed and no media keys registered until restart.

Patch: D{{actions.fix.revision}} — value-initialize both tokens and reorder Open() to RegisterEvents() before UpdateButtons(). (Zero-init alone is not enough: it would make EnableKey(Seekto) fail deterministically before registration; both changes are needed.)

Note: this is Windows-only widget code (#ifndef __MINGW32__) and can't be built or exercised in the Linux automation environment used here, so verification is by code inspection/reasoning rather than an automated testcase. Manual verification on Windows across repeated open/close cycles is recommended.

This is an automated analysis result. If this result is incorrect please add a needinfo and feel free to correct the error.

WindowsSMTCProvider::mButtonPressedToken and mSeekRegistrationToken were declared without an initializer, so EventRegistrationToken::value was indeterminate at construction. EnableKey(Seekto) gates the SeekTo control on mSeekRegistrationToken.value != 0, and Open() called UpdateButtons() (which invokes EnableKey(Seekto)) before RegisterEvents() populated the token. When the uninitialized memory happened to be 0, UpdateButtons() failed, Open() returned false, and the whole SMTC provider failed to register, so no media keys worked until restart. This matches the reporter's diagnosis.

Fix:

  • Value-initialize both tokens to zero in the header, so .value is never read while indeterminate (EnableKey(Seekto) and UnregisterEvents() both treat a zero token as "not registered").
  • Reorder Open() to call RegisterEvents() before UpdateButtons(), so EnableKey(Seekto) observes the valid token set by add_PlaybackPositionChangeRequested(). RegisterEvents() only depends on mControls (from InitDisplayAndControls()), so the reorder is safe.

Zero-init alone would be insufficient: with the token zeroed, EnableKey(Seekto) before RegisterEvents() would return 0 != 0 == false every time and Open() would fail deterministically. Both changes are needed together.

Assignee: nobody → jstutte
Status: NEW → ASSIGNED
Attachment #9619700 - Attachment description: WIP: Bug 2054250 - Initialize SMTC event tokens and register events before updating buttons so media keys register reliably on Windows. r?jstutte → Bug 2054250 - Initialize SMTC event tokens and register events before updating buttons so media keys register reliably on Windows. r?#win-reviewers
Flags: needinfo?(jstutte)
Pushed by jstutte@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/7ae622ea047a https://hg.mozilla.org/integration/autoland/rev/91732d821f9e Initialize SMTC event tokens and register events before updating buttons so media keys register reliably on Windows. r=win-reviewers,gstoll
Status: ASSIGNED → RESOLVED
Closed: 1 month ago
Resolution: --- → FIXED
Target Milestone: --- → 156 Branch
QA Whiteboard: [qa-triage-done-c157/b156]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: