Enhanced Features

Sender application can be more powerful with the following advanced feature like WOW,BLE,Multitsking,install etc..


Related Info


StartArgs

Authentication should ONLY be passed with secure connection"(coming soon)

  • StartArg can be 'login user info','deeplink','AuthToken' etc..

  • Above Mobile Library Android 2.0.18 and iOS 2.2.2

  • Mobile App(Android)

    • MUST write "id" startArgs map's key.
    • simple string ("id","aaa");
    • json ,("id",data{"id":"XX","pw":"1234","pairing_code":"XX@1234"}
//String Type
Map<String,Object> startArgs1 = new HashMap<String, Object>();
Object payload = "aaa";
startArgs1.put(Message.PROPERTY_MESSAGE_ID,payload);
mApplication = mService.createApplication(mApplicationId, mChannelId,startArgs1);
//JSON Object Type
JSONObject test2 = new JSONObject();
try {
  test2.put("userID","XX");
  test2.put("userPW","1234");
  test2.put("pairCode","XX@1234");
} catch (JSONException e) {
  e.printtackTrace();
}

Map<String,Object> startArgs2 = new HashMap<String, Object>();
Object  payload = test2.toString();
startArgs2.put(Message.PROPERTY_MESSAGE_ID,payload);

mApplication = mService.createApplication(mApplicationId, mChannelId,startArgs2); 

TV Web App

To received "Start Args", MUST write "PAYLOAD" to get Data

msf.local(function(err, service) {
var reqAppControl = tizen.application.getCurrentApplication().getRequestedAppControl();
log("reqAppControl =" + reqAppControl + ", appControl = "+reqAppControl.appControl);
if (reqAppControl && reqAppControl.appControl) {
  var data = reqAppControl.appControl.data;

  for (var i = 0; i < data.length; i++) {
    log("WRT param #" + i + " key : " + data[i].key);
    for (var j = 0; j < data[i].value.length; j++) {
      console.log("WRT param #" + i + " #" + j + " value : " + data[i].value[j]);
    }
    if (data[i].key == "PAYLOAD") {
      log("payload =" + data[i].value[0]);
      var payload = data[i].value[0];
    }
  }
}

Install API

Mobile app can make TV to show of webapp installation page when TV webapp is not exist. install() API is possible to make this scenario.

Also, you have 2 times chance to call install().

1. getinfo()

You call getinfo() then you received onError code '404' that means your TV webapp not exist.

2. connect()

You call connect() then you received onError code '404' that means your TV webapp not exist.

3. code flow

//1. Create Appication
mApplication = mService.createApplication(mApplicationId, mChannelId);

//2. Get AppicationInfo if you need
mApplication.getInfo(new Result<ApplicationInfo>() {

    @Override
    public void onSuccess(ApplicationInfo applicationInfo) {
        Log.d(TAG, "getInfo " + applicationInfo.toString());
    }


    @Override
    public void onError(com.samsung.multiscreen.Error error) {
        if (error.getCode() == 404) {
            //Install the application on the TV. 
            //Note: This will only bring up the installation page on the TV. 
            //The user will still have to acknowledge by selecting "install" using the TV remote.

            application.install(new Result<Boolean>() {
                @Override
                public void onSuccess(Boolean result) {
                    Log.d(LOGTAG, "Application.install onSuccess() " + result.toString());
                }
            });  
        }
    });
});


//3. Launch installed app 
mApplication.connect(new Result<Client>() {
    @Override
    public void onSuccess(Client client) {
        Log.d(TAG, "application.connect onSuccess " + client.toString());
    }

    @Override
    public void onError(com.samsung.multiscreen.Error error) {
        if (error.getCode() == 404) {
            //Install the application on the TV. 
            //Note: This will only bring up the installation page on the TV. 
            //The user will still have to acknowledge by selecting "install" using the TV remote.
            application.install(new Result<Boolean>() {
                @Override
                public void onSuccess(Boolean result) {
                    Log.d(LOGTAG, "Application.install onSuccess() " + result.toString());
                }
            });     
        }
    });
} 

WoW (Wake on Wireless LAN)

This section explains how a Samsung Smart TV can use Wake on Wireless LAN (WoWLAN) to power on a previously discovered TV.

This enables the mobile device to subsequently start and interact with applications on the Samsung Tizen TV.

Latest SmartViewSDK include Enhaned WOW feature

SDK 2.4.0 makes your app enable WOW function automatically without NO source code change.

  1. If your app have been connected once,

    • SDK manage the TV device list for WOW feature
    • SDK handles below Basic UI scenario
  2. Basic UI scenario

    • Turn the TV off (put to standby).
    • Appears marked as “TV_NAME(standby)” within 7 seconds.
    • Select the TV.
    • The TV power on
    • The TV WebApp(or DMP) should start loading on the TV.
    • The video should start playing on the TV.

New WOW APIs

SmartView SDK now supports WOW (enabled as default) for 2016 and above Samsung SmartTVs. It enables user to connect to a TV currently in standby mode. Upon making a connect() call to a standby TV, it tries to turn ON the TV and to establish a connection with the same.

  • Standby TVs are those TVs to which user has connected successfully to at-least once in the past & are now in standby mode.
  • Search.start() : This API will start discovery & list standby TVs by default.
  • Search.start(false) : Stop discovery from listing standby TVs.
  • Service.remove() : Remove a standby device from the device list until it is not again connected.
  • Search.clearStandbyDeviceList() : Remove all standby devices form t the device list.

Errors

Following error codes have been added, to identify problems w.r.t. WOW feature.

  • ERROR_CONNECT_FAILED : Connect() request fails due to some internal error.
  • ERROR_HOST_UNREACHABLE : Host is unreachable. This error occurs when WOW API is not able to wake the TV up or TV’s IP was changed & TV is no more broadcasting discovery packets.
  • ERROR_ALREADY_CONNECTED : When connect() is called on already connected TV.
  • ERROR_WEBSOCKET_DISCONENCTED : Web-socket is disconnected. Usually occurs when user tries to send commands to TV without calling connect() first, or after TV has already disconnected.

Implement manually lower version of SDK 2.4.0

1. Simple implementation guide

The Mobile device must get TV's MAC info when connected successfully.

The Mobile device must store certain values(MAC), so that the Mobile device can use Wake-up to power on the TV next time.

2. Pre-condition

(MUST) Mobile App should have connected successfully at least once so that TV can register mobile MAC.

When TV is turned off, the TV status should be displayed as “{TV Name} (standby)” on the mobile device.

3. Basic UI scenario

  1. Turn the TV off (put to standby).
  2. Within 60 seconds TV disappears from the list and within 30 seconds reappears marked as "(standby)".
  3. Select the TV.
  4. The TV should start loading.
  5. The TV WebApp(or DMP) should start loading on the TV.
  6. The video should start playing on the TV.

4. API Usage

1) How to get MAC address:

Service service.getDeviceInfo(new Result<Device>() {
    @Override  
    public void onSuccess(Device device) {
           if (device != null)                                          
               String wifiMac = device.getWifiMac(); 

           SharedPreferences.Editor editor = getSharedPreferences("WoWMacs", 0).edit();

           editor.putString(name, wifiMac);

           editor.commit(); 

    }

    @Override  
    public void onError(com.samsung.multiscreen.Error error) {  
    } 
});

2) Wake up TV :

