This topic describes how you can use Smart Hub Preview to show deep links to application content in the Smart Hub launcher.
The Smart Hub Preview feature allows you to show content when the user hovers over your application icon in the launcher. The user can click the preview tile to open the content directly within the application. You can use the preview to promote new or personalized content to the user.
All Samsung TVs since 2016 support Smart Hub Preview. It is also supported on the TV emulator since Tizen TV Extension 2.3.1.
Figure 1. Preview panel
There are 2 kinds of previews. You can select 1 of them for your application:
You can implement the preview to suit the content of the application. For example:
The following figure illustrates the parts of the preview feature.
Figure 2. Preview parts
The Samsung Apps TV policy defines requirements for the content shown in Smart Hub Preview. You can use the preview to:
In addition, the personal preview can be used to:
Important
The preview must not be used to display third-party advertising or to advertise application features or capabilities.
Content shown in Smart Hub Preview belongs to the application and is the responsibility of the content provider.
The following table defines the section element requirements.
Category | Requirement | Notes |
---|---|---|
Number of sections | 1 or more | - |
Number of tiles within a section | ||
Section title | Optional | Long title text automatically scrolls across the title area. The title must be in the system language. |
Figure 3. Section element with a section title
The following table defines the tile element requirements.
Category | Requirement | |
---|---|---|
Number of tiles | Maximum 40 tiles | |
Deep-link URL | URL must be unique | |
Thumbnail image | Mandatory | |
Format | PNG or JPG | |
File size | Maximum 360 KB | |
Height | 250 px Taller images are reduced to 250 px. |
|
Aspect ratio | Allowed ratios (Resolutions):
| |
Content | Image must be appropriate for viewers of all ages. |
Figure 4. Thumbnail image aspect ratios
Optional elements can be shown when the user hovers on the tile:
The following figure shows a tile with a title, a subtitle, and the "play" icon.
Figure 5. Tile with optional elements
After the user enters the application through a deep link, the “Return/Exit” key click must be implemented to perform the following actions:
Figure 6. Deep-link return key policy
The public preview generation process is shown in the following figure.
Figure 7. Public preview generation process
To enable your application to use the public preview functionality:
<tizen:metadata key='http://samsung.com/tv/metadata/use.preview' value='endpoint_URL=http://yourServer/JSONfile.json'></tizen:metadata>
<tizen:app-control>
<tizen:src name='index.html' reload='disable'></tizen:src>
<tizen:operation name='http://samsung.com/appcontrol/operation/eden_resume'></tizen:operation>
</tizen:app-control>
required_version
attribute to "2.3" and the development API version meta data to "2.4":<tizen:application ... required_version='2.3'></tizen:application>
<tizen:metadata key='http://samsung.com/tv/metadata/devel.api.version' value='2.4'></tizen:metadata>
The preview content is defined in JSON format. The application can only use 1 preview content JSON file at a time.
The following table lists the structure and parameters for the preview content JSON data.
Parameter | Type | Mandatory | Description | ||
---|---|---|---|---|---|
"expires" | UTC timestamp | False | For public preview only If specified, the time at which the preview content is updated. The time is at most 1 week into the future. By default, the preview content is updated every 10 minutes, whenever the TV is switched on, or the JSON file changes. |
||
"expires_only" | Boolean | For public preview only If this value is "true", the preview content is updated only at the time specified by the "expires" parameter. The default value is "false". |
|||
"sections" | Array | True | Preview sections | ||
"title" | String | False | Section title | ||
"position" | Integer | Section position If specified, sections are shown in ascending position order. |
|||
"tiles" | Array | True | Tiles within the section | ||
"title" | String | False | Tile title | ||
"subtitle" | Tile subtitle | ||||
"image_url" | True | Thumbnail image URL | |||
"image_ratio" | Thumbnail image aspect ratio:
|
||||
"action_data" | Data to send to the application when the tile is clicked | ||||
"is_playable" | If "true", a "Play" icon is shown over the thumbnail image | ||||
"display_from" | UTC timestamp | False | Time to begin showing the tile | ||
"display_until" | Time to stop showing the tile | ||||
"position" | Integer | Section position If specified, sections are shown in ascending position order. |
For an example of a preview content JSON file, see sampleJSON.
When the preview system requests JSON data from your server, TV information is sent in the HTTP header. You can serve different preview content depending on TV information, such as the country, language, or application version.
The following table lists the HTTP header fields that contain TV information.
Field | Description |
---|---|
ACCEPT-LANGUAGE | TV language setting, such as 'en-US' |
X-SAMSUNG-COUNTRY | TV country code in ISO 3166-1 alpha2 format, such as 'US' |
X-SAMSUNG-APP-VERSION | Application version |
When a tile is clicked, its associated "action_data" value is converted to an ApplicationControlData
object with the "PAYLOAD" key:
{
"key": "PAYLOAD",
"value": ["{\"values\": \"{\\\"videoIdx\\\": 1}\"}"]
}
For more information on ApplicationControlData
objects, see the Application API.
To implement deep-linking:
To receive "action_data" information when the application is already running, add an event listener for the appcontrol
event to the onload
property:
window.addEventListener('appcontrol', deepLink);
In the onload
property, receive and parse the "PAYLOAD" key value, using the getCurrentApplication().getRequestedAppControl()
method:
function deepLink() {
var requestedAppControl = tizen.application.getCurrentApplication().getRequestedAppControl();
var appControlData;
var actionData;
var videoIdx;
var pictureIdx;
if (requestedAppControl) {
appControlData = requestedAppControl.appControl.data;
for (var i = 0; i < appControlData.length; i++) {
if (appControlData[i].key == 'PAYLOAD') {
actionData = JSON.parse(appControlData[i].value[0]).values;
if (JSON.parse(actionData).videoIdx) {
videoIdx = JSON.parse(actionData).videoIdx;
console.log(videoIdx);
}
else if (JSON.parse(actionData).pictureIdx) {
pictureIdx = JSON.parse(actionData).pictureIdx;
console.log(pictureIdx);
}
}
}
} else {
console.log("no req app control");
}
}
To implement a personal preview, you need to develop a foreground application and a background service application. The foreground application performs the main application tasks, such as showing content, while the background application serves information to show in the preview. Personalized preview content is implemented by sharing data between the foreground and background applications. For example, the foreground application can share user-entered information with the background service, which queries for personalized recommendations.
The personal preview generation process is shown in the following figure.
Figure 8. Personal preview generation process
To enable your application to use the private preview functionality, you must modify the foreground application's "config.xml" file:
Define the JSON source as a background application:
<tizen:metadata key='http://samsung.com/tv/metadata/use.preview' value='bg_service'></tizen:metadata>
To add the service application to the foreground application, add the following code inside the widget
element.
The id
attribute of the tizen:service
element is in the format [application ID].[service name]
, and the src
attribute of the tizen:content
element is the path to the service application code.
<tizen:service id='g3rAasdgsM.service'>
<tizen:content src='service/service.js'></tizen:content>
<tizen:name>service</tizen:name>
<tizen:icon src='service/service_icon.png'></tizen:icon>
<tizen:description>Service Application</tizen:description>
<tizen:metadata key='meta-key' value='meta-value'></tizen:metadata>
<tizen:category name='http://tizen.org/category/service'></tizen:category>
</tizen:service>
Disable reloading the application main page when it receives an application control request.
This allows your application, if it is already running, to receive the "action_data" information without reloading.
<tizen:app-control>
<tizen:src name='index.html' reload='disable'></tizen:src>
<tizen:operation name='http://samsung.com/appcontrol/operation/eden_resume'></tizen:operation>
</tizen:app-control>
If you want the application to support 2015 TV models, set the required_version
attribute to "2.3" and the development API version meta data to "2.4":
<tizen:application ... required_version='2.3'></tizen:application>
<tizen:metadata key='http://samsung.com/tv/metadata/devel.api.version' value='2.4'></tizen:metadata>
The structure and parameters of the preview content JSON file are the same as for public preview, except that the "expires" and "expires_only" properties are not supported.
You can provide the JSON data as a variable, a local file, or a file at a remote URL. If you want to retrieve JSON data using HTTP requests, you must implement them using NodeJS.
The following example provides the JSON data as a variable:
// Sample user data for personalization
var user = {
id : "Rozanne",
age : 27
}
var previewData = {
"sections" : [{
"title" : user.id + "'s recommended",
"tiles" : [{
"title" : "Funny",
"subtitle" : user.age + "th Birthday Party",
"image_ratio" : "16by9",
"image_url" : "https://developer.samsung.com/onlinedocs/tv/Preview/1.jpg",
"action_data" : "{\"videoIdx\": 1}",
"is_playable" : true
}]
}, {
"title" : user.age + "'s choice",
"tiles" : [{
"title" : user.id + "'s Living",
"image_ratio" : "1by1",
"image_url" : "https://developer.samsung.com/onlinedocs/tv/Preview/2.jpg",
"action_data" : "{\"videoIdx\": 2}",
"is_playable" : true
}, {
"title" : "Cooking",
"subtitle" : "Season 1",
"image_ratio" : "16by9",
"image_url" : "https://developer.samsung.com/onlinedocs/tv/Preview/3.jpg",
"action_data" : "{\"pictureIdx\": 3}",
"is_playable" : false
}, {
"title" : user.id + "'s " + user.age + "th Party",
"image_ratio" : "16by9",
"image_url" : "https://developer.samsung.com/onlinedocs/tv/Preview/4.jpg",
"action_data" : "{\"pictureIdx\": 4}",
"is_playable" : false
}, {
"title" : user.id + "'s Animal",
"image_ratio" : "16by9",
"image_url" : "https://developer.samsung.com/onlinedocs/tv/Preview/5.jpg",
"action_data" : "{\"pictureIdx\": 5}",
"is_playable" : false
}]
}]
};
To implement the background service application:
window.onload
method:var serviceId = 'g3rAasdgsM.service'; //Application ID for background service application
tizen.application.launchAppControl(
new tizen.ApplicationControl(
'http://tizen.org/appcontrol/operation/pick', null, 'imag/jpeg',null,
[new tizen.ApplicationControlData('caller', ['ForegroundApp'])]
),
serviceId,
function() {
console.log('Launch success: ' + serviceId);
},
function(error) {
console.log(JSON.stringify(error));
}
);
Define the onStart()
callback.
When the background service application is launched, this callback is the start point.
module.exports.onStart = function() {
console.log("Start Callback");
}
In the onRequest()
callback, implement the background application logic, such as HTTP networking, generating preview data, and communication with the foreground application:
setPreviewData()
method of the Preview API to set the JSON data for the preview.module.exports.onRequest = function() {
console.log("Request Callback");
var reqAppControl = tizen.application.getCurrentApplication().getRequestedAppControl();
if (reqAppControl && reqAppControl.appControl.operation == "http://tizen.org/appcontrol/operation/pick") {
var data = reqAppControl.appControl.data;
if (data[0].value[0] == 'ForegroundApp') {
webapis.preview.setPreviewData(
JSON.stringify(previewData),
function() {
// Terminate service after setting preview data
tizen.application.getCurrentApplication().exit();
},
function(e) {
console.log('setPreviewData failed : ' + e.message);
}
);
}
}
}
Note
In the success callback for the
setPreviewData()
method, you must terminate the background service application using thegetCurrentApplication().exit()
method.The Samsung Apps TV policy defines that, if the background service application is not terminated in this way, it is automatically terminated after 5 minutes.
Define the onExit()
callback.
This callback is invoked when the background service application is terminated.
module.exports.onExit = function() {
console.log("Exit Callback");
}
Private preview deep links are implemented in the same way as public preview deep links.