Do not pause the Player when element is moved to a different document [chromium/src : main]

0 views
Skip to first unread message

Javier Fernandez (Gerrit)

unread,
May 10, 2026, 4:40:27 PMMay 10
to Dale Curtis, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, srirama chandra sekhar, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, eric.c...@apple.com, feature-me...@chromium.org
Attention needed from Dale Curtis

New activity on the change

Open in Gerrit

Related details

Attention is currently required from:
  • Dale Curtis
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I476b72010688f529a8fdfe8aa6c37625ba073fa3
Gerrit-Change-Number: 7828889
Gerrit-PatchSet: 2
Gerrit-Owner: Javier Fernandez <jfern...@igalia.com>
Gerrit-Reviewer: Dale Curtis <dalec...@chromium.org>
Gerrit-Reviewer: Javier Fernandez <jfern...@igalia.com>
Gerrit-CC: srirama chandra sekhar <srir...@samsung.com>
Gerrit-Attention: Dale Curtis <dalec...@chromium.org>
Gerrit-Comment-Date: Sun, 10 May 2026 20:40:06 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Javier Fernandez (Gerrit)

unread,
May 11, 2026, 7:59:30 AMMay 11
to Dale Curtis, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, srirama chandra sekhar, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, eric.c...@apple.com, feature-me...@chromium.org
Attention needed from Dale Curtis and Javier Fernandez

Message from Javier Fernandez

Set Ready For Review

Open in Gerrit

Related details

Attention is currently required from:
  • Dale Curtis
  • Javier Fernandez
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I476b72010688f529a8fdfe8aa6c37625ba073fa3
Gerrit-Change-Number: 7828889
Gerrit-PatchSet: 4
Gerrit-Owner: Javier Fernandez <jfern...@igalia.com>
Gerrit-Reviewer: Dale Curtis <dalec...@chromium.org>
Gerrit-Reviewer: Javier Fernandez <jfern...@igalia.com>
Gerrit-CC: srirama chandra sekhar <srir...@samsung.com>
Gerrit-Attention: Dale Curtis <dalec...@chromium.org>
Gerrit-Attention: Javier Fernandez <jfern...@igalia.com>
Gerrit-Comment-Date: Mon, 11 May 2026 11:59:15 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Dale Curtis (Gerrit)

unread,
May 11, 2026, 12:58:58 PMMay 11
to Javier Fernandez, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, srirama chandra sekhar, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, eric.c...@apple.com, feature-me...@chromium.org
Attention needed from Javier Fernandez

Dale Curtis added 1 comment

File third_party/blink/renderer/core/html/media/html_media_element.cc
Line 718, Patchset 4 (Latest): paused_ = false;
Dale Curtis . unresolved

Play/pause state is pretty complicated. I'm not sure it's sufficient to just set this back to false. It probably at least needs `SetPaused(false)` and more likely `PlayInternal`. Can you investigate a bit more here?

Open in Gerrit

Related details

