Yahoo! Connected TV — Frequently Asked Questions

Here is a list of the most commonly asked questions with their answers. Additional answers, troubleshooting, and testing support for TV Widgets are provided through the Connected TV forums at this URL:
http://developer.yahoo.net/forum/index.php?showforum=91

Business FAQ

Development FAQ

Distribution FAQ

 

 

 

Business FAQ

Q: Does the platform support DRM?

The DRM services supported by Connected TV devices vary by manufacturer. The Yahoo! Widget Engine supports a DRM services interface whose implementation is provided by device partners.

To discuss content protection concerns and acceptable security level options, content providers can contact the Yahoo! Connected TV partner integration team at the following email address: tvwidgets@yahoo-inc.com

 

 

 

Development FAQ

Networking

Q: Do you support both synchronous and asynchronous calls?

Be sure to fetch data asynchronously from your back-end server as device resources are limited. TV Widgets should not make synchronous calls and will not pass the Yahoo! QA process with synchronous calls. Please download the TV Widget Acceptance Criteria (.doc or .rtf) for additional requirements.

Example — URL.fetchAsync()

For more detail, see the URL.fetchAsync() online reference.

var url = new URL();
url.location = "http://www.yahoo.com";
url.fetchAsync(url_done);
function url_done(url){
    print("fetch complete");
    print("response: " + url.response);
    print("result: " + url.result);
}
Example — XMLHttpRequest

For more detail, see the XMLHttpRequest online reference, XPath Support, and the XML DOM API Reference.

var request = new XMLHttpRequest();
request.onreadystatechange = myStatusProc;
request.open("GET", "http://www.yahoo.com", true);
request.send();

// someplace else
function myStatusProc(){
    if (this.readyState == 4) {
        // complete
        print(this.status);
    }
}

Review the discussions in the TV Widget Developer Forum for relevant content: http://developer.yahoo.net/forum/index.php?showtopic=5064

Q: Do you support XML response data (XMLHttpRequest)?

Try to use JSON instead of XML. Parsing large blocks of XML is slow and resource intensive. Avoid using XML on all device platforms. Use JSON for significantly faster performance. See the FAQ on asynchronous calls.

Q: How do you test for network failure?

Widgets need to detect changes in network availability and support both offline and online modes as appropriate. Testing for the "Network Disconnected" state is part of the TV Widget QA and approval process. To streamline getting your widget into the production widget gallery, be sure your widget properly handles the following disconnected states:

  1. Disconnect and reconnect WAN cable from router
    • causes loss of connectivity but retains IP address
  2. Disconnect and reconnect LAN cable from router
    • causes loss of connectivity and loss of IP address
  3. Perform Use Case 1 and Use Case 2 above in the following widget states:
    • Snippet
    • Sidebar
    • Fullscreen view with TV Passthrough off, if applicable
    • Fullscreen view with TV Passthrough on, if applicable
    • Fullscreen view with streaming video, if applicable

 

Check the Network Status before calling XMLHttpRequest and URL methods

Your widget should never initiate an XMLHttpRequest or URL request when the physical network is down. You should use the KONtx.application.­­isPhysicalNetworkDown() method in tandem with the KONtx.­application.getNetworkDownStatus accessor method to differentiate between the physical network being down and a request error (from XMLHttpRequest or URL methods) set by the widget.

KONtx.application.isPhysicalNetworkDown()

In KONtx Framework v1.3.18 and above the KONtx.application.­isPhysicalNetworkDown() method has been added to check if the physical network is disconnected.

  • If KONtx.application.­isPhysicalNetworkDown() returns true, the network is down and you should not make the request.
  • If KONtx.application.­isPhysicalNetworkDown() returns false, it is safe to make the request.

 

When the KONtx Framework detects that the physical network is down, a "physical disconnect" dialog is displayed.

KONtx.application.getNetworkDownStatus

The legacy accessor method KONtx.application.­getNetworkDownStatus is true when the network is disconnected or when your widget's network request has failed (as set by your widget).

The KONtx.application.isPhysicalNetworkDown() method only checks the status of the physical network. If this returns false, we know that the physical network is up, and it's safe to send out an XMLHttpRequest or URL request, even if the current value of KONtx.application.­getNetworkDownStatus is true. When the new request succeeds, the widget should clear the request error by calling KONtx.application.­setNetworkRequestFailed(false) in the request interface.

Set the Network Status when a Network Request Fails