String mac = getSharedPreferences("WoWMacs", 0).getString(service.getName(), 0);

Service.WakeOnWirelessLan(mac);

3) Wake up TV and connect :

This API turns on the selected TV and Smart View SDK confirm to be ready.

Then, you can turn on the TV and launch your application.

//For connection is used default timeout: Service.DEFAULT_WOW_TIMEOUT_VALUE = 60000

String mac = getSharedPreferences("WoWMacs", 0).getString(service.getName(), 0);

String uri = getSharedPreferences("WoWIps", 0).getString(mac, 0);

Service.WakeOnWirelessAndConnect(mac, uri, new Result<Service>() {
    @Override
    public void onSuccess(Service service) {
        if (service != null) {
            Application application = service.createApplication("YOUR_APP_ID","YOUR_CHANNEL_ID");

            application.connect(new Result<Client>() {

                @Override
                public void onSuccess(Client client) {
                    if (client != null) {
                        Log.d("log", "onSuccess: " + client.toString());
                    }
                }

                @Override
                public void onError(com.samsung.multiscreen.Error error) {
                    Log.d("log", "onError: " + error.getMessage());
                }
            });
        }
    }

    @Override
    public void onError(com.samsung.multiscreen.Error error) {
        Log.d("log", "onError: " + error.getMessage());
    }

});


