From: Radek Kintop Date: Mon, 16 Nov 2015 12:53:04 +0000 (+0100) Subject: Documentation for wearable native Ambient weather reference application. X-Git-Tag: tizen_3.0/TD_SYNC/20161201~316^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=245f248d96be0716dfd90e3dd7420032fc0c13ec;p=sdk%2Fonline-doc.git Documentation for wearable native Ambient weather reference application. Change-Id: Ie7d766ef41b59b3e6c33427d76838dab337696b0 Signed-off-by: Radek Kintop --- diff --git a/org.tizen.sampledescriptions/html/images/ambientweather_wn0.png b/org.tizen.sampledescriptions/html/images/ambientweather_wn0.png new file mode 100644 index 0000000..b68a37f Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/ambientweather_wn0.png differ diff --git a/org.tizen.sampledescriptions/html/images/ambientweather_wn1.png b/org.tizen.sampledescriptions/html/images/ambientweather_wn1.png new file mode 100644 index 0000000..5d46583 Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/ambientweather_wn1.png differ diff --git a/org.tizen.sampledescriptions/html/images/ambientweather_wn2.png b/org.tizen.sampledescriptions/html/images/ambientweather_wn2.png new file mode 100644 index 0000000..9e09d72 Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/ambientweather_wn2.png differ diff --git a/org.tizen.sampledescriptions/html/images/ambientweather_wn3.png b/org.tizen.sampledescriptions/html/images/ambientweather_wn3.png new file mode 100644 index 0000000..bed2f4d Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/ambientweather_wn3.png differ diff --git a/org.tizen.sampledescriptions/html/wearable_n/ambientweather_wn.htm b/org.tizen.sampledescriptions/html/wearable_n/ambientweather_wn.htm new file mode 100644 index 0000000..1508423 --- /dev/null +++ b/org.tizen.sampledescriptions/html/wearable_n/ambientweather_wn.htm @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + The Ambient Weather Sample Overview + + + + +
+
+ +
+
+

Wearable native

+
+ +

Ambient Weather Sample Overview

+ +

The Ambient Weather sample application demonstrates how to implement a simple watch with current weather display in ambient mode.

+ +

The following figure illustrates two screens of the (Circle) Ambient Weather sample application: the normal mode digital watch view and the ambient mode view with weather data.

+ +

Figure 1: Ambient Weather views

+

+ Ambient Weather views + Ambient Weather views +

+ +

Figure 2: Ambient Weather widgets structure

+

+ (Circle) Sensors widgets structure +

+ +

It is worth mentioning that this application is multithreaded. The time consuming task of requesting the weather data has been moved to a separate thread to avoid UI lockups. +It is demonstarted in Fig. 3.

+ +

Figure 3: Weather data request diagram

+

+ (Circle) Sensors widgets structure +

+ +

Prerequisites

+

To ensure proper application execution, the following privileges must be set: +

    +
  • http://tizen.org/privilege/network.get
  • +
  • http://tizen.org/privilege/keymanager
  • +
  • http://tizen.org/privilege/internet
  • +
  • http://tizen.org/privilege/alarm.set
  • +
+

+ +

Implementation

+ +

Main module

+

The main() function of the sample application is show below. The application loop +is started when the watch_app_main() +function is invoked. An object of watch_app_lifecycle_callback_s type can be passed to it. +Notice how it differs from ui_app_lifecycle_callback_s type used in the standard application type. +The watch_app_lifecycle_callback_s structure introduces three new pointers to the following callback functions: +

+
    +
  • watch_app_time_tick_cb - called every second when the application is in normal mode, giving the application a chance to refresh the time indicator,
  • +
  • watch_app_ambient_tick_cb - called every minute when the application is in ambient mode, giving the application a chance to refresh the time indicator,
  • +
  • watch_app_ambient_changed_cb - called whenever the application enters normal or ambient mode.
  • +
