diff --git a/js/google_ima.js b/js/google_ima.js index e2a6c85..a07d425 100644 --- a/js/google_ima.js +++ b/js/google_ima.js @@ -34,6 +34,7 @@ require("../html5-common/js/utils/utils.js"); this.ready = false; this.runningUnitTests = false; this.sharedVideoElement = null; + this.enableIosSkippableAds = false; //private member variables of this GoogleIMA object var _amc = null; @@ -129,7 +130,7 @@ require("../html5-common/js/utils/utils.js"); this.canSetupAdsRequest = true; this.adTagUrl = null; this.currentMedia = null; - this.currentImpressionTime = 0; + this.currentImpressionTime = 0; this.adFinalTagUrl = null; this.adPosition = -1; this.showInAdControlBar = false; @@ -303,6 +304,12 @@ require("../html5-common/js/utils/utils.js"); this.imaIframeZIndex = metadata.iframeZIndex; } + this.enableIosSkippableAds = false; + if (metadata.hasOwnProperty("enableIosSkippableAds")) + { + this.enableIosSkippableAds = metadata.enableIosSkippableAds; + } + //On second video playthroughs, we will not be initializing the ad manager again. //Attempt to create the ad display container here instead of after the sdk has loaded if (!_IMAAdDisplayContainer) @@ -639,7 +646,10 @@ require("../html5-common/js/utils/utils.js"); { //resumeAd will only be called if we have exited fullscreen //so this is safe to call - this.sharedVideoElement.webkitEnterFullscreen(); + if (!_inlinePlaybackSupported()) + { + this.sharedVideoElement.webkitEnterFullscreen(); + } this.sharedVideoElement.play(); } _IMAAdsManager.resume(); @@ -1057,19 +1067,6 @@ require("../html5-common/js/utils/utils.js"); _amc.unregisterAdManager(this.name); return; } - _amc.onAdSdkLoaded(this.name); - //These are required by Google for tracking purposes. - google.ima.settings.setPlayerVersion(PLUGIN_VERSION); - google.ima.settings.setPlayerType(PLAYER_TYPE); - google.ima.settings.setLocale(OO.getLocale()); - if (this.useInsecureVpaidMode) - { - google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.INSECURE); - } - else - { - google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED); - } _IMA_SDK_tryInitAdContainer(); _trySetupAdsRequest(); @@ -1093,6 +1090,24 @@ require("../html5-common/js/utils/utils.js"); _IMAAdDisplayContainer.destroy(); } + //**It's now safe to set SDK settings, we have all the page level overrides and + //the SDK is guaranteed to be loaded. + + //These are required by Google for tracking purposes. + google.ima.settings.setPlayerVersion(PLUGIN_VERSION); + google.ima.settings.setPlayerType(PLAYER_TYPE); + google.ima.settings.setLocale(OO.getLocale()); + if (this.useInsecureVpaidMode) + { + google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.INSECURE); + } + else + { + google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED); + } + + google.ima.settings.setDisableCustomPlaybackForIOS10Plus(this.enableIosSkippableAds); + //Prefer to use player skin plugins element to allow for click throughs. Use plugins element if not available _uiContainer = _amc.ui.playerSkinPluginsElement ? _amc.ui.playerSkinPluginsElement[0] : _amc.ui.pluginsElement[0]; //iphone performance is terrible if we don't use the custom playback (i.e. filling in the second param for adDisplayContainer) @@ -1257,15 +1272,15 @@ require("../html5-common/js/utils/utils.js"); var isTimeout = false; var isEmpty = false; var isPlaybackError = false; - var errorCodes = { + var errorCodes = { vastErrorCode : errorData.getVastErrorCode(), innerErrorCode : errorData.getInnerError(), errorCode : errorData.getErrorCode() }; - OO.log("GOOGLE_IMA:: SDK Error received: Error Code List", JSON.stringify(errorCodes)); + OO.log("GOOGLE_IMA:: SDK Error received: Error Code List", JSON.stringify(errorCodes)); var imaErrorCodes = google.ima.AdError.ErrorCode; - switch (errorCodes.vastErrorCode) + switch (errorCodes.vastErrorCode) { case imaErrorCodes.VAST_MEDIA_LOAD_TIMEOUT: case imaErrorCodes.VAST_LOAD_TIMEOUT: @@ -1286,7 +1301,7 @@ require("../html5-common/js/utils/utils.js"); { isPlaybackError = true; } - + _amc.onSdkAdEvent(this.name, adError.type, {errorData: errorData}); if (isEmpty) { @@ -1357,14 +1372,11 @@ require("../html5-common/js/utils/utils.js"); _IMAAdsManager = adsManagerLoadedEvent.getAdsManager(_playheadTracker, adsSettings); // When the ads manager is ready, we are ready to apply css changes to the video element - // If the sharedVideoElement is not used, mark it as null before applying css if (this.videoControllerWrapper) { this.videoControllerWrapper.readyForCss = true; } - if (!_IMAAdsManager.isCustomPlaybackUsed()) { - this.setupSharedVideoElement(null); - } + if (this.videoControllerWrapper) { this.videoControllerWrapper.applyStoredCss(); @@ -1577,7 +1589,7 @@ require("../html5-common/js/utils/utils.js"); // don't have ad object associated. var eventType = google.ima.AdEvent.Type; var ad = adEvent.getAd(); - // Retrieve the ad data as well. + // Retrieve the ad data as well. // Some events will not have ad data associated. var adData = adEvent.getAdData(); @@ -1604,6 +1616,16 @@ require("../html5-common/js/utils/utils.js"); } //Since IMA handles its own UI, we want the video player to hide its UI elements _amc.hidePlayerUi(this.showAdControls, false); + + //in the case where skippable ads are enabled we want to exit fullscreen + //because custom playback is disabled and ads can't be rendered in fullscreen. + if (_inlinePlaybackSupported() && OO.isIphone && this.enableIosSkippableAds === true) + { + if (this.sharedVideoElement) + { + this.sharedVideoElement.webkitExitFullscreen(); + } + } } else { @@ -2169,6 +2191,11 @@ require("../html5-common/js/utils/utils.js"); } }; + var _inlinePlaybackSupported = function() + { + return !(OO.iosMajorVersion < 10 && OO.isIphone); + }; + var _throwError = function(outputStr) { //TODO consolidate code to exit gracefully if we have an error. diff --git a/test/unit-test-helpers/mock_ima.js b/test/unit-test-helpers/mock_ima.js index 7aee296..c536565 100644 --- a/test/unit-test-helpers/mock_ima.js +++ b/test/unit-test-helpers/mock_ima.js @@ -7,11 +7,13 @@ google = adManagerInstance : null, //for unit test convenience adLoaderInstance : null, //for unit test convenience adsRenderingSettingsInstance : null, //for unit test convenience + disableCustomPlaybackForIOS10Plus : false, //for unit test convenience resetDefaultValues : function() { google.ima.linearAds = true; google.ima.delayAdRequest = false; google.ima.adsRenderingSettingsInstance = null; + google.ima.disableCustomPlaybackForIOS10Plus = false; }, Ad : function() { //see https://developers.google.com/interactive-media-ads/docs/sdks/html5/v3/apis#ima.Ad @@ -86,6 +88,7 @@ google = setVpaidMode : function() {}, setLocale : function() {}, setDisableFlashAds : function() {}, + setDisableCustomPlaybackForIOS10Plus : function(newValue) {google.ima.disableCustomPlaybackForIOS10Plus = newValue;} }, AdsManagerLoadedEvent : { diff --git a/test/unit-tests/ima_test.js b/test/unit-tests/ima_test.js index 6183b38..f82fdbc 100644 --- a/test/unit-tests/ima_test.js +++ b/test/unit-tests/ima_test.js @@ -1837,4 +1837,42 @@ describe('ad_manager_ima', function() expect(_.isEmpty(google.ima.adsRenderingSettingsInstance)).to.be(false); expect(google.ima.adsRenderingSettingsInstance.loadVideoTimeout).to.be(15000); }); + + it('IOS Skippable Ads: Test page level param default', function () + { + //default case + ima.initialize(amc, playerId); + ima.loadMetadata({}, {}, {}); + ima.registerUi(); + expect(google.ima.disableCustomPlaybackForIOS10Plus).to.be(false); + expect(ima.enableIosSkippableAds).to.be(false); + }); + + it('IOS Skippable Ads: Test page level param false', function () + { + var content = + { + enableIosSkippableAds : false + }; + ima.initialize(amc, playerId); + ima.loadMetadata(content, {}, {}); + ima.registerUi(); + expect(google.ima.disableCustomPlaybackForIOS10Plus).to.be(false); + expect(ima.enableIosSkippableAds).to.be(false); + }); + + it('IOS Skippable Ads: Test page level param true', function () + { + var content = + { + enableIosSkippableAds : true + }; + ima.initialize(amc, playerId); + ima.loadMetadata(content, {}, {}); + ima.registerUi(); + expect(google.ima.disableCustomPlaybackForIOS10Plus).to.be(true); + expect(ima.enableIosSkippableAds).to.be(true); + }); + + });