The Widget Service sample native application demonstrates how to use the Widget Service API functions calls on a widget.

The Widget Service sample web application is provided as an accompanying application. It is built and pushed to the device with the application. To run this sample application, both sample applications must be packaged together as a multi package.

The following figure shows widget instances.

Figure: Widget Service screens

The widget displays the data sent from the Widget Service sample native application with the sendContent() function. Unless something goes wrong, the data is sent to and shown by all existing widget instances. If no data has been received by the instance yet, the "Widget Service" text is shown by default. If an error occurs, the "Something went wrong" text is displayed.

## Source Files

You can create and view the sample application project, including the source files, in the IDE.

Table: Source files
File name | Description
--- | ---
src/main.c | This file contains the code of the sample widget, used by the application.
inc/main.h | This file contains headers' inclusions.
tizen-manifest.xml | This file is used to describe the application information such as features, name, and API version.

## Implementation

To implement the application:

1. Register the callbacks and event handlers.

   The widget code is divided into several functions organized in a manner typical for a Tizen widget.

   The following functions are callbacks, defining the behaviors of different states of the widget and transitions between states.

   - widget_instance_create()
   - widget_instance_destroy()
   - widget_instance_pause()
   - widget_instance_resume()
   - widget_instance_update()
   - widget_instance_resize()

   The following functions are event handlers. They define reaction of the widget to the region and language changes.

   - widget_app_lang_changed()
   - widget_app_region_changed()

   The widget_app_create() function registers all callbacks and event handlers listed above.

       static widget_class_h
       widget_app_create(void *user_data)
       {
           /*
              Hook to take necessary actions before main event loop starts
              Initialize UI resources
              Make a class for widget instance
           */
           app_event_handler_h handlers[5] = {NULL,};

           widget_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED],
                                        APP_EVENT_LANGUAGE_CHANGED, widget_app_lang_changed, user_data);
           widget_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED],
                                        APP_EVENT_REGION_FORMAT_CHANGED, widget_app_region_changed, user_data);

           widget_instance_lifecycle_callback_s obj_callback = {0,};
           obj_callback.create = widget_instance_create;
           obj_callback.destroy = widget_instance_destroy;
           obj_callback.pause = widget_instance_pause;
           obj_callback.resume = widget_instance_resume;
           obj_callback.resize = widget_instance_resize;
           obj_callback.update = widget_instance_update;

           return widget_app_class_create(obj_callback, user_data);
       }

2. Apart from the widget_instance_update() function, all callbacks and event handlers are unchanged functions from Tizen Studio template widget project for a wearable device. For more information, see Creating Your First Tizen Wearable Native Widget Application.

   The widget_app_terminate() function is an empty function that defines the actions taken when the widget terminates.

       static void
       widget_app_terminate(void *user_data)
       {
           /* Release all resources */
       }

3. The main() function sets up the widget and starts running it by calling the widget_app_main() function.

       int
       main(int argc, char *argv[])
       {
           widget_app_lifecycle_callback_s ops = {0,};
           int ret;

           ops.create = widget_app_create;
           ops.terminate = widget_app_terminate;

           ret = widget_app_main(argc, argv, &ops, NULL);
           if (ret != WIDGET_ERROR_NONE)
               dlog_print(DLOG_ERROR, LOG_TAG, "widget_app_main() is failed. err = %d", ret);

           return ret;
       }

4. The widget_instance_update() function is called to update the text displayed by the widget, when an event of updating the content is received, or when the Widget Service application calls the sendContent() function.

   The string to be printed is retrieved from the bundle with the bundle_get_str() function. Errors are handled by assigning a NULL value to the string.

   The widget instance data is loaded with the widget_app_context_get_tag() function and then used to change the value of the label in the widget to the text passed by the Widget Service application with the elm_object_text_set() function.

       static int
       widget_instance_update(widget_context_h context, bundle *content,
                              int force, void *user_data)
       {
           const char* data_str = NULL;
           const char* null_data = "Something went wrong";

           /* Get data for the 'string' key */
           int ret = bundle_get_str(content, "string", (char**)&data_str);

           if (ret != BUNDLE_ERROR_NONE) {
               /* An error has occurred, set the data_str's value */
               data_str = null_data;
               if (ret == BUNDLE_ERROR_INVALID_PARAMETER)
                   dlog_print(DLOG_INFO, LOG_TAG, "BUNDLE_ERROR_INVALID_PARAMETER");
               else
                   dlog_print(DLOG_INFO, LOG_TAG, "BUNDLE_ERROR_KEY_NOT_AVAILABLE");
           }

           /* Get the widget instance */
           widget_instance_data_s *wid = NULL;
           ret = widget_app_context_get_tag(context, (void**)&wid);

           if (ret != 0) {
               dlog_print(DLOG_ERROR, LOG_TAG, "Failed to get widget instance data from context: %d", ret);

               return WIDGET_ERROR_FAULT;
           }

           const char *format = "<align=center>%s</align>";
           int len = snprintf(NULL, 0, format, data_str) + 1;
           char *str = (char*)malloc(len);
           snprintf(str, len, format, data_str);
           elm_object_text_set(wid->label, str);
           /* Free the allocated memory */
           free(str);

           return WIDGET_ERROR_NONE;
       }