+ +
+int main(int argc, char *argv[])
+{
+  int ret = 0;
+
+  watch_app_lifecycle_callback_s event_callback = {0,};
+
+  event_callback.create = app_create;
+  event_callback.resume = app_resume;
+  event_callback.pause = app_pause;
+  event_callback.terminate = app_terminate;
+  event_callback.time_tick = app_time_tick;
+  event_callback.ambient_tick = app_time_tick;
+  event_callback.ambient_changed = app_ambient_changed;
+
+  ret = watch_app_main(argc, argv, &event_callback, NULL);
+  // Error handling ...
+
+  return ret;
+}
+
+ +
+static void app_time_tick(watch_time_h watch_time, void *data)
+{
+  // Variables definitions and error handling ...
+  __get_date_from_watch_time(watch_time,
+                &year, &month, &day, &day_of_week,
+                &hours, &minutes, &seconds);
+
+  controller_tick(hours, minutes, seconds, year, month, day, day_of_week);
+}
+
+ +
+static void app_ambient_changed(bool ambient_mode, void *data)
+{
+  controller_set_ambient_mode(ambient_mode);
+}
+
+ +
+static void __get_date_from_watch_time(const watch_time_h watch_time,
+                      int *year, int *month, int *day, int *day_of_week,
+                      int *hours, int *minutes, int *seconds)
+{
+  watch_time_get_hour24(watch_time, hours);
+  watch_time_get_minute(watch_time, minutes);
+  watch_time_get_second(watch_time, seconds);
+  watch_time_get_year(watch_time, year);
+  watch_time_get_month(watch_time, month);
+  watch_time_get_day(watch_time, day);
+  watch_time_get_day_of_week(watch_time, day_of_week);
+}
+
+ +

Main controller module

+

Four important functions of this module are presented below. The controller_start_application() +function is called at the application's startup. It sets up the view and initiates the +weather_poll_thread +module by passing the __weather_poll_data_ready_cb() callback function to it. It also sets the current time on the watch view.

+ +
+bool controller_start_application(int width, int height,
+                    int hour, int min, int sec,
+                    int year, int month, int day, int week_day)
+{
+  if (!view_create_gui(width, height))
+    return false;
+
+  if (!weather_poll_thread_init(__weather_poll_data_ready_cb))
+    return false;
+
+  view_set_time(hour, min, sec, year, month, day, week_day);
+
+  return true;
+}
+
+ +

The controller_set_ambient_mode() function is called from +app_ambient_changed() +callback, defined in the main module. This way, the application can track whether it is in ambient or normal mode. +It is recommended to stop any power consuming operations in the ambient mode. For example, you can change the display state to one that has most of its pixels dark.

+ +
+void controller_set_ambient_mode(bool ambient_mode)
+{
+  cdata.ambient_mode = ambient_mode;
+  view_set_ambient(cdata.ambient_mode);
+  if (cdata.ambient_mode) {
+    wifi_monitor_stop_measure();
+  } else {
+    wifi_monitor_start_measure(__wifi_rssi_level_changed_cb);
+  }
+}
+
+

The controller_tick() +is called with one second interval when the application is in normal mode +and with one minute interval when it is in ambient mode. It updates the time view display.

+ +
+void controller_tick(int hour, int min, int sec,
+            int year, int month, int day, int week_day)
+{
+  view_set_time(hour, min, sec, year, month, day, week_day);
+}
+
+ +

The __weather_poll_data_ready_cb() +callback is called in the main thread context whenever the weather polling thread ends its work successfully. +This function updates the UI in ambient mode by displaying the data received from the server.

+ +
+static void __weather_poll_data_ready_cb(xml_weather_t *weather, const void *icon_data, int icon_data_len)
+{
+  if (weather) {
+    view_set_temperature(weather->temperature.value, weather->temperature.unit);
+    view_set_city(weather->city.name, weather->city.country);
+    view_set_humidity(weather->humidity.value, weather->humidity.unit);
+    view_set_pressure(weather->pressure.value, weather->pressure.unit);
+    view_set_wind(weather->wind.name, weather->wind.speed_value, weather->wind.direction_name);
+    view_set_clouds(weather->clouds.name);
+    view_set_percipitation(weather->precipitation.value);
+    view_set_last_update(asctime(&weather->last_update));
+  }
+
+  if (icon_data && icon_data_len > 0) {
+    view_set_icon(icon_data, icon_data_len);
+  }
+}
+
+ +

Weather poll thread controller module

+ +

This module introduces a single ecore timer and its callback launched periodically to execute server data poll function in a separate thread. +Initialization code is shown below.

+ +
+bool weather_poll_thread_init(weather_poll_data_ready_cb cb)
+{
+  // Variables definitions and error handling ...
+
+  wpt.tim = ecore_timer_add(1.0, __weather_poll_timer_cb, NULL);
+
+  // Error handling ...
+
+    ecore_timer_freeze(wpt.tim);
+
+  return true;
+}
+
+ +
+static Eina_Bool __weather_poll_timer_cb(void *data)
+{
+  ecore_timer_interval_set(wpt.tim, WEATHER_POLL_INTERVAL_SEC);
+
+  if (!wpt.thread_h) {
+    wpt.thread_h = ecore_thread_run(__thread_function, __thread_end_cb, __thread_cancelled_cb, NULL);
+
+    // Error handling ...
+  }
+
+  return EINA_TRUE;
+}
+
+ +

