Tizen Implementation
Sourcepoint's Tizen solution enables your organization to launch an OTT message campaign and collect end-user consent on Tizen OTT devices. In this article, we will cover how to implement our web-based solution for Tizen OTT devices.
If your organization is interested in implementing a native client Tizen solution, click here.

Requirements

In order to successfully utilize Sourcepoint's Tizen solution your organization will need to satisfy the following requirements:

Import project

Clone the Tizen SDK into your local workspace directory and:
    1.
    In Tizen Studio click File > Import menu item
    2.
    Choose the directory where you have just cloned the repo
    3.
    Select project to import from the list

Configure client details

The cloned files will allow your organization to demo an OTT message tied to a Sourcepoint controlled property. In this section, we will cover the necessary steps to edit the details of the cloned files to surface your organization's OTT message campaign.

index.html

Replace the accountId and propertyHref parameters in the index.html file with your account specific information.
1
<script>
2
!function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=3)}([function(t,e,n){var r=n(2);t.exports=!r((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,e,n){n(4),function(){if("function"!=typeof window.__tcfapi){var t,e=[],n=window,r=n.document;!n.__tcfapi&&function t(){var e=!!n.frames.__tcfapiLocator;if(!e)if(r.body){var o=r.createElement("iframe");o.style.cssText="display:none",o.name="__tcfapiLocator",r.body.appendChild(o)}else setTimeout(t,5);return!e}()&&(n.__tcfapi=function(){for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];if(!r.length)return e;if("setGdprApplies"===r[0])r.length>3&&2===parseInt(r[1],10)&&"boolean"==typeof r[3]&&(t=r[3],"function"==typeof r[2]&&r[2]("set",!0));else if("ping"===r[0]){var i={gdprApplies:t,cmpLoaded:!1,apiVersion:"2.0"};"function"==typeof r[2]&&r[2](i,!0)}else e.push(r)},n.addEventListener("message",(function(t){var e="string"==typeof t.data,r={};try{r=e?JSON.parse(t.data):t.data}catch(t){}var o=r.__tcfapiCall;o&&n.__tcfapi(o.command,o.parameter,o.version,(function(n,r){var i={__tcfapiReturn:{returnValue:n,success:r,callId:o.callId}};e&&(i=JSON.stringify(i)),t.source.postMessage(i,"*")}))}),!1))}}()},function(t,e,n){var r=n(0),o=n(5).f,i=Function.prototype,c=i.toString,u=/^s*function ([^ (]*)/;r&&!("name"in i)&&o(i,"name",{configurable:!0,get:function(){try{return c.call(this).match(u)[1]}catch(t){return""}}})},function(t,e,n){var r=n(0),o=n(6),i=n(10),c=n(11),u=Object.defineProperty;e.f=r?u:function(t,e,n){if(i(t),e=c(e,!0),i(n),o)try{return u(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported");return"value"in n&&(t[e]=n.value),t}},function(t,e,n){var r=n(0),o=n(2),i=n(7);t.exports=!r&&!o((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},function(t,e,n){var r=n(8),o=n(1),i=r.document,c=o(i)&&o(i.createElement);t.exports=function(t){return c?i.createElement(t):{}}},function(t,e,n){(function(e){var n=function(t){return t&&t.Math==Math&&t};t.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof e&&e)||Function("return this")()}).call(this,n(9))},function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){var r=n(1);t.exports=function(t){if(!r(t))throw TypeError(String(t)+" is not an object");return t}},function(t,e,n){var r=n(1);t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}}]);
3
</script>
4
5
<script>
6
(function () { var e = false; var c = window; var t = document; function r() { if (!c.frames["__uspapiLocator"]) { if (t.body) { var a = t.body; var e = t.createElement("iframe"); e.style.cssText = "display:none"; e.name = "__uspapiLocator"; a.appendChild(e) } else { setTimeout(r, 5) } } } r(); function p() { var a = arguments; __uspapi.a = __uspapi.a || []; if (!a.length) { return __uspapi.a } else if (a[0] === "ping") { a[2]({ gdprAppliesGlobally: e, cmpLoaded: false }, true) } else { __uspapi.a.push([].slice.apply(a)) } } function l(t) { var r = typeof t.data === "string"; try { var a = r ? JSON.parse(t.data) : t.data; if (a.__cmpCall) { var n = a.__cmpCall; c.__uspapi(n.command, n.parameter, function (a, e) { var c = { __cmpReturn: { returnValue: a, success: e, callId: n.callId } }; t.source.postMessage(r ? JSON.stringify(c) : c, "*") }) } } catch (a) { } } if (typeof __uspapi !== "function") { c.__uspapi = p; __uspapi.msgHandler = l; c.addEventListener("message", l, false) } })();
7
</script>
8
9
<script type="text/javascript">
10
window._sp_queue = [];
11
window._sp_ = {
12
config: {
13
accountId: CLIENT_ACCOUNT_ID,
14
baseEndpoint: 'https://cdn.privacy-mgmt.com',
15
propertyHref: 'PROPERTY_NAME',
16
ccpa: { },
17
gdpr: { }
18
}
19
}
20
</script>
21
22
<script src="https://cdn.privacy-mgmt.com/unified/wrapperMessagingWithoutDetection.js"></script>
Copied!
Additionally, to add event listeners to make the remote control work, the following script can be included in the index.html file:
1
<script type="application/javascript">
2
function Navigation(e){e=e||{},this.viewportModal=e.viewport||"[id^='sp_message_iframe_']",this.tvKey={KEY_ENTER:13,KEY_PAUSE:19,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_0:48,KEY_1:49,KEY_2:50,KEY_3:51,KEY_4:52,KEY_5:53,KEY_6:54,KEY_7:55,KEY_8:56,KEY_9:57,KEY_EMPTY:189,KEY_RED:403,KEY_GREEN:404,KEY_YELLOW:405,KEY_BLUE:406,KEY_RW:412,KEY_STOP:413,KEY_PLAY:415,KEY_REC:416,KEY_FF:417,KEY_CH_UP:427,KEY_CH_DOWN:428,KEY_VOL_UP:447,KEY_VOL_DOWN:448,KEY_MUTE:449,KEY_INFO:457,KEY_GUIDE:458,KEY_RETURN:10009,KEY_SOURCE:10072,KEY_CHLIST:10073,KEY_MENU:10133,KEY_TOOLS:10135,KEY_ASPECT:10140,KEY_EMANUAL:10146,KEY_EXIT:10182,KEY_PRECH:10190,KEY_MTS:10195,KEY_3D:10199,KEY_TTX_MIX:10200,KEY_CAPTION:10221,KEY_SEARCH:10225,KEY_SOCCER:10228,KEY_REWIND_:10232,KEY_FF_:10233,KEY_PLAY_PAUSE:10252,KEY_EXTRA:10253},this.onLoad()}Navigation.prototype={onLoad:function(){this.registerKey("0"),this.registerKey("1"),this.bindEvents()},getViewportWindow:function(){const e=document.querySelector(this.viewportModal);return!!e&&e.contentWindow},getActiveElement:function(e=document.activeElement){const t=e.shadowRoot,i=e.contentDocument;return t&&t.activeElement?this.getActiveElement(t.activeElement):i&&i.activeElement?this.getActiveElement(i.activeElement):e},triggerClick:function(){const e=this.getActiveElement();let t=new Event("keydown",{bubbles:!0,cancelable:!0});t.keyCode=this.tvKey.KEY_ENTER,"font-weight: normal;"===e.style.cssText&&(t=new KeyboardEvent("keypress",{key:"Enter",bubbles:!0,charCode:0,keyCode:this.tvKey.KEY_ENTER})),e.dispatchEvent(t)},registerAllKey:function(){let e,t=window.tizen.tvinputdevice.getSupportedKeys();for(e=0;e<t.length;e+=1){try{this.registerKey(t[e].name)}catch(i){logger.error("[registerAllKey] Failed to register "+t[e].name)}this.tvKey[t[e].code]=t[e].name}logger.debug("[registerAllKey] Register all supported keys. [available:"+t.length+"; registered:"+e+"]")},registerKey:function(e){window.tizen.tvinputdevice.registerKey(e)},unregisterKey:function(e){window.tizen.tvinputdevice.unregisterKey(e)},onKeyDown:function(e){const t=tileNavigation.getViewportWindow();switch(e.keyCode){case tileNavigation.tvKey.KEY_ENTER:t&&tileNavigation.triggerClick();break;case tileNavigation.tvKey.KEY_EXIT:window.tizen.application.getCurrentApplication().exit();break;case tileNavigation.tvKey.KEY_1:logger.toolbarToggle();break;case tileNavigation.tvKey.KEY_0:window.location.reload();break;default:if(t){const i=new Event("keydown",{bubbles:!0,cancelable:!0});i.currentTarget=e.currentTarget,i.keyCode=e.keyCode,t.dispatchEvent(i)}}},bindEvents:function(){window.addEventListener("keydown",this.onKeyDown)}};
3
var tileNavigation,DemoCMP={},logger=new Logger({debugMode:!0});DemoCMP.LoadCMP=function(){tileNavigation=new Navigation;try{logger.debug("Widget version: "+window.tizen.application.getAppInfo().version)}catch(o){logger.debug(o)}},window.onload=DemoCMP.LoadCMP();
4
</script>
Copied!
In the navigation.js file, you organization will be able to configure the methods for your project. In the table below, please find the available methods for your Tizen project.
Note: These methods are already configured in the demo file.
Method
Description
onLoad
runs on startup, trigger registerAllKey and bindEvents functions
getViewportWindow
get window object of an iframe
getActiveElement
get an active element of the document
triggerClick
handle enter button pressed event
registerAllKey
register all available keys of a remote control
registerKey
register a button of a remote control by key name
unregisterKey
unregister a button of a remote control by key name
onKeyDown
handle pressed keys of a remote
bindEvents
add event listener from a remote control

Run Tizen simulation

To test your configuration (or the demo configuration) in the Tizen simulator, right-click the project and navigate to Run As > Tizen Web Simulator Application (Samsung TV).
If successful, your OTT message campaign will be surfaced in the simulator.
Last modified 1mo ago