Use a Proxy object to detect changes within the MediaMetadata
Needs ReviewPublic

Authored by broulik on Apr 18 2020, 8:29 AM.

Details

Reviewers
fvogt
ognarb
cblack
Group Reviewers
Plasma
Summary

According to spec [1] it is allowed to change properties within the MediaMetadata rather than assigning a new instance.
Using a Proxy object lets us detect property assignments within the object. Conveniently, it still reports instanceof as being the original object.

[1] https://www.w3.org/TR/mediasession/#the-mediametadata-interface (last sentence)

Test Plan

This fixes VKontakte player not updating metadata when changing tracks. Thanks @IlyaBizyaev for investigating.

YouTube, vimeo, media session example (who all set new metadata instance when they change) still get their metadata propagated correctly

Diff Detail

Repository
R856 Plasma Browser Integration
Lint
Lint Skipped
Unit
Unit Tests Skipped
broulik created this revision.Apr 18 2020, 8:29 AM
Restricted Application added a project: Plasma. · View Herald TranscriptApr 18 2020, 8:29 AM
Restricted Application added a subscriber: plasma-devel. · View Herald Transcript
broulik requested review of this revision.Apr 18 2020, 8:29 AM
broulik added a reviewer: cblack.
fvogt added a comment.Apr 24 2020, 1:43 PM

AFAICT (take with a grain of salt, I'm a JS n00b) this doesn't catch something like this:

let a = {};
navigator.mediaSession.metadata = a;
a["foo"] = "bar";

And behaves weirdly if you do:

let a = navigator.mediaSession.metadata;
navigator.mediaSession.metadata = null;
a["foo"] = "bar";
extension/content-script.js
716

That appears to work fine here

this doesn't catch something like this

Yeah it doesn't. I thought I could "monitor" an Object but the caller actually has to use the Proxy for it to detect anything :/

Any ideas? :)

extension/content-script.js
716

Hmm this didn't work back when I implemented this originally when chrome added support for MediaMetadata

fvogt added a comment.Apr 24 2020, 1:51 PM

this doesn't catch something like this

Yeah it doesn't. I thought I could "monitor" an Object but the caller actually has to use the Proxy for it to detect anything :/

Any ideas? :)

Other than using an interval timer to sync regularly, not really. At least the first case seems impossible to fix.

The second case could be fixed though by navigator.mediaSession.metadata === this or something like that...

Maybe if I overwrote MediaMetadata with a Proxy object already, then the website would never have a separate Object to work with.. hmm