Both __thread_function() +and __weather_data_read_cb() functions are executed +on behalf of a separate thread. Since weather_query() +is a blocking function, its execution from main thread would lock up the UI. +

+
+static void __thread_function(void *data, Ecore_Thread *thread)
+{
+  if (!weather_query(__weather_data_read_cb))
+    dlog_print(DLOG_ERROR, LOG_TAG, "Failed to make a query");
+}
+
+ +

Any UI update function calls from __weather_data_read_cb() +are prohibited. So this callback only stores pointers to received data in common memory area.

+ +
+static void __weather_data_read_cb(xml_weather_t *weather, image_buffer_t *image_buffer)
+{
+  wpt.weather = weather;
+  wpt.image_buffer = image_buffer;
+}
+
+ +

The __thread_end_cb() however is called automatically when the +__thread_function() finishes successfully. +It is called on behalf of the main thread and this is why it can call a callback from the main controller (updating the UI). +Server data pointers, previously stored by the __weather_data_read_cb() +function, are used. +

+ +
+static void __thread_end_cb(void *data, Ecore_Thread *thread)
+{
+  char *buffer = NULL;
+  int buffer_size = 0;
+
+  if (wpt.image_buffer) {
+    buffer = wpt.image_buffer->buffer;
+    buffer_size = wpt.image_buffer->size;
+  }
+
+  if (wpt.cb)
+    wpt.cb(wpt.weather, buffer, buffer_size);
+
+  xml_weather_dispose(wpt.weather);
+  weather_free_image_buffer(wpt.image_buffer);
+  wpt.weather = NULL;
+  wpt.image_buffer = NULL;
+  wpt.thread_h = NULL;
+}
+
+ +

Main view module

+ +

The watch_app_get_elm_win() +function is used to obtain a special watch type window. This way the application can receive ambient/normal mode switch events properly.

+ +
+bool view_create_gui(int width, int height)
+{
+  watch_app_get_elm_win(&vd.win);
+
+  // Error handling ...
+
+  evas_object_resize(vd.win, width, height);
+
+  vd.digital_clock = digital_clock_create(vd.win, width, height);
+  evas_object_show(vd.digital_clock);
+
+  vd.weather = weather_create(vd.win, width, height);
+
+  // Common code ...
+}
+
+ +

Each time a time tick occurs, the controller module calls view_set_time() +function. It updates the digital clock available in the normal application mode.

+ +
+void view_set_time(int hours, int minutes, int seconds,
+            int year, int month, int day, int week_day)
+{
+  digital_clock_set_time(vd.digital_clock, hours, minutes);
+}
+
+ +

The function below is called each time the application mode change occurs. Notice that in ambient mode only the +weather view is shown, whereas in normal mode only the digital clock is visible.

+ +
+void view_set_ambient(bool on_off)
+{
+  vd.ambient = on_off;
+
+  if (on_off) {
+    evas_object_show(vd.weather);
+    evas_object_hide(vd.digital_clock);
+  } else {
+    evas_object_show(vd.digital_clock);
+    evas_object_hide(vd.weather);
+  }
+}
+
+ + + +
+ +Go to top + + + + + + + diff --git a/org.tizen.sampledescriptions/html/wearable_n/sd_wn.htm b/org.tizen.sampledescriptions/html/wearable_n/sd_wn.htm index f093923..8230b61 100644 --- a/org.tizen.sampledescriptions/html/wearable_n/sd_wn.htm +++ b/org.tizen.sampledescriptions/html/wearable_n/sd_wn.htm @@ -64,7 +64,7 @@ (Circle) Cairo EvasGL Demonstrates how you can implement the Cairo GL backend with the Evas_GL surface. - + (Circle) Circular Camera Demonstrates how you can handle camera features, such as start a camera preview and capture images. @@ -104,11 +104,15 @@ (Rectangle) UI Dialer Demonstrates how you can implement a rectangular dialer view. - + (Rectangle) Widget Viewer Demonstrates how you can use the widget service and viewer. + + Ambient weather + Demonstrates how you can implement a simple watch with current weather display in ambient mode. + Analog Watch Demonstrates how you can implement an analog watch application.