//Connect using custom timeout:

int timeout = 120000;

Service.WakeOnWirelessAndConnect(mac, uri, timeout, new Result<Service>()){

....

}

4) Make WoW TV list:

This is a sample code showing how to manage the TV list.

// create Wow TV list
ListView wowList = (ListView)findViewById(R.id.wowListView); 
standByListAdapter = new StandByModeTVListAdapter(this, R.layout.listview_item);
wowList.setAdapter(standByListAdapter);

// create available TV list 
ListView tvList = (ListView)findViewById(R.id.tvListView); 
tvListAdapter = new TVListAdapter(this, R.layout.listview_item);
tvList.setAdapter(tvListAdapter);

// stored names and mac addresses of connected before TVs 
SharedPreferences WoWMacs  = getSharedPreferences("WoWMacs", 0);
 
// stored names and uri of connected before TVs  
SharedPreferences WoWIps  = getSharedPreferences("WoWIps", 0);
 
// stored mac addresses and network's ids of connected before TVs to show available TVs only
SharedPreferences WoWIds  = getSharedPreferences("WoWIds", 0); 

if (WoWMacs!=null && WoWIps!=null && WoWIds!=null) {   
    // get all stored TV's macs  
    Map<String, String> macsList = (Map<String, String>) WoWMacs.getAll(); 

    // get all stored TV's names
    Set<String> names = macsList.keySet(); 

    for (String name : names) {
       // get TV mac according to name
       String mac = WoWMacs.getString(name, null);  

       // get TV uri according to mac
       String uri = WoWIps.getString(mac, null); 

       // get network id according to mac
       int wifiId = WoWIds.getInt(mac, 0); 

       // check whether TV is on or off
       // check whether TV is in network or not

       if (mac != null && null != uri  && !tvListAdapter.contains(uri) 
          && wifiId == wifiManager.getConnectionInfo().getNetworkId() ) {
                // check regarding duplicates
                if (!ListWoW.contains(name + " (standby) : " + mac)) {  
                     ListWoW.add(name + " (standby) : " + mac);             
                     standByListAdapter.add(name + " (standby) : " + mac);
                     standByListAdapter.notifyDataSetChanged();
           }
       }
    }
 } 

BLE Discovery (Bluetooth Low Energy)

You can discover a compatible Samsung smart TV using Bluetooth Low Energy network by the Search class or BLESearchProvider class.

Start BLE Discovery

To start BLE discovery we need to Search object to discover TV's using startUsingBle() API of Smart View SDK.

Search search = com.samsung.multiscreen.Service.search(this);
 search.startUsingBle();

Register Listener for getting TV Device list

To get the discovered devices we need to register search object with setOnBleFoundListener listener. If BLE discovers any device, it notify through onFound() method of OnBleFoundListener.

search.setOnBleFoundListener(new Search.OnBleFoundListener() {
    @Override
    public void onFoundOnlyBLE(String tvname) {
        bleTVList.add(tvname);
        Log.i(TAG,"TV found isActivityRunning(getApplicationContext()"+isActivityRunning(getApplicationContext())));
        showNotification(tvname);
        onTimerTick(tvname);
    }
});

