Implement a chrome-only method `getCurrentMediaSessionPlaybackState()` to expose current actual playback state in testing.
The reason we create an new enum `MediaSessionPlaybackTestState` is because of building issue. If we use `MediaSessionPlaybackState` directly in the `ChromeUtils.webidl`, then the codegen would automatically add an header include of `MediaSessionBinding.h` in the `ChromeUtilsBinding.h`, which would cause the complier complaining about lots of undeclared identifier.
Differential Revision: https://phabricator.services.mozilla.com/D66344
--HG--
extra : moz-landing-system : lando
`PlaybackState` and `MediaSessionPlaybackState` are actually quite similar, and we don't want to have to many states to confuse reader and do unnecessary tranform between two states. Therefore, replaceing `PlaybackState` with `MediaSessionPlaybackState`.
Differential Revision: https://phabricator.services.mozilla.com/D66342
--HG--
extra : moz-landing-system : lando
Whenever pressing the media control keys, it would not only change the media playback state, but also change the playback state of the media controller. Therefore, we want to ensure simulating events always happen after media controller changes its playback state.
In addition, for `play/pause` key, it would check controller's playback state to decide if we should file `play` event or `pause` event, so we definitely have to do that only after the controller changes its playback state.
Changing a file to non-autoplay to prevent missing the `main-media-controller-playback-changed` notification, because we can control when to start media and ensure we have already create a listener for that event.
For non-browser test, we have no way to listen to that notification, which could only be observed in the chrome process, so we do a hack to listen `timeupdate` several times to wait and hope the controller has been created and changed its state in the chrome process.
Differential Revision: https://phabricator.services.mozilla.com/D63926
--HG--
extra : moz-landing-system : lando
By providing element Id, we can use these functions to access video element on other files.
Differential Revision: https://phabricator.services.mozilla.com/D64173
--HG--
extra : moz-landing-system : lando
`async` is actually useless here because we don't have anything to do after `await` so we could return the promise `SpecialPowers.spawn()` generate instead.
Differential Revision: https://phabricator.services.mozilla.com/D63944
--HG--
extra : moz-landing-system : lando
Create a chrome-only method to get the current media metadata to know if we correctly update the media metadata or not. That method would only be used for testing.
Differential Revision: https://phabricator.services.mozilla.com/D64849
--HG--
extra : moz-landing-system : lando
This change can help us ensure doing something after we unset the media controller, which is helpful in testing.
Differential Revision: https://phabricator.services.mozilla.com/D64848
--HG--
extra : moz-landing-system : lando
Whenever the main controller updates its metadata, we should also notify the event source to update the metadata, because we don't want to show the wrong metadata on the virtual control interface.
In this patch, we add a new media event to notify this situation and create a new method `SetMediaMetadata()` on the `MediaControlKeysEventSource`. But we leave that function empty for now, and will have follow-up bugs to handle setting metadata on each different platforms.
Differential Revision: https://phabricator.services.mozilla.com/D64847
--HG--
extra : moz-landing-system : lando
As we would like to use `mTopLevelBCId` in `MediaSessionController` as well in order to get the corresponding browsing context, so move `mTopLevelBCId` to the `MediaSessionController`.
Differential Revision: https://phabricator.services.mozilla.com/D62535
--HG--
extra : moz-landing-system : lando
Since we can determine which browsing context contains an active media session via `MediaSessionController`, we should notify that context directly in order to access correct media session. Especially after we enable Fission, browsing contexts could exist in different processes, so choosing the right context to notify is really important.
Differential Revision: https://phabricator.services.mozilla.com/D60937
--HG--
extra : moz-landing-system : lando
Create a class `MediaSessionController` which is used to track all alive media sessions within a tab and store their metadata which could be used to show on the virtual media control interface. That class would also be responsible to select an active media session with in a tab.
Differential Revision: https://phabricator.services.mozilla.com/D60935
--HG--
extra : moz-landing-system : lando
The check here was used to prevent calling play or pause during playing or pausing.
However, according to the spec [1], even if media session is playing, we would still want to trigger its play action handler when play action happens. So we should forward all media control key events to the content, not to block any of them.
[1] https://w3c.github.io/mediasession/#handle-media-session-action
Differential Revision: https://phabricator.services.mozilla.com/D60918
--HG--
extra : moz-landing-system : lando
It allows us to share the same event name when writing test code like the following:
```
const action = "previoustrack";
mediaSession.setActionHandler(action, () => { ... });
specialPower.generateMediaControlKeyTestEvent(action);
```
Differential Revision: https://phabricator.services.mozilla.com/D60784
--HG--
extra : moz-landing-system : lando
Ensure we have called controller's shutdown before it gets destroyed and not to change its internal status after shutdown.
Differential Revision: https://phabricator.services.mozilla.com/D60563
--HG--
extra : moz-landing-system : lando
Ensure we have called controller's shutdown before it gets destroyed and not to change its internal status after shutdown.
Differential Revision: https://phabricator.services.mozilla.com/D60563
--HG--
extra : moz-landing-system : lando
Currently we append the new controller first, then clear all controllers when handling audio competing, and finally add the new controller to `mOwningFocusControllers` again.
We can handle audio competing first, then adding the new controller, which can avoid adding same controller twice.
Differential Revision: https://phabricator.services.mozilla.com/D58735
--HG--
extra : moz-landing-system : lando
Before applying D58591, `AudioFocusMagager` depends on `MediaControlService` to access media controller. Now we still depend on `CanonicalBrowsingContext` to access media controller, which make us not able to have a unit test without any other components.
Therefore, we can simply store the reference of media controller in `AudioFocusManager` to avoid relying on the implementation of other components.
Differential Revision: https://phabricator.services.mozilla.com/D58734
--HG--
extra : moz-landing-system : lando
We should ensure that controllers has been removed from the service when it destroys. Therefore, we remove the assertion in `MediaControlService::RegisterActiveMediaController()` and `MediaControlService::UnregisterActiveMediaController()`, and return the result to allow caller to know if it has been registered or unregistered or not in order to do error handling or add assertions.
Differential Revision: https://phabricator.services.mozilla.com/D59286
--HG--
extra : moz-landing-system : lando
As each media controller corresponds to a tab (a browsing context tree), so the controller's life cycle should be equal to the tab. Currently we use the top-level browsing context to represent a tab, so when that browsing context is being destroyed, we should also destroy the corresponding media controller.
Therefore, `MediaControlService` don't need to have methods to access media controller anymore, we should access media controller directly from the top-level canonical browsing context.
Differential Revision: https://phabricator.services.mozilla.com/D58591
--HG--
extra : moz-landing-system : lando
To modify variable and function names to emphasize all media controllers added in the service are active controllers. If the controller doesn't have any controlled media, they won't be added into the service.
Differential Revision: https://phabricator.services.mozilla.com/D58589
--HG--
extra : moz-landing-system : lando
Based on the main controller's play state to set the correct playback state to the event source.
Differential Revision: https://phabricator.services.mozilla.com/D58261
--HG--
extra : moz-landing-system : lando
Implement a class `ControllerManager` to wrap the details of how to select the main controller, which would also be used to monitor main controller's play state change.
Differential Revision: https://phabricator.services.mozilla.com/D58260
--HG--
extra : moz-landing-system : lando
We use `PlaybackState` to replace `boolean` which can clearly indicate what controller's current state is and introduce a new method `PlayStateChangedEvent()` which can be used to monitor the play state change of the media controller.
Differential Revision: https://phabricator.services.mozilla.com/D58174
--HG--
extra : moz-landing-system : lando
Since we would like to use `PlaybackState` in MediaController, we move it out from `MediaEventSource` and put it in `MediaControl.h`, which makes more sense because it actually represents media controller's playback state.
In addition, modify `ePlayed` to `ePlaying` and add one new state `eStopped`.
Differential Revision: https://phabricator.services.mozilla.com/D59100
--HG--
extra : moz-landing-system : lando
After XPCOM is shutdown, `sBrowsingContext` would be released, so using `BrowsingContext::Get()` would cause crash. Therefore, after shutdown XPCOM, we should not access browsing context.
Differential Revision: https://phabricator.services.mozilla.com/D59079
--HG--
extra : moz-landing-system : lando
Use `MediaControlKeysEventHandler` to handle the control keys event, which can always find corresponding controlled media if there are some.
Differential Revision: https://phabricator.services.mozilla.com/D57575
--HG--
extra : moz-landing-system : lando
Introduce `ControlledMediaState` to media controller, so now we can now how many controlled media are playing, which allow us to update `mIsPlaying` correctly.
Differential Revision: https://phabricator.services.mozilla.com/D57574
--HG--
extra : moz-landing-system : lando
Modify IPC method to support notify `ControlledMediaState` to the media controller, and remove the previous implementation.
Differential Revision: https://phabricator.services.mozilla.com/D57572
--HG--
extra : moz-landing-system : lando
Implement class `ContentMediaController` that is used to dispatch media controls key events to those media which would like to be controlled.
`ContentMediaController` is inherited from two classes, `MediaControlAgent` and `MediaControlKeysEventHandler`. The former one is used for controlled media, the controlled media can register itself to `MediaControlAgent` to receive events and do corresponding operations depending on the event type. The latter one is used to handle events sent from chrome process and dispatch them to the corresponding controlled media.
Differential Revision: https://phabricator.services.mozilla.com/D57570
--HG--
extra : moz-landing-system : lando
On macOS 10.12.1+, we use `MediaPlayer` library, which has better media key integration, to replace the implementation of `CG EventLoop`.
Differential Revision: https://phabricator.services.mozilla.com/D46890
--HG--
extra : moz-landing-system : lando
We have no plan to use those functions, so remove them in order to keep code clean.
Differential Revision: https://phabricator.services.mozilla.com/D58172
--HG--
extra : moz-landing-system : lando
When a function returning a pointer, returning a raw pointer is enough. The callers should use `RefPtr` to store this pointer explicitly if they do need to add a refcounting.
In addition, using `RefPtr` in the parameter cannot prevent anything as well.
Differential Revision: https://phabricator.services.mozilla.com/D58171
--HG--
extra : moz-landing-system : lando
We have no plan to use those functions, so remove them in order to keep code clean.
Differential Revision: https://phabricator.services.mozilla.com/D58172
--HG--
extra : moz-landing-system : lando
When a function returning a pointer, returning a raw pointer is enough. The callers should use `RefPtr` to store this pointer explicitly if they do need to add a refcounting.
In addition, using `RefPtr` in the parameter cannot prevent anything as well.
Differential Revision: https://phabricator.services.mozilla.com/D58171
--HG--
extra : moz-landing-system : lando
Inheriting from `nsISupports` is too complicated if we just want to support refcounting. Instead, we can use `NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING` to declare `Add/RemoveRef()` as pure virtual functions in order to create ref-counted abstract classes.
Differential Revision: https://phabricator.services.mozilla.com/D57714
--HG--
extra : moz-landing-system : lando