If your widget's XMLHttpRequest or URL network request fails, the widget should inform the KONtx Framework so that a “no network” icon can be displayed on the widget and a "request failed" dialog can be brought up. On a failed network request, the widget should call KONtx.application.­setNetworkRequestFailed(true). For each successful network request, the widget should set the network status to “connected” by calling KONtx.application.­setNetworkRequestFailed(false). In the example below, the method setNetworkRequestFailed() is wrapped in the myWidget namespace (see the section on backward compatibility):

function callAPI(url, callback) {
    if (KONtx.application.isPhysicalNetworkDown()) {
        log("the network is down!");
        return;
    }
    var request = new URL();
    request.callback = callback;
    request.location = url;
    KONtx.utility.WaitIndicator.up();
    request.fetchAsync(function (u) {
        KONtx.utility.WaitIndicator.down();
        if (u.response == 200){
            myWidget.application.setNetworkRequestFailed(false);
            u.callback(u.result);
        } else {
            myWidget.application.setNetworkRequestFailed(true);
        }
    });
}

Handle the onNetworkHideDialog Event

The onNetworkHideDialog event allows you to have more control over what happens when network connectivity is restored. This event is fired when the KONtx Framework detects that the network issue is resolved.

The default behavior for this event is to auto-hide the "no network" dialog box and to return to the currently displayed widget. If you prevent the default behavior from happening, the dialog box will not be auto-hidden, and the consumer is forced to dismiss the dialog and returned to the widget dock.

To change the default action, you can implement custom behavior in the event handler. To handle the onNetworkHideDialog event fired by the KONtx.application class, subscribe to it in your init.js file—for example:

EventHandlers.onNetworkHideDialog.subscribeTo(
    KONtx.application, 
    "onNetworkHideDialog", 
    EventHandlers
);

If the onNetworkHideDialog event's property event.payload.type is equal to 1, the dialog about to be hidden is a "physical disconnect" dialog. If event.payload.type is equal to 2, the dialog is a "request failed" dialog.

Do not fetch data inside the onNetworkHideDialog handler as the network may be unstable. If the KONtx Framework is displaying a "physical disconnect" dialog, and your widget has stale data or is not ready for display, you may want to call event.preventDefault(), for example:

if (event.payload.type == 1) {
    // Check if you have the base data you need to render your main view
    // This would normally be config data which you would fetch at widget startup
    // DO NOT fetch data inside this handler, the network is unstable
    if (data_ready == false) {
        event.preventDefault();
    }
}

The onNetworkConnectionReconnect event is fired when the network's physical connection is restored and stays stable for 60 seconds or more. If you subscribe to this event, subsequent network requests made by the widget should succeed. However, use of this event is not recommended. The suggested best practice is to wait until the consumer accesses your widget from the dock before firing new requests after a network reconnection.

Support Backward-Compatibility with other KONtx Framework versions

To be backward-compatible with older versions of the KONtx Framework, Yahoo! recommends you follow these steps:

1. Create a custom object to set the network down status.

// Replace myWidget with your widget's custom object

myWidget.network = (function () {
    var setDownByUser = false;
    return {
        setNetworkRequestFailed: function (status) {
            KONtx.application.setNetworkRequestFailed(status);
            setDownByUser = status;
        },
        isPhysicalNetworkDown: function () {
            if (KONtx.application.getNetworkDownStatus) {
                return !setDownByUser;
            }
            return false;
        }
    };
})();

2. Use a wrapper to test for the method's existence. Define this wrapper in init.js or someplace parsed once at runtime.

if (typeof KONtx.application.isPhysicalNetworkDown === "undefined") {
    KONtx.application.isPhysicalNetworkDown = function () {
        // Replace myWidget with your widget's custom object
        return myWidget.network.isPhysicalNetworkDown();
    };
}

3. Set the network down status when your XMLHttpRequest() or URL() requests fail. On a failed network request the widget should call KONtx.­application.setNetworkRequestFailed(true). For each successful network request the widget should set the network status to “connected” by calling KONtx.application.­setNetworkRequestFailed(false).

function callAPI(url, callback) {
    if (KONtx.application.isPhysicalNetworkDown()) {
        log("the network is down!");
        return;
    }
    var request = new URL();
    request.callback = callback;
    request.location = url;
    KONtx.utility.WaitIndicator.up();
    request.fetchAsync(function (u) {
        KONtx.utility.WaitIndicator.down();
        if (u.response == 200){
            myWidget.application.setNetworkRequestFailed(false);
            u.callback(u.result);
        } else {
            myWidget.application.setNetworkRequestFailed(true);
        }
    });
}

 

