Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DRM: Create new persistent MediaKeySession when load fails
We noticed of an issue which led to the impossibility of playing an encrypted content in a "persistent-license" mode if its license had already been persisted in the past but it could not be retrieved by the browser through the `MediaKeySession.load` API. This problematic situation only arises if the RxPlayer's persistent session storage, generally stored in `localStorage` by the application, is de-synchronized with the browser/CDM internal one, with the former having more items than the latter. Arguably that situation is not frequent: - we reproduced it at a large scale when updating the browser of some devices on which the RxPlayer runs. That update was not a small step (the two versions were released years apart), leading us to believe that that browser internal representation of persisted `MediaKeySession` had changed, thus it being not able to re-load old persistent `MediaKeySession`. Because the application kept however the same store of old persisted `MediaKeySession`, such de-synchronization was created. (To note that the RxPlayer currently has a policy of being retro-compatible by default - unless opted-out for performance reasons - when it comes to old persisted `MediaKeySession`, so updating the RxPlayer should normally not invalidate old persisted `MediaKeySession` the way it did for the browser here.) - In any case, we suppose that a browser or CDM may decide at any time to evict old persisted `MediaKeySession`. The RxPlayer also has an eviction mechanism in its own store but as both logics are completely un-synchronized, differences may appear in any time. --- The previous logic of the RxPlayer when failing to load an old persistent `MediaKeySession`'s information on a newly created one (as that's how the EME API works), was to just abort trying to load it and continue doing the license request on the same `MediaKeySession`. However, by re-reading the specification, it seems that this does not work. This is not indicated clearly however, but can be deduced by following the `unitialized` flag the EME specification brings up in some API's documentation. Reading the different algorithms proposed for the `load` and `generateRequest` methods, it appears that neither can be called after the other was on the same `MediaKeySession`, because this `unitialized` flag is set to `false`, having previously been asserted to be `true` right before the actual implementation logic is done. Even more implicit, it seems that it is not possible to `close` a `MediaKeySession` whose `load` call did not retrieve anything, by following this time an EME flag called `callable`. --- The (simple) fix for that situation, which remain to be tested, is to just throw away, without closing it, a `MediaKeySession` whose `load` call resolved with false, and to create a new one so that `generateRequest` can be called on it. Also, to prevent any issues (for now unseen) with that `callable` flag whose context appear more unclear, I chose to check if a `sessionId` is set on a persistent `MediaKeySession` whose closing operation failed, to ignore the failure if it wasn't and just continue the usual logic. I did that check in such a way because there seem to be a relation between a set (i.e. different than the empty string) `sessionId` and the `callable` flag though this is never clearly stated.
- Loading branch information