Stop BLE Discovery

To stop BLE discovery, call stopUsingBLE() API of Smart View SDK.

search.stopUsingBle(); 

Support Multitasking

The default value for multitasking support is true. Your application should support multitasking

Your app will change the background state in the following circumstances

  • Launching other application over currently running application.
  • Calling tizen.application.getCurrentApplication().hide() method.
  • Turning off TV during application running in Samsung Instant On mode.
  • Clicking "Smart Hub" button and going to the Apps page.

Your App can select one of two operation.

  • Keep connection
  • Close connection

Keep connection

Webapp and mobile app keep the connection.

and mobile app can change the state TV app(background to foreground)

Example Javascript API Usage(Web App)

// Support MultiTasking 
// Case 2) Keep Connection. 
// 1. Keep connect status. 
// 2. Notify to Mobile  
document.addEventListener("visibilitychange", function() { 

log("App become be hide "+document.hidden);  
   if(document.hidden){ 
     console.log("App become be hide"); 
     channel.publish('visibilitychange', 'hide'); 
    }  
} );  

Example Android API Usage

//1. get "visibilitychange" message 
//2. manage TV Web App status. 
mApplication.addOnMessageListener("visibilitychange", new Application.OnMessageListener() { 

 @Override 
 public void onMessage(Message message) { 
  Log.d(TAG, "addOnMessageListener visibilitychange :  " + message.toString()+"date = "+message.getData()); 
  if("hide".equals(message.getData())){ 
   TVwebAppHide = true; 
    Log.d(TAG, "addOnMessageListener TVwebAppHide :  " + TVwebAppHide); 
   } 
  } 
 }); 

 //And then check TvAppHide 
 //WebApp  
 private void publish(final String event, final Object data){ 
  if(mApplication != null) { 
   if (TVwebAppHide) { 
    //try to start(tv web app move background to foreground) 
     mApplication.start(new Result<Boolean>() { 
       @Override 
       public void onSuccess(Boolean aBoolean) { 
        TVwebAppHide = false; 
        mApplication.publish(event, data); 
        Log.d(TAG, "application.connect onSuccess " + aBoolean.toString()); 
     } 

     @Override 
     public void onError(Error error) { 
      Log.d(TAG, "application.connect onError " + error.toString()); 
     } 
    }); 
   }else{ 
    mApplication.publish(event,data); 
   } 
  } 
 } 

Close connection(Disconnect)

WebApp and Mobile app just close the connection when TV web app is in the background.

Example Javascript API Usage(Web App)

// 1. Disconnect when webapp become background status(hide) 
// 2. and mobile app(android) fire callback onDisconnect() and handle mobile app status. 

 document.addEventListener("visibilitychange", function() { 
    if(document.hidden){ 
     console.log("App become be hide"); 
        var app = tizen.application.getCurrentApplication();   
        if(app) 
             app.exit();      
     }  
 } );  

TLS (make secure connection)

SmartviewSDK can make secure connection between sender and receiver through wss & http.

refer to latest CastVideo sample app.

1) setSecurityMode API

public void setSecurityMode(boolean securityMode, Result <boolean> result)

  • Set security mode status to for web socket connection or rest API
  • Parameters:
    • securityMode - security mode status to set
    • result - result to return whether security mode was set or not

2) Sample Code

mRemoteApp.setSecurityMode(true, new Result<Boolean>() {
	@Override
	public void onSuccess(Boolean aBoolean) {
		if (attributes != null) {
			mRemoteApp.connect(attributes, mConnectResult);
		} else {
			mRemoteApp.connect(mConnectResult);
		}
		mTimeoutTimer = new Timer();
		mTimeoutTimer.schedule(new TimeoutTask(), timeout);
	}

	@Override
	public void onError(Error error) {
		FCError libError = new FCError(203,
				"Connecting error. Can't create TLS channel.");
		for (OnFCErrorListener listener : mFCErrorListeners) {
			listener.OnError(libError);
		}
	}
});