Skip to content

Commit

Permalink
Fix PlayReady on IE and Edge
Browse files Browse the repository at this point in the history
We broke PlayReady on IE and Edge in #815 when we fixed PlayReady for
Tizen.  This should work for both, but will still need to be tested on
Tizen after merging.

Closes #837

Change-Id: Iff41845ae6a4b369e8f21a80623ebb2cb5475fd6
  • Loading branch information
joeyparrish committed Jun 5, 2017
1 parent 734ac9b commit a504f14
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 24 deletions.
34 changes: 15 additions & 19 deletions lib/media/drm_engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -1119,23 +1119,9 @@ shaka.media.DrmEngine.prototype.sendLicenseRequest_ = function(event) {
* @private
*/
shaka.media.DrmEngine.prototype.unpackPlayReadyRequest_ = function(request) {
// PlayReady CDMs in some clients (e.g. IE11, Edge) wrap the license message
// in UTF-16 encoded XML which can't be directly delivered to a license
// server. However, not all clients exhibit this behaviour. The Tizen
// PlayReady CDM message is UTF-8 encoded and can be passed to the license
// server as-is. Other CDMs do not seem to need this kind of special
// handling.
var xml = String.fromCharCode.apply(null, new Uint8Array(request.body));

if (xml.indexOf('<PlayReadyKeyMessage') !== 0) {
// The message is not wrapped.
request.headers['Content-Type'] = 'text/xml; charset=utf-8';
return;
}

// The raw license message is UTF-16-encoded XML. We need to unpack the
// Challenge element (base64-encoded string containing the actual license
// request) and any HttpHeader elements (sent as request headers).
// On IE and Edge, the raw license message is UTF-16-encoded XML. We need to
// unpack the Challenge element (base64-encoded string containing the actual
// license request) and any HttpHeader elements (sent as request headers).

// Example XML:

Expand All @@ -1155,8 +1141,18 @@ shaka.media.DrmEngine.prototype.unpackPlayReadyRequest_ = function(request) {
// </LicenseAcquisition>
// </PlayReadyKeyMessage>

xml = shaka.util.StringUtils.fromUTF16(
request.body, true /* littleEndian */);
var xml = shaka.util.StringUtils.fromUTF16(
request.body, true /* littleEndian */, true /* noThrow */);
if (xml.indexOf('PlayReadyKeyMessage') == -1) {
// This does not appear to be a wrapped message as on IE and Edge. Some
// clients do not need this unwrapping, so we will assume this is one of
// them. Note that "xml" at this point probably looks like random garbage,
// since we interpreted UTF-8 as UTF-16.
shaka.log.debug('PlayReady request is already unwrapped.');
request.headers['Content-Type'] = 'text/xml; charset=utf-8';
return;
}
shaka.log.debug('Unwrapping PlayReady request.');
var dom = new DOMParser().parseFromString(xml, 'application/xml');

// Set request headers.
Expand Down
9 changes: 6 additions & 3 deletions lib/util/string_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,17 @@ shaka.util.StringUtils.fromUTF8 = function(data) {
*
* @param {?BufferSource} data
* @param {boolean} littleEndian true to read little endian, false to read big.
* @param {boolean=} opt_noThrow true to avoid throwing in cases where we may
* expect invalid input. If noThrow is true and the data has an odd length,
* it will be truncated.
* @return {string}
* @throws {shaka.util.Error}
* @export
*/
shaka.util.StringUtils.fromUTF16 = function(data, littleEndian) {
shaka.util.StringUtils.fromUTF16 = function(data, littleEndian, opt_noThrow) {
if (!data) return '';

if (data.byteLength % 2 != 0) {
if (!opt_noThrow && data.byteLength % 2 != 0) {
shaka.log.error('Data has an incorrect length, must be even.');
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL, shaka.util.Error.Category.TEXT,
Expand All @@ -98,7 +101,7 @@ shaka.util.StringUtils.fromUTF16 = function(data, littleEndian) {
}

// Use a DataView to ensure correct endianness.
var length = data.byteLength / 2;
var length = Math.floor(data.byteLength / 2);
var arr = new Uint16Array(length);
var dataView = new DataView(buffer);
for (var i = 0; i < length; i++) {
Expand Down
3 changes: 1 addition & 2 deletions test/media/drm_engine_integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,8 @@ describe('DrmEngine', function() {
}); // describe('basic flow')

function checkKeySystems() {
// TODO: re-enable these tests for PlayReady (b/38496036)
// Our test asset for this suite can use any of these key systems:
if (!support['com.widevine.alpha']) {
if (!support['com.widevine.alpha'] && !support['com.microsoft.playready']) {
// pending() throws a special exception that Jasmine uses to skip a test.
// It can only be used from inside it(), not describe() or beforeEach().
pending('Skipping DrmEngine tests.');
Expand Down

0 comments on commit a504f14

Please sign in to comment.