If you request a GMPParent with a nodeId, you should get any already running
instances with the same nodeId in preference to cloning an existing GMP and
assigning it the nodeId.
This is ensures that EME GMP actors that are same-origin run in the same GMP
instance.
The GMP gtests are failing because of the cross-origin checks in
GeckoMediaPluginServiceParent::SelectPluginForAPI(). The loop there selects the
first GMPParent that can be used from the nodeId passed in. We previously
assumed a GMPParent can be used from a nodeId if the GMPParent has the same
nodeId, or if it has not loaded its process and it has no nodeId. The problem
with assuming that, is if an in-use GMPParent with the target nodeId lies in
the GeckoMediaPluginServiceParent::mPlugins list after a GMPParent with no
nodeId, we'll end up using the first GMPParent (the one with no nodeId) rather
than the one with the target nodeId.
The solution is to change GeckoMediaPluginServiceParent::SelectPluginForAPI()
so that effectively if we have a target nodeId, we'll select the first
GMPParent that has the same nodeId, or we'll clone the first which supported
all the requested capabilities/tags.
This means when you request a GMPParent with a given nodeId, you'll get the one
with the same nodeId (origin) by preference.
MozReview-Commit-ID: 4yVnrO8B1Pg
Prior to this change, we'd store the GMPStorage records for private browsing
sessions in the GMPStorageParent. The problem with this is that they only have
a lifespan matching their corresponding GMPParent. This means that if a GMP
stores something in a PB session, and the GMP is shutdown and then re-created,
we are likely to loose the stored data. This could mean that the PB session
gets results it doesn't expect, and thus expose a way for PB mode to be
detected.
MozReview-Commit-ID: 1OMD0LvidYs
The GMP which GeckoMediaPluginServiceParent::FindPluginForAPIFrom() returns
depends on the order in which GMPs lie in GMPServiceParent::mPlugins. However
when we shutdown a GMPParent we remove and then re-append the GMPParent to
mPlugins. This means the order in which GMPs lie in the list changes.
So when WebRTC requests an H.264 decoder, the first time it will get OpenH264,
since that's first in the list. But once we dispose of that decoder, its
GMPParent will be cloned and the clone will be appended to the end of the
list. This means the next time WebRTC requests a decoder, it'll get whatever
was next in the list.
This could be the Adobe GMP, which seems to be able to handle whatever WebRTC
is putting into it. However, if you do this enough times, you'll get the
Widevine CDM, which can't handle whatever WebRTC is putting into it.
So a quick hack to fix this is in ReAddOnGMPThread is to re-insert the clone
of the GMP into the slot in mPlugins that the original occupied. Then WebRTC
will always get OpenH264 whenever it requests for an H.264 decoder, as the
order of the GMPParents in mPlugins won't change.
MozReview-Commit-ID: Ii4AMqDqAo9
Assert that the CDM wrapper is given a non-null CDM pointer.
(so GetCDM() doesn't need to be null-checked.)
Renamed WidevineVideoDecoder mCDM to mCDMWrapper, to avoid (my) confusion.
Assert that WidevineVideoDecoder is given a non-null CDM-wrapper pointer.
Assert that WidevineVideoDecoder only accesses the CDM before DecodingComplete.
Small optimization: Move aCDM into mCDM (to save an AddRef/Release pair).
MozReview-Commit-ID: yKupY067ly
Ensure that there is a CDM before creating a video decoder that relies on that
CDM. This is mainly to prevent using the Widevine video decoder alone, without
decryption.
MozReview-Commit-ID: 7p49CnmV2r7
Crash reporting for GMPs being used from the EME call site are not generating
crash reports because they depend on the MediaKeys object calling
GMPService::AddPluginCrashHandler() to associate a window to which the
PluginCrashedEvent is fired. This doesn't work with e10s enabled because the
GMPParent which causes the plugin crash handlers to run is in the chrome
process, but the MediaKeys which adds the handler is in the child process. So
the crash handler is on the GMPServiceChild, but we only run the crash handlers
that were added to the GMPServiceParent in the chrome/parent process.
The solution is to broadcast a message from the chrome process to all the
content processes when a GMP has crashed that causes the GMPServiceChild to
also run its crash handlers.
MozReview-Commit-ID: 8Lek16G9ZGb
We normally create global objects in the DOM bindings via:
1. Call JS_NewGlobalObject.
2. Set a private slot to hold a ProtoAndIfaceCache.
3. Other steps that aren't relevant here.
However, it's possible for step 1 to construct a global inside the JS
engine and then fail to initialize it in some way. When that happens,
the newly-created object will be subjected to GC and any GC-related
hooks that were passed in to JS_NewGlobalObject. Which implies that our
tracing and finalization hooks must be prepared to handle an object
that's not fully initialized--i.e. doesn't have a ProtoAndIfaceCache
object allocated for it. We handled such a case in our trace hook, but
we failed to add the same check for our finalization hook. Do so.
When opening a new tab, there is a small window between tab creation and the DOMTitleChanged event firing where the tab - if it is not created as a delay loaded zombie tab right away - won't have any session store data. However a number of functions (tab zombification and restoring of zombified tabs, undo close tabs) depend on the session store data always being available, so things can fall apart if e.g. a zombification is triggered immediately after opening a new tab.
This also means that a tab which is zombfied immediately after its creation (e.g. when a number of tabs are opened through tab queues on startup) is not included in a session save and will therefore get lost if Firefox is killed.
Therefore, we now always intialise new tabs with some basic session store data.
MozReview-Commit-ID: 9248jJFUaq5
Bug 691003 made the minimum allocation size word sized for Linux and OS X, we
now need to do a similar change on Windows as well. For Windows the requirement
is 8-bytes on 32-bit and 16-bytes on 64-bit.
After this patch, I still occasionally see the toolbar positioned part
way down from the top of the screen. However, this state looks slightly
less janky without the animation I removed and I can't consistently
reproduce it anymore. Given the DynamicToolbar.setVisible calls I make,
I'd guess this is likely to be a bug caused by BrowserApp.onTabChanged
(and thus DynamicToolbar.setVisible) not getting called instantly and
so the DynamicToolbar is initialized to a different location on screen.
I'd guess it's a bug in DynamicToolbar as to why it's positioned partially
off-screen.
There is a little bit of code duplication, but that is because the code
to load a url on a new intent is duplicated (i.e. once from GeckoApp.initialize
- the initial load - and once from GeckoApp.onNewIntent). This could
potentially be cleaned up if we moved the app loading code into onResume,
but that may not be possible since we need to wait for Gecko to start
up.
Additionally, this patch adds a lot of hard-to-follow global state, which is
also not good.
Preferred solution (bug 1269041): show the toolbar each time onStart is
called (i.e. FF is unhidden). This is good for the user - they'll be
more aware which page they're on - but it's janky with the current
implementation, where the page content does not scroll when the toolbar
is shown so previously visible content is hidden. Thus, I went with the
other approach. fwiw, Chrome does this behavior, but scrolls the toolbar
offscreen shortly after it is shown.
This solution is blocked on bug 1245523.
MozReview-Commit-ID: 7JjCrIf4KTm
Identify HLS media types (and related m3u playlists) and report
telemetry about how often we fail to play them. This is designed
to measure popularity to inform decisions about support for this
format.
MozReview-Commit-ID: Fp8lNMOJKyA
The WMF HasAAC/HasH264 checks were done off the main thread, as soon as the
plugin was loaded, which was way too soon in the overall startup process, when
the WMF subsystem may not have been properly initialized yet, or may be in the
middle of it.
The solution here is to delay these checks until they are actually needed to
respond to a format-support request, as they come later in the process.
Note: This may not be the ideal solution yet, as we are still relying on some
magic sequencing of events. Other avenues have been explored unsuccessfully
yet, but we may want to revisit this issue after this urgent patch has landed.
MozReview-Commit-ID: JVgINc5FLFx
The first check in ByteLengthIsValid() says "nsTArray only handles
sizes up to INT32_MAX", but the actual requirement is that the
capacity is no larger than UINT32_MAX. The check is overly restrictive
if sizeof(E) is 1 byte, and overly permissive if sizeof(E) is greater
than 2 bytes. I removed this check. Internal nsTArray invariants
should be enforced by nsTArray methods.
The second check is trying to check for overflow, but that should just
be done using CheckedInt.