Attention is currently required from:
  • Javier Fernandez
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I476b72010688f529a8fdfe8aa6c37625ba073fa3
    Gerrit-Change-Number: 7828889
    Gerrit-PatchSet: 4
    Gerrit-Owner: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Reviewer: Dale Curtis <dalec...@chromium.org>
    Gerrit-Reviewer: Javier Fernandez <jfern...@igalia.com>
    Gerrit-CC: srirama chandra sekhar <srir...@samsung.com>
    Gerrit-Attention: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Comment-Date: Mon, 11 May 2026 16:58:38 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Javier Fernandez (Gerrit)

    unread,
    May 11, 2026, 1:12:13 PMMay 11
    to Dale Curtis, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, srirama chandra sekhar, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, eric.c...@apple.com, feature-me...@chromium.org
    Attention needed from Dale Curtis

    Javier Fernandez added 1 comment

    File third_party/blink/renderer/core/html/media/html_media_element.cc
    Dale Curtis . unresolved

    Play/pause state is pretty complicated. I'm not sure it's sufficient to just set this back to false. It probably at least needs `SetPaused(false)` and more likely `PlayInternal`. Can you investigate a bit more here?

    Javier Fernandez

    I see, I've been perhaps too focused on the specific test failing. I may need a more complete test case to understand all the implications of the play / pause logic. Any idea is welcome.

    I'm going to investigate it further in any case. Thanks for the review.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Dale Curtis
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I476b72010688f529a8fdfe8aa6c37625ba073fa3
    Gerrit-Change-Number: 7828889
    Gerrit-PatchSet: 4
    Gerrit-Owner: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Reviewer: Dale Curtis <dalec...@chromium.org>
    Gerrit-Reviewer: Javier Fernandez <jfern...@igalia.com>
    Gerrit-CC: srirama chandra sekhar <srir...@samsung.com>
    Gerrit-Attention: Dale Curtis <dalec...@chromium.org>
    Gerrit-Comment-Date: Mon, 11 May 2026 17:12:00 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Dale Curtis <dalec...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Javier Fernandez (Gerrit)

    unread,
    May 28, 2026, 5:18:43 AM (4 days ago) May 28
    to Dale Curtis, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, srirama chandra sekhar, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, eric.c...@apple.com, feature-me...@chromium.org
    Attention needed from Dale Curtis and Javier Fernandez

    Message from Javier Fernandez

    Set Ready For Review

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Dale Curtis
    • Javier Fernandez
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I476b72010688f529a8fdfe8aa6c37625ba073fa3
    Gerrit-Change-Number: 7828889
    Gerrit-PatchSet: 5
    Gerrit-Owner: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Reviewer: Dale Curtis <dalec...@chromium.org>
    Gerrit-Reviewer: Javier Fernandez <jfern...@igalia.com>
    Gerrit-CC: srirama chandra sekhar <srir...@samsung.com>
    Gerrit-Attention: Dale Curtis <dalec...@chromium.org>
    Gerrit-Attention: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Comment-Date: Thu, 28 May 2026 09:18:26 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Javier Fernandez (Gerrit)

    unread,
    May 28, 2026, 5:20:50 AM (4 days ago) May 28
    to Dale Curtis, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, srirama chandra sekhar, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, eric.c...@apple.com, feature-me...@chromium.org
    Attention needed from Dale Curtis

    Javier Fernandez added 2 comments

    Patchset-level comments
    File-level comment, Patchset 5 (Latest):
    Javier Fernandez . resolved

    Hi dalecurtis@

    I did an analysis of the paused / playing transition logic and a proposal to restore the "playing" state in a more solid way.

    File third_party/blink/renderer/core/html/media/html_media_element.cc
    Line 718, Patchset 4: paused_ = false;
    Dale Curtis . unresolved

    Play/pause state is pretty complicated. I'm not sure it's sufficient to just set this back to false. It probably at least needs `SetPaused(false)` and more likely `PlayInternal`. Can you investigate a bit more here?

    Javier Fernandez

    I see, I've been perhaps too focused on the specific test failing. I may need a more complete test case to understand all the implications of the play / pause logic. Any idea is welcome.

    I'm going to investigate it further in any case. Thanks for the review.

    Javier Fernandez

    It seems that SetPaused is the only, by design, way of modifying the paused_ flag. This is because SetPaused, triggers some PseudoState changes that causes the required pseudo-style invalidations.

    Another consequence of the current approach is that playing_ is never restored, after being modified by ResetMediaPlayerAndMediasource method.

    There is another problem related to the play promises, rejected as part of the InvokeLoadAlgorithm (Step 4.6 in the spec). Modifying the paused_ flag manually doesn't re-create those promises.

    We can use PlayInternal as a way to initiate the paused->unpaused transition, which internally calls to SetPause(false) if needed. It calls ResetMediaPlayerAndMediaSource so that the promises are recreated, and UpdatePlayStte() to indicate the WebMediaPlayer to play.

    The proposed approach has the drawback that it generates a "play" event, and this goes against the spec, which states that a doc-move should be transparent and shouldn't generate any event. However, invoking the load algorithm is already generating some events, like 'emptied' and 'loadstart', so I think we are already assuming that compromise.

    A more spec-compliant approach would be to implement a new helper to restore the pause stated after attaching to a new frame, so that it does SetPaused(false) + SetShowPosterFlag(false) + UpdatePlayState(), but without scheduling play / playing events. However, I see this a more complex approach and more likely to cause regressions.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Dale Curtis
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I476b72010688f529a8fdfe8aa6c37625ba073fa3
    Gerrit-Change-Number: 7828889
    Gerrit-PatchSet: 5
    Gerrit-Owner: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Reviewer: Dale Curtis <dalec...@chromium.org>
    Gerrit-Reviewer: Javier Fernandez <jfern...@igalia.com>
    Gerrit-CC: srirama chandra sekhar <srir...@samsung.com>
    Gerrit-Attention: Dale Curtis <dalec...@chromium.org>
    Gerrit-Comment-Date: Thu, 28 May 2026 09:20:35 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Dale Curtis <dalec...@chromium.org>
    Comment-In-Reply-To: Javier Fernandez <jfern...@igalia.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Dale Curtis (Gerrit)

    unread,
    May 28, 2026, 3:23:27 PM (4 days ago) May 28
    to Javier Fernandez, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, srirama chandra sekhar, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, eric.c...@apple.com, feature-me...@chromium.org
    Attention needed from Javier Fernandez

    Dale Curtis added 3 comments

    File third_party/blink/renderer/core/html/media/html_media_element.cc
    Line 718, Patchset 4: paused_ = false;
    Dale Curtis . unresolved

    Play/pause state is pretty complicated. I'm not sure it's sufficient to just set this back to false. It probably at least needs `SetPaused(false)` and more likely `PlayInternal`. Can you investigate a bit more here?

    Javier Fernandez

    I see, I've been perhaps too focused on the specific test failing. I may need a more complete test case to understand all the implications of the play / pause logic. Any idea is welcome.

    I'm going to investigate it further in any case. Thanks for the review.

    Javier Fernandez

    It seems that SetPaused is the only, by design, way of modifying the paused_ flag. This is because SetPaused, triggers some PseudoState changes that causes the required pseudo-style invalidations.

    Another consequence of the current approach is that playing_ is never restored, after being modified by ResetMediaPlayerAndMediasource method.

    There is another problem related to the play promises, rejected as part of the InvokeLoadAlgorithm (Step 4.6 in the spec). Modifying the paused_ flag manually doesn't re-create those promises.

    We can use PlayInternal as a way to initiate the paused->unpaused transition, which internally calls to SetPause(false) if needed. It calls ResetMediaPlayerAndMediaSource so that the promises are recreated, and UpdatePlayStte() to indicate the WebMediaPlayer to play.

    The proposed approach has the drawback that it generates a "play" event, and this goes against the spec, which states that a doc-move should be transparent and shouldn't generate any event. However, invoking the load algorithm is already generating some events, like 'emptied' and 'loadstart', so I think we are already assuming that compromise.

    A more spec-compliant approach would be to implement a new helper to restore the pause stated after attaching to a new frame, so that it does SetPaused(false) + SetShowPosterFlag(false) + UpdatePlayState(), but without scheduling play / playing events. However, I see this a more complex approach and more likely to cause regressions.

    Dale Curtis

    This seems an okay compromise, but the wpts probably shouldn't test for this since it's not part of the spec? This does result in some additional issues though with play promises that the review agent noticed.

    Line 722, Patchset 5 (Latest): if (was_playing) {
    Dale Curtis . unresolved

    As currently implemented, this logic will still result in the rejection of pending play promises with AbortError. InvokeLoadAlgorithm() (at line 721) checks if !paused_ and, if so, triggers RejectPlayPromises(). Since PlayInternal() is called after the algorithm runs, it cannot resolve the promises that were already settled by the rejection logic.

    If the intention is to preserve pending promises, you might want to manually set paused_ = true before calling InvokeLoadAlgorithm() to bypass step 4.6, and then let PlayInternal() handle the state restoration. Note that the WPT test doesn't catch this because it waits for the promise to resolve before moving the node.

    File third_party/blink/renderer/core/html/media/html_media_element_test.cc
    Line 1941, Patchset 5 (Latest): new_dummy_page_holder->GetDocument().adoptNode(Media(), ASSERT_NO_EXCEPTION);
    Dale Curtis . unresolved

    In these tests, you are calling adoptNode() but not actually inserting the node into the new document tree. While this is sufficient for synchronous checks, adoptNode() leaves the node disconnected. This means when the OnRemovedFromDocumentTimer eventually fires, isConnected() will be false and the element will pause. To more accurately simulate a document move and verify the timer behavior, it is better to append the node to the new document's body.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Javier Fernandez
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I476b72010688f529a8fdfe8aa6c37625ba073fa3
    Gerrit-Change-Number: 7828889
    Gerrit-PatchSet: 5
    Gerrit-Owner: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Reviewer: Dale Curtis <dalec...@chromium.org>
    Gerrit-Reviewer: Javier Fernandez <jfern...@igalia.com>
    Gerrit-CC: srirama chandra sekhar <srir...@samsung.com>
    Gerrit-Attention: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Comment-Date: Thu, 28 May 2026 19:23:08 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Javier Fernandez (Gerrit)

    unread,
    May 29, 2026, 6:19:28 PM (3 days ago) May 29
    to Dale Curtis, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, srirama chandra sekhar, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, eric.c...@apple.com, feature-me...@chromium.org
    Attention needed from Dale Curtis

    Javier Fernandez added 4 comments

    Patchset-level comments
    File-level comment, Patchset 6 (Latest):
    Javier Fernandez . resolved

    Thanks for the review.
    See my comments inline

    File third_party/blink/renderer/core/html/media/html_media_element.cc
    Line 718, Patchset 4: paused_ = false;
    Dale Curtis . unresolved

    Play/pause state is pretty complicated. I'm not sure it's sufficient to just set this back to false. It probably at least needs `SetPaused(false)` and more likely `PlayInternal`. Can you investigate a bit more here?

    Javier Fernandez

    I see, I've been perhaps too focused on the specific test failing. I may need a more complete test case to understand all the implications of the play / pause logic. Any idea is welcome.

    I'm going to investigate it further in any case. Thanks for the review.

    Javier Fernandez

    It seems that SetPaused is the only, by design, way of modifying the paused_ flag. This is because SetPaused, triggers some PseudoState changes that causes the required pseudo-style invalidations.

    Another consequence of the current approach is that playing_ is never restored, after being modified by ResetMediaPlayerAndMediasource method.

    There is another problem related to the play promises, rejected as part of the InvokeLoadAlgorithm (Step 4.6 in the spec). Modifying the paused_ flag manually doesn't re-create those promises.

    We can use PlayInternal as a way to initiate the paused->unpaused transition, which internally calls to SetPause(false) if needed. It calls ResetMediaPlayerAndMediaSource so that the promises are recreated, and UpdatePlayStte() to indicate the WebMediaPlayer to play.

    The proposed approach has the drawback that it generates a "play" event, and this goes against the spec, which states that a doc-move should be transparent and shouldn't generate any event. However, invoking the load algorithm is already generating some events, like 'emptied' and 'loadstart', so I think we are already assuming that compromise.

    A more spec-compliant approach would be to implement a new helper to restore the pause stated after attaching to a new frame, so that it does SetPaused(false) + SetShowPosterFlag(false) + UpdatePlayState(), but without scheduling play / playing events. However, I see this a more complex approach and more likely to cause regressions.

    Dale Curtis

    This seems an okay compromise, but the wpts probably shouldn't test for this since it's not part of the spec? This does result in some additional issues though with play promises that the review agent noticed.

    Javier Fernandez

    Your concerns about the new WPT to assert non-specified behavior comes from the play-promises and pseudo-class related tests, right ? Maybe it's better remove them and use browser tests instead.

    I believe the one about the absence of the 'paused" can be justified with certain part of the spec; I can elaborate on that if needed. Not to mention that there is already a pause-move-to-other-document.html test that verifies precisely that the player is not paused as a consequence of the movement to a different document.

    Line 722, Patchset 5: if (was_playing) {
    Dale Curtis . unresolved

    As currently implemented, this logic will still result in the rejection of pending play promises with AbortError. InvokeLoadAlgorithm() (at line 721) checks if !paused_ and, if so, triggers RejectPlayPromises(). Since PlayInternal() is called after the algorithm runs, it cannot resolve the promises that were already settled by the rejection logic.

    If the intention is to preserve pending promises, you might want to manually set paused_ = true before calling InvokeLoadAlgorithm() to bypass step 4.6, and then let PlayInternal() handle the state restoration. Note that the WPT test doesn't catch this because it waits for the promise to resolve before moving the node.

    Javier Fernandez

    Before this patch, the SetPaused was the only way to modify the paused_ flag, which I believe is a good idea because it avoid complex issues related to the pause -> play transition, as you pointed out before.

    Don't you think that this way of avoiding the promise rejection is a bit hacky ? Not to mention there is a DCHECK in the InvokeLoadAlgorithm [1] to ensure there is no pending promises if paused_ is true.

    I know that all this comes from the fact of invoking the load algorithm when the media elements changes it's document, which it's not what the spec states. I understand that it's a convenient implementation detail, though, but I wonder then whether it's worth the effort of testing the issue related to the pending promises.

    Maybe it's better to drop both the both the test about the pending promises and the pseudoclases. The only think that worries me is that my change to force pause_ = false didn't cause any regression; that's what motivated me provide some regression tests.

    File third_party/blink/renderer/core/html/media/html_media_element_test.cc
    Line 1941, Patchset 5: new_dummy_page_holder->GetDocument().adoptNode(Media(), ASSERT_NO_EXCEPTION);
    Dale Curtis . resolved

    In these tests, you are calling adoptNode() but not actually inserting the node into the new document tree. While this is sufficient for synchronous checks, adoptNode() leaves the node disconnected. This means when the OnRemovedFromDocumentTimer eventually fires, isConnected() will be false and the element will pause. To more accurately simulate a document move and verify the timer behavior, it is better to append the node to the new document's body.

    Javier Fernandez

    Done

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Dale Curtis
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I476b72010688f529a8fdfe8aa6c37625ba073fa3
    Gerrit-Change-Number: 7828889
    Gerrit-PatchSet: 6
    Gerrit-Owner: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Reviewer: Dale Curtis <dalec...@chromium.org>
    Gerrit-Reviewer: Javier Fernandez <jfern...@igalia.com>
    Gerrit-CC: srirama chandra sekhar <srir...@samsung.com>
    Gerrit-Attention: Dale Curtis <dalec...@chromium.org>
    Gerrit-Comment-Date: Fri, 29 May 2026 22:19:06 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Dale Curtis (Gerrit)

    unread,
    2:52 PM (1 hour ago) 2:52 PM
    to Javier Fernandez, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, srirama chandra sekhar, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, eric.c...@apple.com, feature-me...@chromium.org
    Attention needed from Javier Fernandez

    Dale Curtis added 2 comments

    File third_party/blink/renderer/core/html/media/html_media_element.cc
    Line 718, Patchset 4: paused_ = false;
    Dale Curtis . unresolved

    Play/pause state is pretty complicated. I'm not sure it's sufficient to just set this back to false. It probably at least needs `SetPaused(false)` and more likely `PlayInternal`. Can you investigate a bit more here?

    Javier Fernandez

    I see, I've been perhaps too focused on the specific test failing. I may need a more complete test case to understand all the implications of the play / pause logic. Any idea is welcome.

    I'm going to investigate it further in any case. Thanks for the review.

    Javier Fernandez

    It seems that SetPaused is the only, by design, way of modifying the paused_ flag. This is because SetPaused, triggers some PseudoState changes that causes the required pseudo-style invalidations.

    Another consequence of the current approach is that playing_ is never restored, after being modified by ResetMediaPlayerAndMediasource method.

    There is another problem related to the play promises, rejected as part of the InvokeLoadAlgorithm (Step 4.6 in the spec). Modifying the paused_ flag manually doesn't re-create those promises.

    We can use PlayInternal as a way to initiate the paused->unpaused transition, which internally calls to SetPause(false) if needed. It calls ResetMediaPlayerAndMediaSource so that the promises are recreated, and UpdatePlayStte() to indicate the WebMediaPlayer to play.

    The proposed approach has the drawback that it generates a "play" event, and this goes against the spec, which states that a doc-move should be transparent and shouldn't generate any event. However, invoking the load algorithm is already generating some events, like 'emptied' and 'loadstart', so I think we are already assuming that compromise.

    A more spec-compliant approach would be to implement a new helper to restore the pause stated after attaching to a new frame, so that it does SetPaused(false) + SetShowPosterFlag(false) + UpdatePlayState(), but without scheduling play / playing events. However, I see this a more complex approach and more likely to cause regressions.

    Dale Curtis

    This seems an okay compromise, but the wpts probably shouldn't test for this since it's not part of the spec? This does result in some additional issues though with play promises that the review agent noticed.

    Javier Fernandez

    Your concerns about the new WPT to assert non-specified behavior comes from the play-promises and pseudo-class related tests, right ? Maybe it's better remove them and use browser tests instead.

    I believe the one about the absence of the 'paused" can be justified with certain part of the spec; I can elaborate on that if needed. Not to mention that there is already a pause-move-to-other-document.html test that verifies precisely that the player is not paused as a consequence of the movement to a different document.

    Dale Curtis

    You can just have them be wpt_internal tests if we're slightly deviating from the spec. Which I thought we were per your comments about the playing event being surfaced now?

    Line 722, Patchset 5: if (was_playing) {
    Dale Curtis . unresolved

    As currently implemented, this logic will still result in the rejection of pending play promises with AbortError. InvokeLoadAlgorithm() (at line 721) checks if !paused_ and, if so, triggers RejectPlayPromises(). Since PlayInternal() is called after the algorithm runs, it cannot resolve the promises that were already settled by the rejection logic.

    If the intention is to preserve pending promises, you might want to manually set paused_ = true before calling InvokeLoadAlgorithm() to bypass step 4.6, and then let PlayInternal() handle the state restoration. Note that the WPT test doesn't catch this because it waits for the promise to resolve before moving the node.

    Javier Fernandez

    Before this patch, the SetPaused was the only way to modify the paused_ flag, which I believe is a good idea because it avoid complex issues related to the pause -> play transition, as you pointed out before.

    Don't you think that this way of avoiding the promise rejection is a bit hacky ? Not to mention there is a DCHECK in the InvokeLoadAlgorithm [1] to ensure there is no pending promises if paused_ is true.

    I know that all this comes from the fact of invoking the load algorithm when the media elements changes it's document, which it's not what the spec states. I understand that it's a convenient implementation detail, though, but I wonder then whether it's worth the effort of testing the issue related to the pending promises.

    Maybe it's better to drop both the both the test about the pending promises and the pseudoclases. The only think that worries me is that my change to force pause_ = false didn't cause any regression; that's what motivated me provide some regression tests.

    Dale Curtis

    Sorry, that comment was from the AI review tool. I should have checked its suggested fix more closely. I only wanted to surface that the play promise state would be incorrect. I don't have a suggested work around.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Javier Fernandez
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I476b72010688f529a8fdfe8aa6c37625ba073fa3
    Gerrit-Change-Number: 7828889
    Gerrit-PatchSet: 6
    Gerrit-Owner: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Reviewer: Dale Curtis <dalec...@chromium.org>
    Gerrit-Reviewer: Javier Fernandez <jfern...@igalia.com>
    Gerrit-CC: srirama chandra sekhar <srir...@samsung.com>
    Gerrit-Attention: Javier Fernandez <jfern...@igalia.com>
    Gerrit-Comment-Date: Mon, 01 Jun 2026 18:52:21 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages