Sending Bundle over Message Port
PUBLISHED
Introduction
Tizen Platform facilitates application developers to develop Native application with C/C++ and Web application with HTML, CSS and JS. Both Native and Web development platform have their own strength as well as limitations. Native app’s ability to access deeper layer and Powerful User Interface Design feature of Web app can be a winner combination, which is called Hybrid application. To develop a Hybrid application, communication between the applications is a major concern. In this document, this concern is addressed by discussing a concept “Sending bundle over message port”.
Packaging a Bundle
A bundle is a string-based dictionary abstract data type (ADT). A dictionary is a list of key-value pairs, where keys are used to locate elements in the list. The key is always a string.
- To use the functions and data types of Bundle, include the <bundle.h> header file in your application.
- To perform any operations on a bundle, create the bundle instance.
- To add content to a bundle, use bundle_add_str() or bundle_add_str_array() function depending on the data type.
- When no longer needed, release the bundle by calling the bundle_free() function
Example C code:
#include <bundle.h> void packageBundle(){ bundle *reply =NULL; reply = bundle_create(); // Create bundle instance bundle_add_str(reply,"testChar","T"); // Add string key Value pair to bundle char *array[] = {"Z2","Z4","GearS2","GearS3"}; bundle_add_str_array(reply,"Models",array, 4); //Add string array of key Value pair to bundle, length of 4 dlog_print(DLOG_DEBUG, TAG, "Bundled Successfully"); //bundle_free(reply); //Once no longer required }
Concept of Local & Remote Port
For Inter-Application Data exchange, Message Port offers communication channel between different Tizen applications. In Message port Communication protocol, ‘The Port’ is named as ‘Local Port’ with respect to receiver application as the app would receive message at its own end (local end). The same port is named as ‘Remote Port’ with respect to sender application as the app would transmit data to remote receiver apps end (remote end). Using Message Port, Web-Web, Native-Native, Web-Native, Native-Web application; all sorts of communication is possible. In this document, Native to Web application communication is discussed.
Register Local Port Using Web API
The LocalMessagePort interface is used to register message port and prepare to receive messages from other applications. To create a local port which receives messages, the requestLocalMessagePort() method is used. The parameter to the requestLocalMessagePort() method is the localMessagePortName.
To receive messages from other applications, a callback to the local message port must be registered. Use the addMessagePortListener() method of the LocalMessagePort interface to add a callback method that is invoked when the message arrives. The parameter to the addMessagePortListener() method is the MessagePortCallback listener function name.
Example JavaScript Code:
function registerLocalPort(){ var localPort = tizen.messageport.requestLocalMessagePort("CrossPort"); // Request LocalMessagePort Instance named "CrossPort" localPort.addMessagePortListener(onReceive); // "onReceive" Callback Function to be invoked when meesage is received by the Port console.log("Local port Listener Registered"); } function onReceive(data, remoteMsgPort) { console.log("Local port Listener Called"); }
Here, Instance of LocalMessagePort is returned on var localPort. The port is named “CrossPort” to be recognized by other applications.
Request Remote Port & Send Message Using C API
message_port_check_remote_port() function Checks whether the message port of a remote application is registered or not and message_port_send_message() function is used to send message to remote port of an application.
Example C Code:
char *remote_app_id="G85Cygkpsb.BundleReceiverWebUI"; char *remote_port="CrossPort"; bool result=false; int ret; ret = message_port_check_remote_port(remote_app_id,remote_port,result); if (ret != MESSAGE_PORT_ERROR_NONE){ dlog_print(DLOG_ERROR, TAG, "message_port_check_remote_port error: %d", ret); } dlog_print(DLOG_DEBUG, TAG ,"Remote app id: %s Remote port: %s Result: %d", remote_app_id, remote_port, result); dlog_print(DLOG_DEBUG, TAG ,"Remote port exists: %s", result ? "true" : "false"); if (result){ ret = message_port_send_message(remote_app_id, remote_port, reply); //send 'reply' bundle to the remote port if (ret != MESSAGE_PORT_ERROR_NONE) dlog_print(DLOG_ERROR, TAG, "message_port_check_remote_port error: %d", ret); else dlog_print(DLOG_INFO, TAG, "Send message done"); }
Here, ‘remote app id’ is a string variable referring to the destination application’s id. This Id can be found in config.xml of web application or in tizen-manifest.xml of native application. ‘remote port’ string variable is the name of the remote port, which is actually name of the local port registered on the remote application. In this case, the remote port is “CrossPort”. For both the message_port_check_remote_port() and message_port_send_message() function first two parameters are same.
The result whether remote port exists or not is returned on the third parameter of message_port_check_remote_port() which has to be a ‘bool’ variable. And third parameter of message_port_send_message() is the Bundle Instance to be send.
If message_port_check_remote_port() and message_port_send_message() functions run without any runtime error it returns MESSAGE_PORT_ERROR_NONE, otherwise error is returned. You can check out the error types in message port Native API references.
Receive & Read the Message in Web Application
As MessagePortListener function is already added, when the message will arrive in local port the listener function would be automatically invoked. The message would arrive on the first parameter of listener function. The structure of the message is a set of key value pair like:
[ { key:”key1”, value: {”value1”,”value2”} }, { key:”key2”, value: ”value1” } ]
To read the message, iterator variables is introduced to iterate through the key value pairs. Example Iteration:
function onReceive(data) { console.log("Local port Listener Called"); var msg=""; for (var i = 0; i < data.length; i++){ // Iterating key Value pairs like: [key1:{val1,val2},key2:{val2}] var keyX = data[i].key; console.log("key:" + keyX); msg+=keyX+': '; for (var j = 0; j < data[i].value.length; j++){ var valueX = data[i].value[j]; console.log("value:" + valueX); if (j === data[i].value.length-1) msg+=valueX+ '.\n'; else msg+=valueX+ ', '; } } alert(msg); // show the msg in Wearable Display }
Sample Application
A sample Web application and Native Service application is developed for understanding of use of Tizen Message Port API and Bundle API. The process flow is kept simple for test purpose and both the applications are kept distinct. To test the sample app, follow the process below:
I. Download both Web and Native application zip files.
II. Import both the applications in Tizen-Studio.
III. Clean & Build the Web application and deploy to Tizen wearable device/emulator.
IV. Touch on display screen to register local port.
V. Once the port on web application is listening, Clean & Build the Native service app & deploy to same device/emulator. As the message sending is handled on service_app_create() function, it will send the message to web application once deployed.
VI. Check the ‘Console’ tab for web app logs and ‘Log’ Tab for Native app logs. To search the native logs write “bundle” on search box while ‘Tag’ is selected in dropdown.
For sample implementation, the message sending is triggered in ‘onCreate’ lifecycle function of the native service app. Again both the applications are kept distinct; Multi packaging can be used to install them as single application. In that case, app control should be used to launch the service app from web app.
Figure A: Web app Launched Figure B: Web Local Message Port Listening
Figure C: Native Service app log
Figure D: Bundle received at web application from native application
In Fig A: the Web application is deployed to wearable emulator. Once the display is touched the local port is requested and starts listening (in Fig B). Then The Native application is deployed to the emulator and the message is sent, as we can see in the log (In Fig C). Fig D is the screenshot of Web application displaying the message bundle received from Native application.