Video / Audio / Media Player

Q: How do you migrate from KONtx.videoplayer to KONtx.mediaplayer?

Refer to the "Migrating to KONtx.mediaplayer" section in the TV Widget Media Player API Reference (.pdf).

Q: What video/audio codecs are supported?

To ensure that your TV Widget’s video works on all supported TVs/devices the following encoding specifications have been verified on all Connected TV devices. Deviating from these recommended video encoding parameters may render the video incompatible with deployed or legacy systems.

Streaming Transport

Progressive download over HTTP is supported. Many encoders have an option to enable Internet streaming where the stream is buffered so that playback starts before the whole clip is fully downloaded.

Some device-specific media players support seeking to particular times inside a piece of media by jumping to a relative or absolute offset. Video-seeking and time index changes require a special version of GStreamer (0.10.23) to test on the Simulator, so typically time index testing occurs on the TV/device. To support stopping at a particular point in a video, the event onTimeIndexChanged fires at one second intervals. Currently none of the devices in production support fast forward and rewind over HTTP streams.

Other supported streaming protocols vary by device. Currently one device partner supports MMS and other device partners will be supporting M3U8 and RTSP late in 2010 and early 2011. Existing devices can support a video playlist of URLs, but do not support a continuous open stream. The Yahoo! Widget Engine also supports redirection for the video playlist URLs.

Currently play-listed progressive download is being used for radio widgets. HTTP streaming audio is supported through a fullscreen view where you have exclusive access to the audio pipeline. In fullscreen mode, there is no mixing with any other audio signals. You cannot playback audio (or video) from the sidebar view, as it will be mixed with the audio from the TV Channel. Play-listed progressive download is supported by the current Connected TV devices, but a continuous open stream is not supported. The playlist can be a series of audio files, which play one after the other over an HTTP stream. The majority of our platform partners have all specified they are supporting HTTP live streaming protocols in their 2011 devices. Some partners will come out with updated firmware for existing devices as well. Currently our Simulator supports live streaming for your development needs.

Encoding Formats

The following encoding formats have been tested and work across all Connected TV devices:

  • MP4 / H.264 / AAC — Recommended
    • Container: MP4 (mpeg4)
    • Codec: H.264
    • Audio: AAC
  • WMV9 / VC-1 / WMA
    • Container: WMV9
    • Codec: VC-1
    • Audio: WMA

Constant/Variable Bit Rate

Optional. Both Constant Bit Rate (CBR) and Variable Bit Rate (VBR) are supported.

Multiple Video Bitrates

Yahoo! recommends choosing one resolution based on your source video's size, and then encoding your videos in multiple bitrates to support varying connection bandwidth. The KONtx.mediaplayer chooses the best stream given the current connection speed returned from KONtx.speedtest. Support for the following video bitrates is recommended:

  • 300 kbps
  • 700 kbps
  • 1000 kbps
  • 2000 kbps

Audio Bitrate

The recommended audio bitrate is 128 kbps for standard bitrate quality.

Resolution

All devices are HD compatible and have a 16:9 aspect ratio. However, the device's available network bandwidth limits HD resolution to 1280 x 720. PAL resolutions are supported. Depending on your content source, the following pixel resolutions are recommended:

  • 640 x 360 — (medium quality 16:9)
  • 640 x 480 — (medium quality 4:3)
  • 720 x 480 — (high quality)
  • 1280 x 720 — (for HD content only)

B-frames

Optional.

Encoding Passes

Optional.

Frame Rate

Optional. Typical frame rates of 29.97 fps for video-based source material and 23.97 fps for film-based source material are supported.

Q: How do you test video playback?

Video playback behavior and performance in the Simulator are not representative of video playback behavior and performance on a TV/device.

The Simulator uses the video playback software library GStreamer to decode and render video. Typically, the software rendering provided by GStreamer is much slower than hardware optimized rasterization. You may see that the audio and video playback is not in sync. This is not representative of device media player behavior. Detailed specifications for each device’s media player implementation do not yet exist. You can go to http://connectedtv.yahoo.com to find out more about Connected TV devices.

