top

Implementing Personal Preview

This topic describes how to implement a personal preview for the Smart Hub Preview feature. A personal preview shows preview content personalized for the user.

Personal preview content is defined by a JSON file managed by a background service application running on the TV.

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 1. Personal preview generation process

Figure 1. Personal preview generation process

  1. Launching the foreground application also launches the background service application.
  2. The JSON data is set by the background service application.
  3. The preview is generated and shown based on the JSON data.
  4. The user clicks a preview tile.
  5. The tile’s corresponding JSON “action_data” value is sent to the application.
  6. The foreground application parses the “action_data” value and shows the detail page.

Prerequisites

To enable your application to use the personal preview functionality, you must modify the foreground application's "config.xml" file:

  1. Define the JSON source as a background application:

    <tizen:metadata key='http://samsung.com/tv/metadata/use.preview' value='bg_service'></tizen:metadata>
    
  2. 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> 
    
  3. 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> 
    
  4. 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> 
    

Configuring Personal Preview Data

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 
    }] 
  }]
}; 

Implementing the Background Service Application

To implement the background service application:

  1. In the foreground application, launch the background service using the Application API in the 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, 'image/jpeg', null, 
        [new tizen.ApplicationControlData('caller', ['ForegroundApp'])] 
      ), 
      serviceId, 
      function() { 
        console.log('Launch success: ' + serviceId);
      }, 
      function(error) { 
        console.log(JSON.stringify(error)); 
      } 
    ); 
    
  2. In the "service/[service name].js" file, develop the background service application using NodeJS:

    1. 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"); 
      } 
      
    2. In the onRequest() callback, implement the background application logic, such as HTTP networking, generating preview data, and communication with the foreground application:

      • Use the setPreviewData() method of the Preview API to set the JSON data for the preview.
      • Use the Messageport API to share data between the foreground application and the background service application.
        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 the getCurrentApplication().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.

    3. Define the onExit() callback.
      This callback is invoked when the background service application is terminated.

      module.exports.onExit = function() { 
        console.log("Exit Callback"); 
      } 
      

Personal preview deep links are implemented in the same way as public preview deep links.