Skip to content

Commit

Permalink
Fix type info and initData types in EME polyfills
Browse files Browse the repository at this point in the history
The latest Closure Compiler initially complained about "initData" not
being a known property of "Event".  Correcting the type to
MediaEncryptedEvent exposed a potential bug, which is that we were
assigning Uint8Array in some cases instead of the correct ArrayBuffer.
This fixes both the type of the event and converts the Uint8Arrays to
ArrayBuffers.

This also works around a complaint about "code" on "Error".  We use
"Error" objects as look-alikes for DOMException because there is no
exposed constructor for DOMExceptions.  To satisfy the compiler, we
use square brackets now to set the "code" field on these DOMException
look-alikes.

Finally, this removes the "method" field on certain Errors in the
WebKit EME polyfill.  These must have been leftover from some
debugging, and are not used at all.

Issue shaka-project#2528

Change-Id: I32c4617b14a30c412d5bc532ec17a46fdc1fea1a
  • Loading branch information
joeyparrish committed Apr 28, 2020
1 parent 15e48e9 commit 34cde38
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 22 deletions.
17 changes: 11 additions & 6 deletions lib/polyfill/patchedmediakeys_apple.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ shaka.polyfill.PatchedMediaKeysApple = class {
*
* @this {!HTMLMediaElement}
* @param {!MediaKeyEvent} event
* @suppress {constantProperty} We reassign what would be const on a real
* MediaEncryptedEvent, but in our look-alike event.
* @private
*/
static onWebkitNeedKey_(event) {
Expand Down Expand Up @@ -168,8 +170,11 @@ shaka.polyfill.PatchedMediaKeysApple = class {
// NOTE: Because "this" is a real EventTarget, the event we dispatch here
// must also be a real Event.
const event2 = new Event('encrypted');
event2.initDataType = 'skd';
event2.initData = shaka.util.BufferUtils.toArrayBuffer(initData);

const encryptedEvent =
/** @type {!MediaEncryptedEvent} */(/** @type {?} */(event2));
encryptedEvent.initDataType = 'skd';
encryptedEvent.initData = shaka.util.BufferUtils.toArrayBuffer(initData);

this.dispatchEvent(event2);
}
Expand Down Expand Up @@ -209,11 +214,11 @@ shaka.polyfill.PatchedMediaKeysApple.MediaKeySystemAccess = class {
}
}

// As per the spec, this should be a DOMException, but there is not a
// public constructor for DOMException.
// According to the spec, this should be a DOMException, but there is not a
// public constructor for that. So we make this look-alike instead.
const unsupportedKeySystemError = new Error('Unsupported keySystem');
unsupportedKeySystemError.name = 'NotSupportedError';
unsupportedKeySystemError.code = DOMException.NOT_SUPPORTED_ERR;
unsupportedKeySystemError['code'] = DOMException.NOT_SUPPORTED_ERR;
throw unsupportedKeySystemError;
}