If you have trouble testing video in your TV Widget please follow these recommended steps:

  1. Use small test files that are less than 20 MB. This is for testing purposes only.
  2. Check to see that all the GStreamer packages are installed. Try setting the following environment variable:
    export KF_GSTREAMER_USE_ALTERNATIVE_PIPELINE=1
  3. Test using the Simulator with the latest KONtx Framework and Yahoo! Widget Engine (via the Latest Production Simulator menu item from the Applications→TV Widgets→Latest Production menu).
  4. Update the Simulator and sample widgets software when updates are available (via the Latest Production Simulator Update Widgets menu item from the Applications→TV Widgets→Latest Production menu).
  5. Use the MediaPlayerSample widget (located in $HOME/TVWidgets/Konfabulator-Latest/TV/Widgets/) as a template for using the KONtx.mediaplayer API.
  6. Test all video-related code on an actual TV/device. Playback behavior and performance on the Simulator are not representative.
  7. Update the firmware of your TV/device. New features may be supported on new device models, for example US and European models vary in format and feature support.
  8. Test the device's media player using the Simulator Console. Launch the Simulator. Let the dock load. Do not interact with any widgets. On the Simulator Console command line, execute the following:
    tv.mediaPlayer.load("http://mycompany.com/test/test.mp4");
    tv.mediaPlayer.play();

    You must run the commands above from a fresh start of the Simulator to avoid an inconsistent state.  If these commands fail there may be a problem with the media player installation.
  9. Test the device's sound server using the Simulator Console. An error message of "Invalid argument" from the gstreamer pipeline may be caused by the sound server. Try setting the sound server to ALSA or PulseAudio instead of auto-detect. Try to playback the stream by entering the following command in the Simulator Console:
    gst-launch playbin uri=http://mycompany.com/test/test.mp4
  10. Test local files. If the stream stalls while buffering it usually indicates an issue with the stream server. In these test cases, store the file locally and use a local uri (for example, file:///noise.mp4).
  11. Test playback through the entire video stream so you can test end-of-stream behavior.
  12. Research existing video playback sample solutions in the TV Widget Developer Forums http://developer.yahoo.net/forum/index.php?showforum=91

Q: How does video buffering work?

Typically devices cannot buffer more than 100 MB of video. If the video metadata moov atom is at the end of the video, and the video size is larger than the device’s buffer size, the device’s media player will not play the video. Some media players can fetch the video metadata from the end of the file but not all devices support this behavior.

Some encoders, for example Quicktime, have options for Internet streaming which put the video metadata at the front file. For Quicktime, the qt-faststart utility rearranges the top-level atoms by shifting the moov atom from the back of the file to the front, and patches the chunk offsets along the way. This utility only operates on uncompressed moov atoms. To move the metadata to the front of the file run:

qt-faststart original.mov new_file.mov 

Q: How do you configure the aspect ratio of the media player?

The default viewport configuration for the media player has the (x,y) position at (0,0) and sets the width and height of the viewport to 1920x1080. To use the default viewport configuration for the media player use the following methods:

KONtx.mediaplayer.setViewportBounds(KONtx.mediaplayer.getDefaultViewportBounds()); 

The default viewport will stretch 4:3 content during playback on some devices. The video playback on the Simulator is not intended to be an indicator of video playback on the Connected TV device. If you want to configure the aspect ratio of video playback for 4:3 content without stretching you can set the viewport properties as follows:

var bounds = {
  x: 333,
  y: 333,
  width: 640,
  height: 480
};
KONtx.mediaplayer.setViewportBounds(bounds); 

Q: How do you letterbox the video plane?

The graphical plane sits on top of the video plane. To have video playback within a graphical boundary, create a transparent area within your background image.

Q: Do you support streaming audio?

Currently play-listed progressive download is being used for radio widgets. HTTP streaming audio is supported through a fullscreen view where you have exclusive access to the audio pipeline. In fullscreen mode, there is no mixing with any other audio signals. You cannot playback audio (or video) from the sidebar view, as it will be mixed with the audio from the TV Channel. Play-listed progressive download is supported by the current Connected TV devices, but a continuous open stream is not supported. The playlist can be a series of audio files, which play one after the other over an HTTP stream. The majority of our platform partners have all specified they are supporting HTTP live streaming protocols in their 2011 devices. Some partners will come out with updated firmware for existing devices as well. Currently our Simulator supports live streaming for your development needs.

Images and Animation

Q: How do you handle image load failure?

To handle image load failure add onError events where you instantiate the image. For example:

var myImage = new KONtx.element.Image({
    src: "Images/960x540/detail/play.png",
    missingSrc: "Images/960x540/missingImage.png",
    events: {
        onLoaded: function(event) {
            // Do something on load of an image, like resize or add a border
        },
        onError: function(event) {
            // Do something on failure to load the image
        }
    }
});

Q: How do you change an image after view creation?

To change an image in an existing view call:

myImage.setSource(newURL);

Q: Do you support animation?

Currently animation is not supported. Many partner platforms do not have enough processing power at this time to support animation. Please let us know your animation requirements and feedback on simplified animation support for Connected TV devices through the developer forum:
http://developer.yahoo.net/forum/index.php?showforum=91

Q: Why does the Simulator screen appear black?

When you first launch the Simulator, the screen may appear totally black. Resizing the window (maximizing it and returning it to its regular size) forces a refresh of the background and provides the correct display. This workaround is also valuable when playing video. Pressing the F10 key (BACK) causes video playback to stop, but does not close the video screen. Resizing the window after pressing the F10 key (BACK), forces a refresh of the background and provides the correct display.

User Interface Controls

Q: How do you set up button handlers that access the containing view?

There are two basic approaches to set up button selection handlers that affect or need information from the containing view.

Example — this.getView()

The first method is to get a reference to the view while within the button's scope.

this.controls.my_button = new KONtx.control.TextButton({
    events: {
        onSelect: function () {
            this.setText('You selected me!');
            var view = this.getView();
            view.controls.other_button.setDisabled(true);
        }
    }
}).appendTo(this);

Example — bindto(this)

You can also bind the method to the view to guarantee that this will reference the view while within the button’s onSelect listener. This method of accessing the view from within a button scope is useful if your onSelect listener operates mostly on items in the view's scope.

this.controls.my_button = new KONtx.control.TextButton({
    events: {
        onSelect: (function () {
            this.controls.my_button.setText('You selected me!');
            this.controls.other_button.setDisabled(true);
    }).bindTo(this)
  }
}).appendTo(this);

Q: How do you redefine the back button?

The BACK button is integral to the interaction model defined for the widget. Changes to the default BACK button behavior should be limited to the following example. If your widget moves from Home to View A to View B:

Home→View A→View B

and you do not want the BACK button to go from View B to View A, call the loadView() method when going to View B as follows:

KONtx.application.loadView('view-B', myPersistParams, true);

This call prevents View A from being stored in the view history. An example of this behavior is useful when changing a video player view to a video post roll view. When selecting the BACK button from the post roll view, the consumer should not go back to the player view, but instead, all the way back to the sidebar or detailed view.

Before investing resources in design and development, please send email to tvwidgets@yahoo-inc.com to get approval for this user interface behavior change. In order to pass the TV Widget Acceptance Criteria, when you submit your widget for production approval, you must outline this "BACK Button Use Case" for testing purposes. Please download the TV Widget Acceptance Criteria (.doc and .rtf) for additional requirements.

Q: How do you wrap text properly?

To make text wrap properly based on the width of the container, you need to specify the styles.width property at the same time as setting the wrap property to true. If you add the wrap property and your text object is no longer displayed, check that the styles.width property is set.

Example — Centered, Wrapped, and Truncated

Here is an example of centered, wrapped, and truncated text:

var descTxt = new KONtx.element.Text({
    label: dataItem.description || ' ', 
    wrap: true, 
    truncation: 'end', 
    styles: { 
        visible: (ss.show_title_description && true) || false, 
        fontSize: '26px', 
        color: '#FFFFFF', 
        textAlign: 'center', 
        width: 584, 
        height: 36, 
        hOffset: 12, 
        vOffset: 70 
    }
}).appendTo(container); 

Example — Left-Justified, Wrapped, and Truncated

Here is an example of left-justified, wrapped, and truncated text:

var descTxt = new KONtx.element.Text({
    label: dataItem.description || ' ',
    wrap: true, 
    truncation: 'end', 
    styles: { 
        visible: (ss.show_title_description && true) || false, 
        fontSize: '26px', 
        color: '#FFFFFF', 
        textAlign: 'left', 
        width: 584, 
        height: 36, 
        hOffset: 12, 
        vOffset: 70 
    } 
}).appendTo(container);

Q: How do you get date/time values on the TV?

Be careful when using JavaScript Date/Time methods which may work on the Simulator but will not work on the TV device. The TV device does not maintain an accurate real time clock and restarts at zero each time the TV is turned on. The method to get the current time is as follows:

var datetime = getRealTime();

The method getRealTime() returns the number of seconds since the epoch. Convert this time from seconds to milliseconds to use the JavaScript Date formatting and conversion methods.

var date = new Date(getRealTime() * 1000);

If the date returned from this function is January 1, 1970, Coordinate Universal Time (UTC), check that your clock has been reset properly.

Q: How do you set up a timer?

Use the Timer class with MessageCenter together to get a callback in your view:

File init.js:

var myTimer = new Timer(); 
myTimer.onTimerFired = function () {
    var beat = getRealTime()*1000; // getRealTime() is provided by the Yahoo! Widget Engine
    KONtx.messages.store("TimerTrigger", beat); 
};
myTimer.interval = 10; // in seconds 
myTimer.ticking = true; // kick it off

File myView.js:

var myView = new KONtx.Class({
    initView: function(){ 
        this.registerMessageCenterListenerCallback(this.onBroadcast); 
    }, 
    onBroadcast: function(event){ 
        switch (event.payload.key) { 
            case "TimerTrigger": 
                var currentTime = new Date(event.payload.value); 
                // Your implementation here
                break;
            default:
                break;                  
        } 
    }
});

Q: How do you authenticate an account?

You can login to a remote server account using the KONtx.dialogs class which creates a generic dialog box for username and password text entry. The login dialog box does not automatically handle new account authentication when the profile is switched. You can store authentication information in the currentAppData storage class which stores application data for the active profile.

Example — Generic Login
// Fetch Login Credentials if they exist
var loginData = currentAppData.get("loginCredentials");
if (loginData === null) { 
    var dialog = new KONtx.dialogs.Login({ 
        title: "Login to my service", 
        message: "To use this functionality, you need to login below", 
        callback: function(result) { 
            var user = result.username; 
            var pwd = result.password; 
            // Verify login
			
            // Store Login Credentials 
            currentAppData.set("loginCredentials", {username: user, password: pwd});
        },
        logo: "Assets/960x540/logo_snippet_65x29.png",
cancelCallback: function (){ // Handle user cancels login } }); dialog.show(); }

Q: How do you store Copyright, Terms of Service, and Privacy policies?

Ideally you would pull the Copyright, TOS, and Privacy text on-demand from your web site. If you wish to package the text up, use an XML file in your Contents directory. For example:

File TOS.xml

<?xml version="1.0" encoding="UTF-8"?>
<tos>
<![CDATA[
  I am the TOS, and no character escaping is needed.
  ]]>
</tos>

Then use XMLDOM.parseFile() to read in the XML file in a view:

var TosView = new KONtx.Class({
    title: 'TosView',
    Extends: KONtx.system.SidebarView,
    config: {
        tos_key: 'tos',
    },
    createView: function() {
        this.controls.buttonHeight = KONtx.utility.scale(35);
        this.controls.agree = new KONtx.control.TextButton({ 
            guid: 'agree-button', 
            label: 'I agree',
            styles: { 
                width:this.width/2,
                height: this.controls.buttonHeight,
                vOffset: this.height-this.controls.buttonHeight
            },
            events: {
                onSelect: function(event) {
                    currentAppData.set(this.getView().config.tos_key, "you have seen the tos");
                    KONtx.application.loadView('view-Main', {});
                }
            } 
        }).appendTo(this); 
        this.controls.disagree = new KONtx.control.TextButton({ 
            guid: 'agree-button', 
            label: 'I do not agree',
            styles: { 
                width:this.width/2,
                hOffset: this.width/2,
                height: this.controls.buttonHeight,
                vOffset: this.height-this.controls.buttonHeight
            },
            events: {
                onSelect: function(event) {
                KONtx.HostEventManager.send('exitToDock');
                }
            } 
        }).appendTo(this); 
        this.controls.pageIndicator = new KONtx.control.PageIndicator({
            guid: 'pager', 
            styles: {
                width: this.width,
                height: this.controls.buttonHeight,
                vOffset: this.controls.agree.outerHeight-this.controls.agree.height -this.controls.buttonHeight,
            }
        }).appendTo(this);
        this.controls.content = new KONtx.element.TextGrid({
            guid: 'tos',
            styles: {
                fontFamily: '"Helvetica Neue Regular"',
                fontSize: 12,
                color: '#FFFFFF',
                padding: 5,
                wrap: true,
                width: this.width,
                height: this.height-this.controls.agree.height-this.controls.pageIndicator.height,
            }
        }).appendTo(this).attachAccessories(this.controls.pageIndicator);
    },
    updateView: function() {
        var tos = XMLDOM.parseFile("TOS.xml");
        this.controls.content.setText(tos.documentElement.firstChild.nodeValue);
    }
});

Redirect the view to the TOS if this is the first time opening the widget. Save a Boolean value into currentAppData to show that you have read the TOS.

File init.js:

include("Framework/kontx/version/src/all.js");
include("Javascript/views/TosView.js");
include("Javascript/views/snippet.js");
include("Javascript/views/sidebar.js");
include("Javascript/views/settings.js");

KONtx.application.init({
    views: [
        { id: 'view-Main', viewClass: SampleSidebarView },
        { id: 'view-Player', viewClass: SamplePlayerView },
        { id: 'view-Settings', viewClass: SettingsView },
        { id: 'snippet-main', viewClass: SampleSnippetView },
        { id: 'view-Tos', viewClass: TosView },
    ],
    defaultViewId: 'view-Main',
    settingsViewId: 'view-Settings',
});
(function (event) {
    var snippet_id = event.payload.viewId;
    var load_tos = (currentAppData.get('tos')==null)?true:false;
    if (load_tos) {
        event.preventDefault();
        event.stopPropagation();
        KONtx.application.setHostResultToViewId(event, 'view-Tos', {} );
    }
}).subscribeTo( KONtx.application, 'onActivateSnippet' );

Examples and Samples

Q: How do you get more widgets in my Simulator dock?

The Simulator has access to only platform and sample widgets from the Yahoo! Widget Gallery and does not have access to commercial TV Widgets.

Q: Where can you find media player examples?

Examples for the KONtx.mediaplayer interface can be found in the "Media Player Examples" section of the TV Widget Media Player API Reference (.pdf).

Q: Where can you find sample widgets?

Sample widgets are installed with the WDK. For detailed steps see the section, Extract a Sample Widget to Your Development Directory.

Debugging and Testing

Q: Which version of Ubuntu should you use?

The Simulator has been tested and is supported on the provided Ubuntu 10.04 Linux VMware virtual machine (VM) for Mac OS X and Windows. See the Installation Guide.

Q: How do you debug on the Simulator?

Widget developers can use the Simulator Console to inspect both the widget engine and toolbox objects during runtime. When you launch the widget engine, a terminal window running the Simulator Console is also launched. You can type commands into this terminal window.

For a list of debugger commands, see Debugging with the Simulator Console.

Q: How do you debug on the TV?

To debug your widget on a TV send a request to a web server, and view the logs. The example below uses the regular log() function when debugging on the Simulator, and sends HTTP requests when debugging on the TV. For production releases this type of logging should be disabled.

function myLog(s) {
    if (myPlatform.buildConfig == 'beta') {
        var r = new XMLHttpRequest();
        r.onreadystatechange = function() {};
        r.open("GET", "http://mycompany.com/debug?output=" + s, true);
        r.timeout = 10;
        r.send();
    } else {
        log(s);
    }
}

Q: How do you test the remote control using the Simulator?

To test the remote control keys using the Simulator, type the following commands into the Simulator Console. First attach the debugger to your widget:

/widgets
/widgets number-of-your-widget
/key Up
/key Down
/key Left
/key Right
/key Select
/key Home

/key Play
/key Pause
/key Stop
/key Rewind
/key Forward

/widgets
/widgets number-of-container-widget-one-or-two
/key Red
/key Green
/key Yellow
/key Blue

You can also use the Keyboard to Remote Control Mapping table.

 

 

 

Distribution FAQ

Q: How do you initiate the TV Widget QA process?

The QA process starts when we receive your TV Widget's completed TV Widget Acceptance Criteria Form (download the .doc or the .rtf file).

When you are ready to enter the production QA process, send your completed TV Widget Acceptance Criteria document to tvwidgets@yahoo-inc.com. For a complete list of required steps, see this section on Uploading to the Widget Gallery Service . Yahoo! Connected TV will acknowledge your submission through email and will update you as your TV Widget moves through the QA process.

Q: Which device partners support the application framework's new media player interface, KONtx.mediaplayer?

The KONtx.mediaplayer interface is implemented in KONtx Framework v1.3 (and above) and is shipped out-of-the-box in all 2010 devices. Older 2009 devices using KONtx v1.2 or KONtx v1.1 will not support TV Widgets using the KONtx.mediaplayer interface and its advanced features. These older devices will work with widgets using the legacy KONtx.videoplayer interface.

When you submit the TV Widget Acceptance Criteria (download the .doc or the .rtf file), you must list the Supported OEMs and identify the platforms on which your TV Widget should be distributed. If you are submitting a media-based widget to Vizio, you must use KONtx.mediaplayer. All OEMs in your Supported OEMs list should support your TV Widget's use of the media player interface.

Q: Do you require additional QA tests after bug fixes or other changes?

If you fix a bug, or change your TV Widget's software (or user interface assets) you need to resubmit your TV Widget to the QA process. You do not need to send a new TV Widget Acceptance Criteria form unless an update is necessary (for example, new use cases). To resubmit a TV Widget, send email to tvwidgets@yahoo-inc.com with a description of your changes. If Yahoo! has provided you with a bug list, you need to update the bug list with each bug's resolution and attach it to your email.

Q: How long does it take for a widget to get through the approval process?

The shortest path to production is 3 weeks. This occurs when the widget developer submits a bug-free widget for production release. During this time both Yahoo! and the device partners must pass the widget through their QA processes without a bug or issue.

Once Yahoo! QA has been passed, the widget developer will be informed that his or her widget has met the criteria necessary to move on to device partner QA.

At the end of the device partner QA process, if no launch-gating issues remain, then the widget will enter the widget release process. Widget developers will receive a minimum of 3 US business days notice of the pending release of a widget.

Q: Who communicates with each device partner?

Yahoo! manages all widget submissions and communication with each device partner on behalf of the widget developer. Yahoo! reviews the bugs provided by the device partner prior to sending them to you. At this time, all communication is via email with Yahoo! and bug lists are managed in spreadsheet attachments. When resubmitting your widget with fixes, you should update your status on each bug using this spreadsheet.

Q: What does Yahoo! QA testing cover?

Yahoo! QA testing covers the following:

  • Installation
  • Interaction/Functionality
  • Media playback (where appropriate)
  • Negative inputs
  • Disconnected network handling

 

The following defects will prevent a widget from passing Yahoo! QA on any platform:

  • Failure to meet all the TV Widget Acceptance Criteria (download the .doc or the .rtf version).
  • Blank or incomplete loading of snippet, sidebar, and/or fullscreen views.
  • Inconsistent video playback, including not returning to the sidebar at the end of video playback.
  • Inappropriate messaging when network connectivity fails.
  • Not returning as expected when network connectivity is re-established.
  • Dead-ends in the widget interaction resulting in returning to the widget dock.
  • Inconsistent back button behavior (for example, bread-crumbing and focus).
  • Poor handling of negative inputs (for example, erroneous ids and passwords).

 

The following defects are considered bugs but will not prevent passing Yahoo! QA if an acceptable committed fix-date is received from the widget developer:

  • Cosmetic issues.
  • Testing considered excessively outside normal user behavior, such as extraordinarily complex, excessive, or rapid input.
  • Defects discovered on pre-production platforms not otherwise present on production platforms.

 

It is important to note that due to platform differences (such as media player implementations and disconnected network event handling) a widget may function correctly on one platform but not on another during QA.

Q: Which TV should you buy?

Yahoo! Connected TV recommends buying the latest 2010 models which support the fastest, most-advanced environments. Follow the Connected TV Developer Forums for device updates and feedback.

Q: How can you speed up the QA process?

Here's a list of tips to speed up the QA process:

  • Test on several TVs, including newer models. For example, test the media player and network connectivity failure on several devices. Be prepared to reproduce bugs on specific devices.
  • Do not include synchronous calls in your TV Widget. See this FAQ on asynchronous support.
  • Encode your video/audio using these Video Encoding Specifications.
  • Create test cases so you can independently test all the requirements in the TV Widgets Acceptance Criteria form (download the .doc or the .rtf version).
  • Remove hidden files from your widget's folders prior to zipping (for example, remove .thumb, .DS_Store, .svn, and all other non-widget files).
  • Submit detailed use cases with the TV Widgets Acceptance Criteria form to indicate your widget's desired behavior (for example, unconventional back button behavior).
  • Provide the appropriate username and passwords for test accounts with your TV Widget submission.
  • Be sure to contact tvwidgets@yahoo-inc.com if your content is IP filtered to retrieve IP addresses for whitelisting.