From 979b373f3c0add1117e78840a03d8f8c0128a74d Mon Sep 17 00:00:00 2001 From: Joey Parrish Date: Mon, 18 Nov 2019 14:30:33 -0800 Subject: [PATCH] Add a polyfill for EME encryption scheme queries Note that the encryptionScheme field isn't being used by Shaka Player yet, but that this will enable us to experiment with it ahead of the full launch of the feature in browsers. See also: - https://wicg.github.io/encrypted-media-encryption-scheme/ - https://github.com/WICG/encrypted-media-encryption-scheme/issues/13 - https://github.com/w3c/encrypted-media/pull/457 Change-Id: I9e8c2b6ce4ce3f4fe634fa4164669c69959e7fde --- build/build.py | 5 +++- build/check.py | 38 +++++++++++++++++++---------- build/conformance.textproto | 2 ++ build/types/polyfill | 2 ++ demo/index.html | 2 ++ karma.conf.js | 4 ++++ lib/polyfill/encryption_scheme.js | 40 +++++++++++++++++++++++++++++++ package.json | 3 +++ shaka-player.uncompiled.js | 1 + 9 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 lib/polyfill/encryption_scheme.js diff --git a/build/build.py b/build/build.py index 17070ce778..b56c005944 100755 --- a/build/build.py +++ b/build/build.py @@ -276,7 +276,10 @@ def build_library(self, name, locales, force, is_debug): build_name = 'shaka-player.' + name closure = compiler.ClosureCompiler(self.include, build_name) - generator = compiler.ExternGenerator(self.include, build_name) + + # Don't pass node modules to the extern generator. + local_include = set([f for f in self.include if 'node_modules' not in f]) + generator = compiler.ExternGenerator(local_include, build_name) closure_opts = common_closure_opts + common_closure_defines if is_debug: diff --git a/build/check.py b/build/check.py index be9d97928a..3e227c5d55 100755 --- a/build/check.py +++ b/build/check.py @@ -32,6 +32,17 @@ import shakaBuildHelpers +def complete_build_files(): + """Returns a complete set of build files.""" + complete = build.Build() + # Normally we don't need to include @core, but because we look at the build + # object directly, we need to include it here. When using main(), it will + # call addCore which will ensure core is included. + if not complete.parse_build(['+@complete', '+@core'], os.getcwd()): + logging.error('Error parsing complete build') + return False + return complete.include + def get_lint_files(): """Returns the absolute paths to all the files to run the linter over.""" match = re.compile(r'.*\.js$') @@ -94,20 +105,18 @@ def check_complete(_): """ logging.info('Checking that the build files are complete...') - complete = build.Build() - # Normally we don't need to include @core, but because we look at the build - # object directly, we need to include it here. When using main(), it will - # call addCore which will ensure core is included. - if not complete.parse_build(['+@complete', '+@core'], os.getcwd()): - logging.error('Error parsing complete build') + complete_build = complete_build_files() + if not complete_build: return False match = re.compile(r'.*\.js$') base = shakaBuildHelpers.get_source_base() all_files = set() - all_files.update(shakaBuildHelpers.get_all_files(os.path.join(base, 'lib'), match)) - all_files.update(shakaBuildHelpers.get_all_files(os.path.join(base, 'ui'), match)) - missing_files = all_files - complete.include + all_files.update(shakaBuildHelpers.get_all_files( + os.path.join(base, 'lib'), match)) + all_files.update(shakaBuildHelpers.get_all_files( + os.path.join(base, 'ui'), match)) + missing_files = all_files - complete_build if missing_files: logging.error('There are files missing from the complete build:') @@ -126,14 +135,19 @@ def check_tests(args): """ logging.info('Checking the tests for type errors...') + complete_build = complete_build_files() + if not complete_build: + return False + match = re.compile(r'.*\.js$') base = shakaBuildHelpers.get_source_base() def get(*path_components): return shakaBuildHelpers.get_all_files( os.path.join(base, *path_components), match) - files = set(get('lib') + get('externs') + get('test') + get('ui') + - get('third_party', 'closure') + - get('third_party', 'language-mapping-list')) + + files = complete_build + files.update(set(get('externs') + get('test') + + get('third_party', 'closure'))) files.add(os.path.join(base, 'demo', 'common', 'asset.js')) files.add(os.path.join(base, 'demo', 'common', 'assets.js')) diff --git a/build/conformance.textproto b/build/conformance.textproto index 7e6a8154f9..f1387674b2 100644 --- a/build/conformance.textproto +++ b/build/conformance.textproto @@ -81,6 +81,7 @@ requirement { whitelist_regexp: 'demo/' whitelist_regexp: 'third_party/closure/' whitelist_regexp: 'test/' + whitelist_regexp: 'node_modules/' } @@ -110,6 +111,7 @@ requirement: { whitelist_regexp: 'lib/debug/log.js' whitelist_regexp: 'third_party/closure/' whitelist_regexp: 'test/test/boot.js' + whitelist_regexp: 'node_modules/' } diff --git a/build/types/polyfill b/build/types/polyfill index f92f499197..497d6eae9b 100644 --- a/build/types/polyfill +++ b/build/types/polyfill @@ -1,5 +1,7 @@ # Polyfills used to emulate missing browsers features. ++../../node_modules/eme-encryption-scheme-polyfill/index.js ++../../lib/polyfill/encryption_scheme.js +../../lib/polyfill/fullscreen.js +../../lib/polyfill/indexed_db.js +../../lib/polyfill/input_event.js diff --git a/demo/index.html b/demo/index.html index efc881d36f..1d73f15f48 100644 --- a/demo/index.html +++ b/demo/index.html @@ -72,6 +72,8 @@ '../dist/deps.js', // This is required for goog.asserts. '../lib/debug/asserts.js', + // Compiled into Shaka Player, but outside of the Closure deps system. + '../node_modules/eme-encryption-scheme-polyfill/index.js', // This file contains goog.require calls for all exported library classes. '../shaka-player.uncompiled.js', // Enable less, the CSS pre-processor. diff --git a/karma.conf.js b/karma.conf.js index 1c5bf692d5..17c24ef8c7 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -83,6 +83,10 @@ module.exports = function(config) { // muxjs module next 'node_modules/mux.js/dist/mux.min.js', + // EME encryption scheme polyfill, compiled into Shaka Player, but outside + // of the Closure deps system. + 'node_modules/eme-encryption-scheme-polyfill/index.js', + // load closure base, the deps tree, and the uncompiled library 'third_party/closure/goog/base.js', 'dist/deps.js', diff --git a/lib/polyfill/encryption_scheme.js b/lib/polyfill/encryption_scheme.js new file mode 100644 index 0000000000..4a6212ef6c --- /dev/null +++ b/lib/polyfill/encryption_scheme.js @@ -0,0 +1,40 @@ +/** + * @license + * Copyright 2016 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +goog.provide('shaka.polyfill.EncryptionScheme'); + +goog.require('shaka.polyfill.register'); + +/** + * @summary A polyfill to add support for EncryptionScheme queries in EME. + * @see https://wicg.github.io/encrypted-media-encryption-scheme/ + * @see https://github.com/w3c/encrypted-media/pull/457 + * @see https://github.com/google/eme-encryption-scheme-polyfill + */ +shaka.polyfill.EncryptionScheme = class { + /** + * Install the polyfill if needed. + * + * @suppress {missingRequire} + */ + static install() { + EmeEncryptionSchemePolyfill.install(); + } +}; + +// Install at a low priority so that other EME polyfills go first. +shaka.polyfill.register(shaka.polyfill.EncryptionScheme.install, -1); diff --git a/package.json b/package.json index 68a68dbf2b..bf0565e4fa 100644 --- a/package.json +++ b/package.json @@ -64,5 +64,8 @@ "license": "Apache-2.0", "scripts": { "prepublishOnly": "python build/checkversion.py && python build/all.py --force" + }, + "dependencies": { + "eme-encryption-scheme-polyfill": "^1.0.0" } } diff --git a/shaka-player.uncompiled.js b/shaka-player.uncompiled.js index 0f8eea407b..8905b29f21 100644 --- a/shaka-player.uncompiled.js +++ b/shaka-player.uncompiled.js @@ -42,6 +42,7 @@ goog.require('shaka.offline.OfflineManifestParser'); goog.require('shaka.offline.OfflineScheme'); goog.require('shaka.offline.Storage'); goog.require('shaka.offline.indexeddb.StorageMechanism'); +goog.require('shaka.polyfill.EncryptionScheme'); goog.require('shaka.polyfill.Fullscreen'); goog.require('shaka.polyfill.IndexedDB'); goog.require('shaka.polyfill.InputEvent');