Expand Down Expand Up @@ -597,7 +602,7 @@ class extends shaka.util.FakeEventTarget {
shaka.log.debug('PatchedMediaKeysApple.onWebkitKeyError_', event);

const error = new Error('EME PatchedMediaKeysApple key error');
error.errorCode = this.nativeMediaKeySession_.error;
error['errorCode'] = this.nativeMediaKeySession_.error;

if (this.generateRequestPromise_ != null) {
this.generateRequestPromise_.reject(error);
Expand Down
20 changes: 13 additions & 7 deletions lib/polyfill/patchedmediakeys_ms.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ shaka.polyfill.PatchedMediaKeysMs = class {
*
* @this {!HTMLMediaElement}
* @param {!MediaKeyEvent} event
* @suppress {constantProperty} We reassign what would be const on a real
* MediaEncryptedEvent, but in our look-alike event.
* @private
*/
static onMsNeedKey_(event) {
Expand All @@ -97,10 +99,14 @@ shaka.polyfill.PatchedMediaKeysMs = class {
// NOTE: Because "this" is a real EventTarget, on IE, the event we dispatch
// here must also be a real Event.
const event2 =
/** @type {!CustomEvent} */ (document.createEvent('CustomEvent'));
/** @type {!CustomEvent} */(document.createEvent('CustomEvent'));
event2.initCustomEvent('encrypted', false, false, null);
event2.initDataType = 'cenc';
event2.initData = shaka.util.Pssh.normaliseInitData(event.initData);

const encryptedEvent =
/** @type {!MediaEncryptedEvent} */(/** @type {?} */(event2));
encryptedEvent.initDataType = 'cenc';
encryptedEvent.initData = shaka.util.BufferUtils.toArrayBuffer(
shaka.util.Pssh.normaliseInitData(event.initData));

this.dispatchEvent(event2);
}
Expand Down Expand Up @@ -196,11 +202,11 @@ shaka.polyfill.PatchedMediaKeysMs.MediaKeySystemAccess = class {
}
} // for each cfg in supportedConfigurations

// As per the spec, this should be a DOMException, but there is not a
// public constructor for this.
// According to the spec, this should be a DOMException, but there is not a
// public constructor for that. So we make this look-alike instead.
const unsupportedKeySystemError = new Error('Unsupported keySystem');
unsupportedKeySystemError.name = 'NotSupportedError';
unsupportedKeySystemError.code = DOMException.NOT_SUPPORTED_ERR;
unsupportedKeySystemError['code'] = DOMException.NOT_SUPPORTED_ERR;
throw unsupportedKeySystemError;
}

Expand Down Expand Up @@ -566,7 +572,7 @@ class extends shaka.util.FakeEventTarget {
shaka.log.debug('PatchedMediaKeysMs.onMsKeyError_', event);

const error = new Error('EME PatchedMediaKeysMs key error');
error.errorCode = this.nativeMediaKeySession_.error;
error['errorCode'] = this.nativeMediaKeySession_.error;

if (this.generateRequestPromise_ != null) {
this.generateRequestPromise_.reject(error);
Expand Down
25 changes: 16 additions & 9 deletions lib/polyfill/patchedmediakeys_webkit.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,12 @@ shaka.polyfill.PatchedMediaKeysWebkit.MediaKeySystemAccess = class {
if (keySystem == 'org.w3.clearkey' || keySystem == 'com.widevine.alpha') {
message = 'None of the requested configurations were supported.';
}

// According to the spec, this should be a DOMException, but there is not a
// public constructor for that. So we make this look-alike instead.
const unsupportedError = new Error(message);
unsupportedError.name = 'NotSupportedError';
unsupportedError.code = DOMException.NOT_SUPPORTED_ERR;
unsupportedError['code'] = DOMException.NOT_SUPPORTED_ERR;
throw unsupportedError;
}

Expand Down Expand Up @@ -411,19 +414,24 @@ shaka.polyfill.PatchedMediaKeysWebkit.MediaKeys = class {

/**
* @param {!MediaKeyEvent} event
* @suppress {constantProperty} We reassign what would be const on a real
* MediaEncryptedEvent, but in our look-alike event.
* @private
*/
onWebkitNeedKey_(event) {
shaka.log.debug('PatchedMediaKeysWebkit.onWebkitNeedKey_', event);
goog.asserts.assert(this.media_, 'media_ not set in onWebkitNeedKey_');

const event2 =
/** @type {!CustomEvent} */ (document.createEvent('CustomEvent'));
/** @type {!CustomEvent} */ (document.createEvent('CustomEvent'));
event2.initCustomEvent('encrypted', false, false, null);

// not used by v0.1b EME, but given a valid value
event2.initDataType = 'webm';
event2.initData = event.initData;
const encryptedEvent =
/** @type {!MediaEncryptedEvent} */(/** @type {?} */(event2));
// initDataType is not used by v0.1b EME, so any valid value is fine here.
encryptedEvent.initDataType = 'cenc';
encryptedEvent.initData = shaka.util.BufferUtils.toArrayBuffer(
event.initData);

this.media_.dispatchEvent(event2);
}
Expand Down Expand Up @@ -603,20 +611,19 @@ class extends shaka.util.FakeEventTarget {
// will at least provide some information which can be used to look into the
// problem.
const error = new Error('EME v0.1b key error');
error.errorCode = event.errorCode;
error.errorCode.systemCode = event.systemCode;
const errorCode = event.errorCode;
errorCode.systemCode = event.systemCode;
error['errorCode'] = errorCode;

// The presence or absence of sessionId indicates whether this corresponds
// to generateRequest() or update().
if (!event.sessionId && this.generatePromise_) {
error.method = 'generateRequest';
if (event.systemCode == 45) {
error.message = 'Unsupported session type.';
}
this.generatePromise_.reject(error);
this.generatePromise_ = null;
} else if (event.sessionId && this.updatePromise_) {
error.method = 'update';
this.updatePromise_.reject(error);
this.updatePromise_ = null;
} else {
Expand Down

0 comments on commit 34cde38

Please sign in to comment.