Refactor widget_viewer_sdk 72/259572/19
authorjh9216.park <jh9216.park@samsung.com>
Thu, 10 Jun 2021 01:30:29 +0000 (21:30 -0400)
committerjh9216.park <jh9216.park@samsung.com>
Fri, 25 Jun 2021 06:13:52 +0000 (02:13 -0400)
- Requires
 https://review.tizen.org/gerrit/#/c/platform/core/api/app-common/+/259565/
 https://review.tizen.org/gerrit/#/c/platform/core/api/application/+/259567/
 https://review.tizen.org/gerrit/#/c/platform/core/api/app-control/+/259566/

Change-Id: I2031f950dbf195c6896b3ce5129c78206abd9d35
Signed-off-by: jh9216.park <jh9216.park@samsung.com>
widget_viewer_sdk/CMakeLists.txt
widget_viewer_sdk/include/debug.h [deleted file]
widget_viewer_sdk/include/main.h
widget_viewer_sdk/include/view.h [new file with mode: 0644]
widget_viewer_sdk/include/widget.h [new file with mode: 0644]
widget_viewer_sdk/src/main.c [deleted file]
widget_viewer_sdk/src/main.cc [new file with mode: 0644]
widget_viewer_sdk/src/view.cc [new file with mode: 0644]
widget_viewer_sdk/src/widget.cc [new file with mode: 0644]

index 10f3c70b86cd07a73abd094ace1b91f16099aecb..be6288ef7e74e5a69ba6efdb4105c9d92837f18f 100644 (file)
@@ -1,5 +1,5 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(widget_viewer_sdk C)
+PROJECT(widget_viewer_sdk C CXX)
 
 SET(PACKAGE ${PROJECT_NAME})
 SET(VENDOR "tizen")
@@ -29,6 +29,7 @@ IF("${ARCH}" STREQUAL "arm")
 ENDIF("${ARCH}" STREQUAL "arm")
 
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE")
+SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
 
 INCLUDE(FindPkgConfig)
 pkg_check_modules(sdk_pkgs REQUIRED
@@ -42,7 +43,6 @@ pkg_check_modules(sdk_pkgs REQUIRED
        dlog
        widget_service
        efl-extension
-       appsvc
 )
 
 ADD_DEFINITIONS("-DWIDGET_EVAS_RESOURCE_EDJ=\"${EDJDIR}/widget_viewer_sdk.edj\"")
@@ -56,7 +56,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../widget_viewer_evas/include)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../watch-holder/api)
 
 
-ADD_EXECUTABLE(${PROJECT_NAME} src/main.c)
+ADD_EXECUTABLE(${PROJECT_NAME} src/main.cc src/view.cc src/widget.cc)
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${sdk_pkgs_LDFLAGS} "-lm -pie -fPIC" widget_viewer_evas watch-holder)
 
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})
diff --git a/widget_viewer_sdk/include/debug.h b/widget_viewer_sdk/include/debug.h
deleted file mode 100644 (file)
index 483309e..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2013  Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#if !defined(FLOG)
-#define DbgPrint(format, arg...)    SECURE_LOGD(format, ##arg)
-#define ErrPrint(format, arg...)    SECURE_LOGE(format, ##arg)
-#else
-extern FILE *__file_log_fp;
-#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [\e[32m%s/%s\e[0m:%d] " format, widget_util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
-
-#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [\e[32m%s/%s\e[0m:%d] " format, widget_util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
-#endif
-
-
-/* End of a file */
index 21307e25277311449c609edd7d02baeac8b258e4..4f7cf657279a2c04b1a29facb0331cd0ec25fd6f 100644 (file)
@@ -24,5 +24,4 @@
 #define PREVIEW_DEFAULT RESDIR"/images/unknown.png"
 #define LAYOUT_EDJ RESDIR"/edje/widget_viewer_sdk.edj"
 
-#endif /* __MAIN_H__ */
-
+#endif /* __MAIN_H__ */
\ No newline at end of file
diff --git a/widget_viewer_sdk/include/view.h b/widget_viewer_sdk/include/view.h
new file mode 100644 (file)
index 0000000..5c95169
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2021  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.tizenopensource.org/license
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VIEW_H_
+#define VIEW_H_
+
+#include <Elementary.h>
+
+#include <list>
+#include <memory>
+#include <string>
+
+#include "widget.h"
+
+constexpr const double LAZY_WATCH_TIME = 3.0f;
+
+class View {
+ public:
+  View() = default;
+  ~View() = default;
+  Evas_Object* GetBox() const;
+  Evas_Object* GetWin() const;
+  Evas_Object* GetLayout() const;
+  Evas_Object* GetBg() const;
+  int GetW() const;
+  int GetH() const;
+  Ecore_Timer* GetLongPressTimer() const;
+  void SetLongPressTimer(Ecore_Timer* timer);
+  bool Init();
+  void Show();
+  void Resize();
+  void Activate();
+  void Fini();
+  int ExitWidget();
+  void RunWidget(const std::string& widget_id, app_control_h service,
+      const std::string& lazy_loader);
+
+ private:
+  int LoadWidget(const char* widget_id, Widget* info);
+  static Eina_Bool LazyWidgetLoaderCb(void* data);
+  static void HideWidgetInfoCb(void* data, Evas_Object* obj,
+      const char* emission, const char *source);
+
+ private:
+  int w_ = 0;
+  int h_ = 0;
+  Evas_Object* win_ = nullptr;
+  Evas_Object* bg_ = nullptr;
+  Evas_Object* box_ = nullptr;
+  Evas_Object* layout_ = nullptr;
+  Ecore_Timer* long_press_ = nullptr;
+  std::list<std::unique_ptr<Widget>> widget_info_list_;
+  Ecore_Timer* lazy_widget_loader_ = nullptr;
+  double lazy_watch_time_ = LAZY_WATCH_TIME;
+};
+
+#endif  // VIEW_H_
\ No newline at end of file
diff --git a/widget_viewer_sdk/include/widget.h b/widget_viewer_sdk/include/widget.h
new file mode 100644 (file)
index 0000000..39605e7
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2021  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.tizenopensource.org/license
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIDGET_H_
+#define WIDGET_H_
+
+#include <Elementary.h>
+
+#include <string>
+
+class View;
+class Widget {
+ public:
+  Widget(View* parent, std::string widget_id, double period,
+      int count_of_size_type);
+  Widget(const Widget& info) = delete;
+  Widget& operator = (const Widget&) = delete;
+
+  Widget(Widget&& info) noexcept;
+  Widget& operator = (Widget&& info) noexcept;
+  ~Widget();
+
+  const std::string& GetId() const;
+  const std::string& GetContent() const;
+  const std::string& GetTitle() const;
+  double GetPeriod() const;
+  bool Attach(const char* widget_id);
+  View* GetParent() const;
+  int Prepare(app_control_h control);
+
+ private:
+  static void UpdatedCb(void* data, Evas_Object* obj, void* event_info);
+  static void ExtraUpdatedCb(void* data, Evas_Object* obj, void* event_info);
+  static void WidgetCreateAbortedCb(void* data, Evas_Object* obj,
+      void* event_info);
+  static void WidgetCreatedCb(void* data, Evas_Object* obj, void* event_info);
+  static void PeriodChangedCb(void* data, Evas_Object* obj, void* event_info);
+  static void LayoutDownCb(void* data, Evas* e, Evas_Object* obj,
+      void* event_info);
+  static void LayoutUpCb(void* data, Evas* e, Evas_Object* obj,
+      void* event_info);
+  static Eina_Bool ShowWidgetInfoCb(void* data);
+  static char* ListItemTextGetCb(void* data, Evas_Object* obj,
+      const char* part);
+  static Evas_Object* ListItemContentGetCb(void* data, Evas_Object* obj,
+      const char* part);
+  static void ListItemClickedCb(void* data, Evas_Object* obj,
+      void* event_info);
+  void UpdateMessage(const char* fmt, ...);
+
+ private:
+  View* parent_ = nullptr;
+  std::string widget_id_;
+  std::string content_info_;
+  std::string title_;
+  double period_;
+  Evas_Object* widget_ = nullptr;
+  Evas_Object* widget_layout_ = nullptr;
+  int* size_types_ = nullptr;
+  int count_of_size_type_ = 0;
+};
+
+#endif  // WIDGET_H_
\ No newline at end of file
diff --git a/widget_viewer_sdk/src/main.c b/widget_viewer_sdk/src/main.c
deleted file mode 100644 (file)
index d7df949..0000000
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * Copyright 2014  Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <glib.h>
-#include <Elementary.h>
-#include <app.h>
-#include <unistd.h>
-#include <errno.h>
-#include <watch_holder.h>
-#include <widget_errno.h>
-#include <widget_service.h>
-#include <widget_service_internal.h>
-#include <widget_viewer_evas.h>
-#include <vconf.h>
-#include <bundle.h>
-#include <dlog.h>
-#include <string.h>
-#include <app_control.h>
-#include <app_control_internal.h>
-#include <efl_extension.h>
-#include <aul.h>
-#include <aul_debug_info.h>
-#include <appsvc.h>
-#include <pkgmgr-info.h>
-
-
-int errno;
-
-#include "main.h"
-#include "debug.h"
-
-#define ERR_BUFFER_SIZE                1024
-#define WATCH_CATEGORY "http://tizen.org/category/wearable_clock"
-#define LAZY_WATCH_TIME 3.0f
-#define CR 13
-#define LF 10
-#if !defined(VCONFKEY_WMS_CLOCKS_SET_IDLE)
-#define VCONFKEY_WMS_CLOCKS_SET_IDLE "db/wms/clocks_set_idle"
-#endif
-
-#define LAZY_LOADER "__LAZY_LOADER__"
-#define DEFAULT_WATCH "org.tizen.idle-clock-digital"
-
-typedef struct _widget_info {
-       char *widget_id;
-       char *content_info;
-       char *title;
-       double period;
-       Evas_Object *widget;
-       Evas_Object *widget_layout;
-       int *size_types;
-       int count_of_size_type;
-} widget_info;
-
-typedef struct _widget_size_list_item {
-       widget_info *info;
-       int idx;
-}widget_size_list_item;
-
-static struct info {
-       int w;
-       int h;
-       Evas_Object *win;
-       Evas_Object *bg;
-       Evas_Object *box;
-       Evas_Object *layout;
-       Ecore_Timer *long_press;
-       GList *widget_info_list;
-       Ecore_Timer *lazy_widget_loader;
-       double lazy_watch_time;
-       char *default_watch;
-       char *watch_category;
-} s_info = {
-       .w = 0,
-       .h = 0,
-       .win = NULL,
-       .layout = NULL,
-       .long_press = NULL,
-       .widget_info_list = NULL,
-       .lazy_widget_loader = NULL,
-       .lazy_watch_time = LAZY_WATCH_TIME,
-       .default_watch = DEFAULT_WATCH,
-       .watch_category = WATCH_CATEGORY,
-};
-
-#define LONG_PRESS 1.0f
-#define CONF_FNAME "/etc/widget_viewer_sdk.conf"
-
-static char *__watch_pkgid;
-static Evas_Object *__clock;
-static bool __debug_info_initialized;
-static watch_holder_h __watch_holder;
-
-static void back_key_cb(void *data, Evas_Object *obj, void *event_info)
-{
-       ui_app_exit();
-}
-
-static void hide_widget_info_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
-{
-       DbgPrint("Hide info panel\n");
-       elm_object_signal_emit(s_info.layout, "hide", "info");
-}
-
-static char *list_item_text_get_cb(void *data, Evas_Object *obj, const char *part)
-{
-       char buffer[256];
-       int ret;
-       int w;
-       int h;
-       widget_size_list_item *item = (widget_size_list_item *)data;
-
-       ret = widget_service_get_size(item->info->size_types[item->idx], &w, &h);
-       if (ret != WIDGET_ERROR_NONE)
-               return strdup("Invalid");
-
-       snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
-       DbgPrint("Size: [%s]\n", buffer);
-       return strdup(buffer);
-}
-
-static Evas_Object *list_item_content_get_cb(void *data, Evas_Object *obj, const char *part)
-{
-       Evas_Object *icon = NULL;
-       char *icon_filename;
-       const char *widget_id;
-       widget_size_list_item *item = (widget_size_list_item *)data;
-
-       widget_id = widget_viewer_evas_get_widget_id(item->info->widget);
-
-       icon_filename = widget_service_get_preview_image_path(widget_id, item->info->size_types[item->idx]);
-       if (icon_filename) {
-               icon = elm_icon_add(s_info.win);
-               if (icon) {
-                       elm_image_file_set(icon, icon_filename, NULL);
-                       elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
-                       evas_object_size_hint_max_set(icon, 100, 100);
-                       DbgPrint("Icon: %s\n", icon_filename);
-               }
-               free(icon_filename);
-       } else {
-               icon = NULL;
-       }
-
-       return icon;
-}
-
-static void list_item_clicked_cb(void *data, Evas_Object *obj, void *event_info)
-{
-       int w;
-       int h;
-       widget_size_list_item *item;
-
-       item = (widget_size_list_item *)data;
-       if (item == NULL)
-               return;
-
-       if (widget_service_get_size(item->info->size_types[item->idx], &w, &h) != WIDGET_ERROR_NONE)
-               return;
-
-       evas_object_resize(item->info->widget, w, h);
-       evas_object_size_hint_min_set(item->info->widget, w, h);
-       evas_object_size_hint_max_set(item->info->widget, w, h);
-}
-
-static Eina_Bool show_widget_info_cb(void *data)
-{
-       DbgPrint("Show info panel\n");
-
-       int i;
-       int w;
-       int h;
-       Evas_Object *size_list;
-       widget_size_list_item *item;
-       Elm_Object_Item *elm_item;
-       widget_info *info = (widget_info *)data;
-       static Elm_Genlist_Item_Class class = {
-               .item_style = "1text.1icon",
-               .func = {
-                       .text_get = list_item_text_get_cb,
-                       .content_get = list_item_content_get_cb,
-                       .state_get = NULL,
-                       .del = NULL,
-               }
-       };
-
-       DbgPrint("======== %d", info->count_of_size_type);
-
-       if (info->count_of_size_type <= 1) {
-               elm_object_signal_emit(s_info.layout, "hide", "size,list");
-               return ECORE_CALLBACK_CANCEL;
-       } else {
-               elm_object_signal_emit(s_info.layout, "show", "size,list");
-       }
-
-       size_list = elm_object_part_content_get(s_info.layout, "widget,size,list");
-       if (size_list) {
-               elm_genlist_clear(size_list);
-       } else {
-               size_list = elm_genlist_add(s_info.win);
-               if (!size_list) {
-                       ErrPrint("Failed to create a genlist\n");
-                       return ECORE_CALLBACK_RENEW;
-               }
-
-               elm_object_part_content_set(s_info.layout, "widget,size,list", size_list);
-       }
-
-       DbgPrint("========\nDump supported size types \n");
-       for (i = 0; i < info->count_of_size_type; i++) {
-               if (widget_service_get_size(info->size_types[i], &w, &h) != WIDGET_ERROR_NONE || w == 0 || h == 0) {
-                       DbgPrint("[%X] is not supported (%dx%d)\n", info->size_types[i], w, h);
-                       continue;
-               }
-               DbgPrint("Size[%X]\n", info->size_types[i]);
-
-               item = (widget_size_list_item *)calloc(1, sizeof(widget_size_list_item));
-               if (item == NULL) {
-                       ErrPrint("Fail to calloc");
-                       continue;
-               }
-
-               item->info = info;
-               item->idx = i;
-               elm_item = elm_genlist_item_append(size_list, &class, (void *)item, NULL, ELM_GENLIST_ITEM_NONE, list_item_clicked_cb, (void *)item);
-               if (!elm_item)
-                       ErrPrint("Failed to add a new size elm_item\n");
-       }
-       DbgPrint("========\nEnd of a dump\n");
-       elm_object_signal_emit(s_info.layout, "show", "info");
-
-       s_info.long_press = NULL;
-       return ECORE_CALLBACK_CANCEL;
-}
-
-static void layout_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
-       if (s_info.long_press) {
-               ecore_timer_del(s_info.long_press);
-               s_info.long_press = NULL;
-       }
-
-       s_info.long_press = ecore_timer_add(LONG_PRESS, show_widget_info_cb, data);
-       if (!s_info.long_press)
-               ErrPrint("Failed to add a timer\n");
-}
-
-static void layout_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
-       if (s_info.long_press) {
-               ecore_timer_del(s_info.long_press);
-               s_info.long_press = NULL;
-       }
-}
-
-void  __clock_vconf_cb(keynode_t *node, void *data)
-{
-       char *cur_watch = vconf_get_str(VCONFKEY_WMS_CLOCKS_SET_IDLE);
-
-       LOGD("watch sdk [%s], home [%s]",
-                       __watch_pkgid, cur_watch);
-       if (cur_watch != NULL && __watch_pkgid != NULL
-                       && strcmp(cur_watch, __watch_pkgid) == 0) {
-               ui_app_exit();
-               LOGW("same watch displayed on the other viewer EXIT");
-       }
-       free(cur_watch);
-}
-
-static bool app_create(void *data)
-{
-
-       Evas_Object *scroller;
-       s_info.win = elm_win_add(NULL, "Widget Viewer (SDK)", ELM_WIN_BASIC);
-       if (!s_info.win) {
-               LOGD("Failed to create a window\n");
-               return false;
-       }
-
-       elm_app_base_scale_set(2.6);
-       elm_win_screen_size_get(s_info.win, NULL, NULL, &s_info.w, &s_info.h);
-       LOGD("Window: %dx%d\n", s_info.w, s_info.h);
-
-       elm_win_alpha_set(s_info.win, EINA_FALSE);
-       elm_win_indicator_mode_set(s_info.win, ELM_WIN_INDICATOR_SHOW);
-
-       s_info.layout = elm_layout_add(s_info.win);
-       if (!s_info.layout) {
-               evas_object_del(s_info.box);
-               evas_object_del(s_info.bg);
-               evas_object_del(s_info.win);
-               s_info.box = NULL;
-               s_info.win = NULL;
-               s_info.bg = NULL;
-               return false;
-       }
-
-       if (elm_layout_file_set(s_info.layout, LAYOUT_EDJ, "layout") != EINA_TRUE) {
-               LOGE("Failed to load an edje\n");
-               evas_object_del(s_info.bg);
-               evas_object_del(s_info.layout);
-               evas_object_del(s_info.win);
-               s_info.bg = NULL;
-               s_info.layout = NULL;
-               s_info.win = NULL;
-               return false;
-       }
-       evas_object_size_hint_weight_set(s_info.layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-       elm_win_resize_object_add(s_info.win, s_info.layout);
-       evas_object_show(s_info.layout);
-       elm_object_signal_callback_add(s_info.layout, "mouse,clicked,1", "widget,info,bg", hide_widget_info_cb, NULL);
-
-       /* Initialize scroller */
-       scroller = elm_scroller_add(s_info.layout);
-       evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-       elm_win_resize_object_add(s_info.layout, scroller);
-       evas_object_show(scroller);
-
-
-       /* Initialize box */
-       s_info.box = elm_box_add(scroller);
-       if (!s_info.box) {
-               evas_object_del(s_info.bg);
-               evas_object_del(s_info.win);
-               s_info.bg = NULL;
-               s_info.win = NULL;
-               return false;
-       }
-       evas_object_size_hint_fill_set(s_info.box, EVAS_HINT_FILL, EVAS_HINT_FILL);
-       evas_object_size_hint_weight_set(s_info.box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-       elm_box_align_set(s_info.box, 0.0, 0.0);
-
-
-       elm_object_content_set(scroller, s_info.box);
-       elm_scroller_bounce_set(scroller, EINA_TRUE, EINA_FALSE);
-       elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
-       elm_scroller_propagate_events_set(scroller, EINA_TRUE);
-       elm_scroller_page_relative_set(scroller, 0, 1);
-       elm_scroller_region_show(scroller, 50, 50, 200, 200);
-
-       elm_object_scroll_lock_x_set(scroller, EINA_FALSE);
-       elm_object_part_content_set(s_info.layout, "widget", scroller);
-
-
-       /* WIDGET init */
-       widget_viewer_evas_set_option(WIDGET_VIEWER_EVAS_DIRECT_UPDATE, 1);
-       widget_viewer_evas_set_option(WIDGET_VIEWER_EVAS_EVENT_AUTO_FEED, 1);
-       widget_viewer_evas_init(s_info.win);
-
-       eext_object_event_callback_add(s_info.win, EEXT_CALLBACK_BACK, back_key_cb, NULL);
-       evas_object_show(s_info.win);
-       vconf_notify_key_changed(VCONFKEY_WMS_CLOCKS_SET_IDLE, __clock_vconf_cb, NULL);
-
-       return true;
-}
-
-static void free_widget_info(gpointer data)
-{
-       const char *tmp;
-       widget_info *info = (widget_info *)data;
-
-       if (info == NULL)
-               return;
-
-       tmp = widget_viewer_evas_get_widget_id(info->widget);
-       DbgPrint("Unload previous widget: %s\n", tmp);
-
-       elm_box_unpack(s_info.box, info->widget_layout);
-       evas_object_del(info->widget);
-       evas_object_del(info->widget_layout);
-       if (info->title)
-               free(info->title);
-       if (info->content_info)
-               free(info->content_info);
-       if (info->size_types)
-               free(info->size_types);
-       if (info->widget_id)
-               free(info->widget_id);
-
-       info->widget = NULL;
-       info->widget_layout = NULL;
-       info->title = NULL;
-       info->content_info = NULL;
-       info->size_types = NULL;
-       info->period = WIDGET_VIEWER_EVAS_DEFAULT_PERIOD;
-       info->count_of_size_type = 20;
-       free(info);
-}
-
-static int unload_widget(void)
-{
-       int widget_cnt;
-
-       widget_cnt = g_list_length(s_info.widget_info_list);
-       if (widget_cnt == 0)
-               return WIDGET_ERROR_NOT_EXIST;
-
-       g_list_free_full(s_info.widget_info_list, free_widget_info);
-       s_info.widget_info_list = NULL;
-
-       elm_object_part_text_set(s_info.layout, "widget,id", "");
-       elm_object_part_text_set(s_info.layout, "widget,content,info", "");
-       elm_object_part_text_set(s_info.layout, "widget,title", "");
-       elm_object_part_text_set(s_info.layout, "widget,period", "");
-
-       return WIDGET_ERROR_NONE;
-}
-
-static void app_terminate(void *data)
-{
-       eext_object_event_callback_del(s_info.win, EEXT_CALLBACK_BACK, back_key_cb);
-
-       if (__debug_info_initialized) {
-               aul_debug_info_fini();
-               __debug_info_initialized = false;
-       }
-       unload_widget();
-
-       /* WIDGET fini */
-       widget_viewer_evas_fini();
-
-       if (s_info.win) {
-               evas_object_del(s_info.win);
-               s_info.win = NULL;
-       }
-}
-
-static void app_pause(void *data)
-{
-       /* WIDGET pause */
-       widget_viewer_evas_notify_paused_status_of_viewer();
-       watch_h watch;
-       int ret = watch_holder_get_current(__watch_holder, &watch);
-       if (ret == WATCH_HOLDER_ERROR_NONE) {
-               ret = watch_pause(watch);
-               if (ret != WATCH_HOLDER_ERROR_NONE) {
-                       ErrPrint("watch_pause() failed: %d", ret);
-               }
-       }
-}
-
-static void __resume_process()
-{
-       widget_viewer_evas_notify_resumed_status_of_viewer();
-       watch_h watch;
-       int ret = watch_holder_get_current(__watch_holder, &watch);
-       if (ret == WATCH_HOLDER_ERROR_NONE) {
-               ret = watch_resume(watch);
-               if (ret != WATCH_HOLDER_ERROR_NONE) {
-                       ErrPrint("watch_resume() failed: %d", ret);
-               }
-       }
-}
-
-static void app_resume(void *data)
-{
-       __resume_process();
-}
-
-static void updated_cb(void *data, Evas_Object *obj, void *event_info)
-{
-       /* Updated */
-       DbgPrint("Widget updated\n");
-}
-
-static void extra_updated_cb(void *data, Evas_Object *obj, void *event_info)
-{
-       const char *string;
-       char *tmp;
-       widget_info *info = (widget_info *)data;
-
-       string = widget_viewer_evas_get_title_string(obj);
-       if (string) {
-               tmp = strdup(string);
-               if (!tmp)
-                       return;
-
-               free(info->title);
-               info->title = tmp;
-
-               elm_object_part_text_set(s_info.layout, "widget,title", info->title);
-       }
-
-       string = widget_viewer_evas_get_content_info(obj);
-       if (string) {
-               tmp = strdup(string);
-               if (!tmp)
-                       return;
-
-               free(info->content_info);
-               info->content_info = tmp;
-
-               elm_object_part_text_set(s_info.layout, "widget,content,info", info->content_info);
-               DbgPrint("Content updated: [%s]\n", info->content_info);
-       }
-}
-
-static void period_changed_cb(void *data, Evas_Object *obj, void *event_info)
-{
-       char buffer[96];
-       widget_info *info = (widget_info *)data;
-
-       info->period = widget_viewer_evas_get_period(obj);
-       snprintf(buffer, sizeof(buffer), "%lf", info->period);
-       elm_object_part_text_set(s_info.layout, "widget,period", buffer);
-       DbgPrint("Period updated: %s\n", buffer);
-}
-
-static void update_message(const char *fmt, ...)
-{
-       if (!fmt) {
-               elm_object_signal_emit(s_info.layout, "hide", "message");
-       } else {
-               va_list ap;
-               char buffer[1024];
-
-               va_start(ap, fmt);
-               vsnprintf(buffer, sizeof(buffer) - 1, fmt, ap);
-               va_end(ap);
-
-               elm_object_part_text_set(s_info.layout, "message", buffer);
-               elm_object_signal_emit(s_info.layout, "show", "message");
-               ErrPrint("%s", buffer);
-       }
-}
-
-static void widget_create_aborted_cb(void *data, Evas_Object *obj, void *event_info)
-{
-       update_message("Create aborted");
-}
-
-static void widget_created_cb(void *data, Evas_Object *obj, void *event_info)
-{
-       period_changed_cb(data, obj, NULL);
-       extra_updated_cb(data, obj, NULL);
-}
-
-static int load_widget(const char *widget_id, widget_info *info)
-{
-       Evas_Object *bg = NULL;
-       int w = 0;
-       int h = 0;
-       int i;
-
-       for (i = 0; i < info->count_of_size_type; i++) {
-               if (widget_service_get_size(info->size_types[i], &w, &h) != WIDGET_ERROR_NONE || w == 0 || h == 0)
-                       continue;
-               break;
-       }
-
-       info->widget_layout = elm_layout_add(s_info.win);
-       elm_layout_file_set(info->widget_layout, LAYOUT_EDJ, "widget");
-       evas_object_size_hint_weight_set(info->widget_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-       evas_object_size_hint_align_set(info->widget, 0.0, 0.5);
-       evas_object_show(info->widget_layout);
-
-       bg = evas_object_rectangle_add(evas_object_evas_get(s_info.layout));
-       evas_object_resize(bg, w, h);
-       evas_object_size_hint_min_set(bg, w, h);
-       evas_object_color_set(bg, 255, 255, 255, 0);
-       evas_object_show(bg);
-       elm_object_part_content_set(info->widget_layout, "bg", bg);
-
-       info->widget = widget_viewer_evas_add_widget(s_info.win, widget_id, info->content_info, info->period);
-       if (!info->widget) {
-               update_message("Failed to create a new widget");
-               return WIDGET_ERROR_FAULT;
-       }
-
-       DbgPrint("Resize the widget(%s) to [%X] %dx%d\n", widget_id, info->size_types[0], w, h);
-
-       evas_object_smart_callback_add(info->widget, WIDGET_SMART_SIGNAL_UPDATED, updated_cb, info);
-       evas_object_smart_callback_add(info->widget, WIDGET_SMART_SIGNAL_EXTRA_INFO_UPDATED, extra_updated_cb, info);
-       evas_object_smart_callback_add(info->widget, WIDGET_SMART_SIGNAL_PERIOD_CHANGED, period_changed_cb, info);
-       evas_object_smart_callback_add(info->widget, WIDGET_SMART_SIGNAL_WIDGET_CREATED, widget_created_cb, info);
-       evas_object_smart_callback_add(info->widget, WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED, widget_create_aborted_cb, info);
-
-       evas_object_resize(info->widget, w, h);
-       evas_object_size_hint_align_set(info->widget, 0.0, 0.5);
-       evas_object_show(info->widget);
-       elm_object_part_content_set(info->widget_layout, "widget", info->widget);
-
-       elm_box_pack_end(s_info.box, info->widget_layout);
-       elm_object_part_text_set(s_info.layout, "widget,id", widget_id);
-
-       update_message(NULL);
-       elm_box_padding_set(s_info.box, 0, 5);
-
-       DbgPrint("Found valid size[%X]: %dx%d\n", info->size_types[i], w, h);
-       evas_object_event_callback_add(info->widget, EVAS_CALLBACK_MOUSE_DOWN, layout_down_cb, info);
-       evas_object_event_callback_add(info->widget, EVAS_CALLBACK_MOUSE_UP, layout_up_cb, NULL);
-
-       s_info.widget_info_list = g_list_append(s_info.widget_info_list, info);
-
-       return WIDGET_ERROR_NONE;
-}
-
-static int prepare_widget(const char *widget_id, app_control_h control, widget_info *info)
-{
-       int ret;
-       bundle *b;
-
-       if (app_control_export_as_bundle(control, &b) == APP_CONTROL_ERROR_NONE) {
-               bundle_raw *r;
-               int len;
-
-               if (bundle_encode(b, &r, &len) == BUNDLE_ERROR_NONE) {
-                       info->content_info = strdup((const char *)r);
-                       if (!info->content_info)
-                               ErrPrint("strdup: %d\n", errno);
-                       else
-                               DbgPrint("Encoded content_info: [%s]\n", info->content_info);
-
-                       free((char *)r);
-               } else {
-                       ErrPrint("Failed to encode a bundle\n");
-               }
-
-               bundle_free(b);
-       }
-
-       info->count_of_size_type = 20;
-       ret = widget_service_get_supported_size_types(widget_id, &info->count_of_size_type, &info->size_types);
-       if (ret != WIDGET_ERROR_NONE)
-               ErrPrint("Failed to load an widget\n");
-
-       DbgPrint("[%s] %d\n", widget_id, info->count_of_size_type);
-       return ret;
-}
-
-static Eina_Bool lazy_widget_loader_cb(void *data)
-{
-       widget_info *info = (widget_info *)data;
-
-       DbgPrint("Lazy loader expired. load widget [%s]\n", info->widget_id);
-       (void)load_widget(info->widget_id, info);
-       s_info.lazy_widget_loader = NULL;
-
-       return ECORE_CALLBACK_CANCEL;
-}
-
-static void _run_widget(char *widget_id, app_control_h service, char *lazy_loader)
-{
-       widget_info *info = (widget_info *)calloc(1, sizeof(widget_info));
-
-       if (info == NULL) {
-               ErrPrint("Fail to create info");
-               return;
-       }
-       info->widget_id = strdup(widget_id);
-       if (info->widget_id == NULL) {
-               ErrPrint("Fail to strdup widget_id");
-               free(info);
-               return;
-       }
-
-       info->period = WIDGET_VIEWER_EVAS_DEFAULT_PERIOD;
-       info->count_of_size_type = 20;
-
-       prepare_widget(widget_id, service, info);
-       if (s_info.lazy_widget_loader) {
-               char *tmp;
-               tmp = ecore_timer_del(s_info.lazy_widget_loader);
-               free(tmp);
-       }
-
-       if (lazy_loader != NULL && strcmp(lazy_loader, "true") == 0) {
-               DbgPrint("Load a watch after some time later (%lf)\n", s_info.lazy_watch_time);
-               s_info.lazy_widget_loader = ecore_timer_add(s_info.lazy_watch_time, lazy_widget_loader_cb, info);
-               if (!s_info.lazy_widget_loader) {
-                       ErrPrint("Unable to fire the timer\n");
-                       lazy_widget_loader_cb(info);
-               }
-               /**
-                * @note
-                * widget_id will be deleted from lazy_widget_loader_cb. or return value of ecore_timer_del().
-                */
-       } else {
-               DbgPrint("Immediately loads the watch[%s]\n", widget_id);
-               lazy_widget_loader_cb(info);
-       }
-}
-
-static void __set_bundle_for_watchapp(bundle *app_control_b, bundle *b)
-{
-       char *sdk_util = NULL;
-       char *value = NULL;
-       char buf[32];
-
-       bundle_get_str(app_control_b, AUL_K_DEBUG, &value);
-       if (value) {
-               bundle_add_str(b, AUL_K_DEBUG, value);
-               value = NULL;
-       }
-
-       bundle_get_str(app_control_b, AUL_K_SEQ_NUM, &value);
-       if (value) {
-               bundle_add_str(b, AUL_K_SEQ_NUM, value);
-               value = NULL;
-       }
-
-       bundle_get_str(app_control_b, AUL_K_WAIT_RESULT, &value);
-       if (value) {
-               bundle_add_str(b, AUL_K_WAIT_RESULT, value);
-               value = NULL;
-       }
-
-       bundle_get_str(app_control_b, AUL_K_CALLER_PID, &value);
-       if (value) {
-               bundle_add_str(b, AUL_K_CALLER_PID, value);
-               value = NULL;
-       } else {
-               snprintf(buf, sizeof(buf), "%d", getpid());
-               bundle_add_str(b, AUL_K_CALLER_PID, buf);
-       }
-
-       bundle_get_str(app_control_b, AUL_K_CALLER_UID, &value);
-       if (value) {
-               bundle_add_str(b, AUL_K_CALLER_UID, value);
-               value = NULL;
-       } else {
-               snprintf(buf, sizeof(buf), "%d", getuid());
-               bundle_add_str(b, AUL_K_CALLER_UID, buf);
-       }
-
-       bundle_get_str(app_control_b, AUL_K_SDK, &sdk_util);
-       if (sdk_util != NULL) {
-               aul_debug_info_init();
-               aul_debug_info_set(app_control_b, b); // copies all the keys and values
-               __debug_info_initialized = true;
-               DbgPrint("util %s", sdk_util);
-       }
-}
-
-static char *__get_pkgid_by_appid(char *appid)
-{
-       pkgmgrinfo_appinfo_h handle;
-       int ret;
-       char *pkgid = NULL;
-       char *ret_pkgid = NULL;
-
-       ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
-       if (ret != PMINFO_R_OK)
-               return NULL;
-
-       ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
-       if (ret != PMINFO_R_OK) {
-               pkgmgrinfo_appinfo_destroy_appinfo(handle);
-               return NULL;
-       }
-
-       ret_pkgid = strdup(pkgid);
-       pkgmgrinfo_appinfo_destroy_appinfo(handle);
-
-       return ret_pkgid;
-}
-
-static void __watch_launched_cb(watch_h watch, void *data) {
-       char* appid = NULL;
-       watch_get_appid(watch, &appid);
-       DbgPrint("watch(%s) launched", appid);
-       if (appid)
-               free(appid);
-}
-
-static void __watch_dead_cb(watch_h watch, bool is_faulted, void *data) {
-       char* appid = NULL;
-       watch_get_appid(watch, &appid);
-       DbgPrint("watch(%s) dead (%d)", appid, is_faulted);
-       if (appid)
-               free(appid);
-}
-
-static void __watch_added_cb(watch_h watch, void *data) {
-       if (watch == NULL) {
-               ErrPrint("Wrong operation");
-               return;
-       }
-
-       char* appid = NULL;
-       watch_get_appid(watch, &appid);
-       DbgPrint("watch added : %s", appid);
-       if (appid)
-               free(appid);
-
-       int ret = watch_get_current_image(watch, &__clock);
-       if (ret == WATCH_HOLDER_ERROR_NONE) {
-               evas_object_resize(s_info.win, s_info.w, s_info.h);
-               evas_object_resize(__clock, s_info.w, s_info.h);
-               evas_object_show(__clock);
-               evas_object_show(s_info.win);
-       } else {
-               ErrPrint("watch_get_current_image error:%d", ret);
-       }
-}
-
-static void __watch_removed_cb(watch_h watch, void *data) {
-       DbgPrint("watch removed");
-}
-
-static void __watch_updated_cb(watch_h watch, Evas_Object *image, void *data) {
-       DbgPrint("watch updated");
-}
-
-static void __watch_bound_cb(watch_h watch, void *data) {
-       DbgPrint("watch bound");
-}
-
-static void __watch_ambient_changed_cb(bool enter, bundle *extra, void *data) {
-       DbgPrint("watch ambient changed (%d)", enter);
-}
-
-static void __watch_ambient_event_cb(
-               watch_holder_ambient_event_e event, const char *sender, bundle *extra, void *data) {
-       DbgPrint("watch ambient event (%d) from (%s)", event, sender);
-}
-
-static void _app_control(app_control_h service, void *user_data)
-{
-       char *widget_id = NULL;
-       int ret;
-       char *app_type = NULL;
-       pkgmgrinfo_appinfo_h app_info = NULL;
-       bundle *data = NULL;
-       bundle *app_control_b;
-       char *lazy_loader = NULL;
-       bool is_array;
-       int array_len;
-       char **widget_id_arr;
-       int i;
-       char *cur_watch = NULL;
-
-       app_control_get_extra_data(service, WIDGET_APPID, &widget_id);
-       if (widget_id) {
-               DbgPrint("Loading a widget: [%s]\n", widget_id);
-               ret = pkgmgrinfo_appinfo_get_appinfo(widget_id, &app_info);
-               if (PMINFO_R_OK != ret)
-                       ErrPrint("fail to get %s appinfo %d", widget_id, ret);
-               else
-                       pkgmgrinfo_appinfo_get_component_type(app_info, &app_type);
-       }
-
-       if (app_type != NULL && strcmp(app_type, "watchapp") == 0) {
-               cur_watch = vconf_get_str(VCONFKEY_WMS_CLOCKS_SET_IDLE);
-               if (widget_id != NULL) {
-                       if (__watch_pkgid) {
-                               free(__watch_pkgid);
-                               __watch_pkgid = NULL;
-                       }
-                       __watch_pkgid = __get_pkgid_by_appid(widget_id);
-
-                       if (cur_watch != NULL && __watch_pkgid != NULL &&
-                                       strcmp(cur_watch, __watch_pkgid) == 0) {
-                               vconf_set_str(VCONFKEY_WMS_CLOCKS_SET_IDLE,
-                                               DEFAULT_WATCH);
-                       }
-               }
-               evas_object_resize(s_info.win, s_info.w, s_info.h);
-
-               watch_holder_lifecycle_st lifecycle;
-               lifecycle.watch_holder_lifecycle_launched_cb = __watch_launched_cb;
-               lifecycle.watch_holder_lifecycle_dead_cb = __watch_dead_cb;
-               lifecycle.watch_holder_lifecycle_added_cb = __watch_added_cb;
-               lifecycle.watch_holder_lifecycle_removed_cb = __watch_removed_cb;
-               lifecycle.watch_holder_lifecycle_updated_cb = __watch_updated_cb;
-               lifecycle.watch_holder_lifecycle_bound_cb = __watch_bound_cb;
-               lifecycle.watch_holder_lifecycle_ambient_changed_cb = __watch_ambient_changed_cb;
-               lifecycle.watch_holder_lifecycle_ambient_event_cb = __watch_ambient_event_cb;
-
-               if (__watch_holder != NULL) {
-                       watch_holder_destroy(__watch_holder);
-                       __watch_holder = NULL;
-               }
-
-               ret = watch_holder_create(s_info.win, lifecycle, &s_info, &__watch_holder);
-               if (ret != WATCH_HOLDER_ERROR_NONE) {
-                       ErrPrint("Watch Holder Error:%d", ret);
-                       goto end;
-               }
-
-               data = bundle_create();
-               if (data == NULL) {
-                       ErrPrint("Out of memory");
-                       goto end;
-               }
-
-               app_control_to_bundle(service, &app_control_b);
-               __set_bundle_for_watchapp(app_control_b, data);
-               ret = watch_holder_launch(__watch_holder, false, widget_id, data);
-               if (ret < 0)
-                       ErrPrint("Watch Holder Launch Error:%d", ret);
-               else
-                       DbgPrint("Watch Holder Launch pid(%d)", ret);
-       } else {
-               ret = app_control_get_extra_data(service, LAZY_LOADER, &lazy_loader);
-               app_control_to_bundle(service, &data);
-               widget_service_set_sdk_util(data);
-               ret = unload_widget();
-               ret = app_control_is_extra_data_array(service, WIDGET_APPID, &is_array);
-               if (is_array) {
-                       app_control_get_extra_data_array(service, WIDGET_APPID, &widget_id_arr, &array_len);
-                       for (i = 0; i < array_len; ++i) {
-                               _run_widget(widget_id_arr[i], service, lazy_loader);
-                               free(widget_id_arr[i]);
-                       }
-                       free(widget_id_arr);
-               } else if (widget_id != NULL) {
-                       _run_widget(widget_id, service, lazy_loader);
-               } else {
-                       __resume_process();
-                       elm_win_activate(s_info.win);
-               }
-       }
-
-end:
-       if (data)
-               bundle_free(data);
-
-       if (cur_watch)
-               free(cur_watch);
-
-       if (lazy_loader)
-               free(lazy_loader);
-
-       if (widget_id)
-               free(widget_id);
-
-       if (app_info)
-               pkgmgrinfo_appinfo_destroy_appinfo(app_info);
-}
-
-int main(int argc, char *argv[])
-{
-       char err_buf[ERR_BUFFER_SIZE];
-       ui_app_lifecycle_callback_s event_callback;
-
-       event_callback.create = app_create;
-       event_callback.terminate = app_terminate;
-       event_callback.pause = app_pause;
-       event_callback.resume = app_resume;
-       event_callback.app_control = _app_control;
-
-       if (setenv("BUFMGR_LOCK_TYPE", "once", 0) < 0)
-               LOGE("setenv(BUFMGR_LOCK_TYPE) is failed: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
-
-       if (setenv("BUFMGR_MAP_CACHE", "true", 0) < 0)
-               LOGE("setenv(BUFMGR_MAP_CACHE) is failed: %s", strerror_r(errno, err_buf, sizeof(err_buf)));
-
-       return ui_app_main(argc, argv, &event_callback, NULL);
-}
-
-/* End of a file */
diff --git a/widget_viewer_sdk/src/main.cc b/widget_viewer_sdk/src/main.cc
new file mode 100644 (file)
index 0000000..5b11a30
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+* Copyright 2014 - 2021 Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.1 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <app.hpp>
+#include <app_control.hpp>
+#include <app_control_internal.h>
+#include <aul.h>
+#include <aul_debug_info.h>
+#include <bundle_cpp.h>
+#include <dlog.h>
+#include <efl_extension.h>
+#include <Elementary.h>
+#include <pkgmgr-info.h>
+#include <vconf.h>
+#include <watch_holder.h>
+#include <widget_errno.h>
+#include <widget_service.h>
+#include <widget_service_internal.h>
+#include <widget_viewer_evas.h>
+
+#include "main.h"
+#include "view.h"
+#include "widget.h"
+
+using namespace tizen_appfw;
+
+#if !defined(VCONFKEY_WMS_CLOCKS_SET_IDLE)
+#define VCONFKEY_WMS_CLOCKS_SET_IDLE "db/wms/clocks_set_idle"
+#endif
+
+namespace {
+
+constexpr const char LAZY_LOADER[] = "__LAZY_LOADER__";
+constexpr const char DEFAULT_WATCH[] = "org.tizen.idle-clock-digital";
+
+class App : public UiAppBase {
+ public:
+  App() = default;
+  virtual ~App() = default;
+
+  bool OnCreate() override {
+    if (!view_.Init())
+      return false;
+    vconf_notify_key_changed(VCONFKEY_WMS_CLOCKS_SET_IDLE, ClockVconfCb, this);
+    eext_object_event_callback_add(view_.GetWin(), EEXT_CALLBACK_BACK,
+        BackKeyCb, this);
+    view_.Show();
+    return true;
+  }
+
+  void OnTerminate() override {
+    eext_object_event_callback_del(view_.GetWin(), EEXT_CALLBACK_BACK,
+        BackKeyCb);
+
+    if (debug_info_initialized_) {
+      aul_debug_info_fini();
+      debug_info_initialized_ = false;
+    }
+
+    view_.ExitWidget();
+    widget_viewer_evas_fini();
+    view_.Fini();
+  }
+
+  void OnAppControl(const ReceivedAppControl& ctrl) override {
+    std::string widget_id = ctrl.GetExtraData(WIDGET_APPID);
+    std::string comp_type = GetCompType(widget_id);
+
+    if (comp_type == "watchapp") {
+      std::unique_ptr<char, decltype(free)*> cur_watch(
+          vconf_get_str(VCONFKEY_WMS_CLOCKS_SET_IDLE), free);
+      if (!widget_id.empty()) {
+        watch_pkgid_ = GetPkgidByAppid(widget_id);
+
+        if (cur_watch.get() != nullptr && watch_pkgid_ == cur_watch.get()) {
+          vconf_set_str(VCONFKEY_WMS_CLOCKS_SET_IDLE, DEFAULT_WATCH);
+        }
+      }
+
+      view_.Resize();
+      watch_holder_lifecycle_st lifecycle;
+      lifecycle.watch_holder_lifecycle_launched_cb = WatchLaunchedCb;
+      lifecycle.watch_holder_lifecycle_dead_cb = WatchDeadCb;
+      lifecycle.watch_holder_lifecycle_added_cb = WatchAddedCb;
+      lifecycle.watch_holder_lifecycle_removed_cb = WatchRemovedCb;
+      lifecycle.watch_holder_lifecycle_updated_cb = WatchUpdatedCb;
+      lifecycle.watch_holder_lifecycle_bound_cb = WatchBoundCb;
+      lifecycle.watch_holder_lifecycle_ambient_changed_cb =
+          WatchAmbientChangedCb;
+      lifecycle.watch_holder_lifecycle_ambient_event_cb = WatchAmbientEventCb;
+
+      if (watch_holder_ != NULL)
+        watch_holder_destroy(watch_holder_);
+
+      int ret = watch_holder_create(view_.GetWin(), lifecycle, &view_,
+          &watch_holder_);
+      if (ret != WATCH_HOLDER_ERROR_NONE) {
+        LOGE("Watch Holder Error:%d", ret);
+        return;
+      }
+
+      tizen_base::Bundle b;
+      bundle* raw = nullptr;
+      app_control_to_bundle(ctrl.GetHandle(), &raw);
+      if (!raw)
+        return;
+      tizen_base::Bundle app_control_b(raw, false, false);
+      SetBundleForWatchapp(app_control_b, b);
+      ret = watch_holder_launch(watch_holder_, false, widget_id.c_str(),
+          b.GetHandle());
+      if (ret < 0)
+        LOGE("Watch Holder Launch Error:%d", ret);
+      else
+        LOGD("Watch Holder Launch pid(%d)", ret);
+    } else {
+      std::string lazy_loader = ctrl.GetExtraData(LAZY_LOADER);
+      bundle* raw = nullptr;
+      app_control_to_bundle(ctrl.GetHandle(), &raw);
+      if (!raw)
+        return;
+      tizen_base::Bundle b(raw, false, false);
+      widget_service_set_sdk_util(b.GetHandle());
+      view_.ExitWidget();
+      if (ctrl.IsExtraDataArray(WIDGET_APPID)) {
+        auto arr = ctrl.GetExtraDataArray(WIDGET_APPID);
+        for (const auto& i : arr) {
+          view_.RunWidget(i, ctrl.GetHandle(), lazy_loader);
+        }
+      } else if (!widget_id.empty()) {
+        view_.RunWidget(widget_id, ctrl.GetHandle(), lazy_loader);
+      } else {
+        OnResume();
+        view_.Activate();
+      }
+    }
+  }
+
+  void OnResume() override {
+    widget_viewer_evas_notify_resumed_status_of_viewer();
+    watch_h watch;
+    int ret = watch_holder_get_current(watch_holder_, &watch);
+    if (ret == WATCH_HOLDER_ERROR_NONE) {
+      ret = watch_resume(watch);
+      if (ret != WATCH_HOLDER_ERROR_NONE) {
+        LOGE("watch_resume() failed: %d", ret);
+      }
+    }
+  }
+
+  void OnPause() override {
+    widget_viewer_evas_notify_paused_status_of_viewer();
+    watch_h watch;
+    int ret = watch_holder_get_current(watch_holder_, &watch);
+    if (ret == WATCH_HOLDER_ERROR_NONE) {
+      ret = watch_pause(watch);
+      if (ret != WATCH_HOLDER_ERROR_NONE) {
+        LOGE("watch_pause() failed: %d", ret);
+      }
+    }
+  }
+
+ private:
+  static void BackKeyCb(void* data, Evas_Object* obj, void* event_info) {
+    auto* app = reinterpret_cast<App*>(data);
+    app->Exit();
+  }
+
+  static void WatchLaunchedCb(watch_h watch, void* data) {
+    char* appid = NULL;
+    watch_get_appid(watch, &appid);
+    LOGD("watch(%s) launched", appid);
+    if (appid)
+      free(appid);
+  }
+
+  static void WatchDeadCb(watch_h watch, bool is_faulted, void* data) {
+    char* appid = NULL;
+    watch_get_appid(watch, &appid);
+    LOGD("watch(%s) dead (%d)", appid, is_faulted);
+    if (appid)
+      free(appid);
+  }
+
+  static void WatchAddedCb(watch_h watch, void* data) {
+    auto* view = reinterpret_cast<View*>(data);
+    if (watch == nullptr) {
+      LOGE("Wrong operation");
+      return;
+    }
+
+    char* appid = nullptr;
+    watch_get_appid(watch, &appid);
+    LOGD("watch added : %s", appid);
+    if (appid)
+      free(appid);
+
+    Evas_Object* clock = nullptr;
+    int ret = watch_get_current_image(watch, &clock);
+    if (ret == WATCH_HOLDER_ERROR_NONE) {
+      view->Resize();
+      evas_object_resize(clock, view->GetW(), view->GetH());
+      evas_object_show(clock);
+      view->Show();
+    } else {
+      LOGE("watch_get_current_image error:%d", ret);
+    }
+  }
+
+  static void WatchRemovedCb(watch_h watch, void* data) {
+    LOGD("watch removed");
+  }
+
+  static void WatchUpdatedCb(watch_h watch, Evas_Object* image, void* data) {
+    LOGD("watch updated");
+  }
+
+  static void WatchBoundCb(watch_h watch, void* data) {
+    LOGD("watch bound");
+  }
+
+  static void WatchAmbientChangedCb(bool enter, bundle* extra, void* data) {
+    LOGD("watch ambient changed (%d)", enter);
+  }
+
+  static void WatchAmbientEventCb(
+      watch_holder_ambient_event_e event, const char* sender, bundle* extra,
+      void* data) {
+    LOGD("watch ambient event (%d) from (%s)", event, sender);
+  }
+
+  static void  ClockVconfCb(keynode_t* node, void* data) {
+    auto* app = reinterpret_cast<::App*>(data);
+    std::unique_ptr<char, decltype(free)*> cur_watch(
+        vconf_get_str(VCONFKEY_WMS_CLOCKS_SET_IDLE), free);
+
+    LOGD("watch sdk [%s], home [%s]",
+        app->watch_pkgid_.c_str(), cur_watch.get());
+    if (cur_watch != nullptr && app->watch_pkgid_ == cur_watch.get()) {
+      app->Exit();
+      LOGW("same watch displayed on the other viewer EXIT");
+    }
+  }
+
+  void SetBundleForWatchapp(const tizen_base::Bundle& app_control_b,
+      tizen_base::Bundle& b) {
+    std::string value = app_control_b.GetString(AUL_K_DEBUG);
+    if (!value.empty()) {
+      b.Add(AUL_K_DEBUG, value);
+    }
+
+    value = app_control_b.GetString(AUL_K_SEQ_NUM);
+    if (!value.empty()) {
+      b.Add(AUL_K_SEQ_NUM, value);
+    }
+
+    value = app_control_b.GetString(AUL_K_WAIT_RESULT);
+    if (!value.empty()) {
+      b.Add(AUL_K_WAIT_RESULT, value);
+    }
+
+    value = app_control_b.GetString(AUL_K_CALLER_PID);
+    if (!value.empty()) {
+      b.Add(AUL_K_CALLER_PID, value);
+    } else {
+      b.Add(AUL_K_CALLER_PID, std::to_string(getpid()));
+    }
+
+    value = app_control_b.GetString(AUL_K_CALLER_UID);
+    if (!value.empty()) {
+      b.Add(AUL_K_CALLER_UID, value);
+    } else {
+      b.Add(AUL_K_CALLER_UID, std::to_string(getuid()));
+    }
+
+    value = app_control_b.GetString(AUL_K_SDK);
+    if (!value.empty()) {
+      aul_debug_info_init();
+      aul_debug_info_set(app_control_b.GetHandle(), b.GetHandle());
+      debug_info_initialized_ = true;
+      LOGD("util %s", value.c_str());
+    }
+  }
+
+  std::string GetPkgidByAppid(const std::string& appid) {
+    pkgmgrinfo_appinfo_h handle;
+    char* pkgid = nullptr;
+
+    int ret = pkgmgrinfo_appinfo_get_appinfo(appid.c_str(), &handle);
+    if (ret != PMINFO_R_OK)
+      return "";
+
+    ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
+    if (ret != PMINFO_R_OK) {
+      pkgmgrinfo_appinfo_destroy_appinfo(handle);
+      return "";
+    }
+
+    std::string ret_pkgid = pkgid;
+    pkgmgrinfo_appinfo_destroy_appinfo(handle);
+
+    return ret_pkgid;
+  }
+
+  std::string GetCompType(const std::string& widget_id) {
+    std::string comp_type;
+    pkgmgrinfo_appinfo_h app_info;
+
+    if (widget_id.empty())
+      return "";
+
+    LOGD("Loading a widget: [%s]", widget_id.c_str());
+    int ret = pkgmgrinfo_appinfo_get_appinfo(widget_id.c_str(), &app_info);
+    if (ret != PMINFO_R_OK) {
+      LOGE("fail to get %s appinfo %d", widget_id.c_str(), ret);
+    } else {
+      char* type = nullptr;
+      pkgmgrinfo_appinfo_get_component_type(app_info, &type);
+      if (type)
+        comp_type = type;
+      pkgmgrinfo_appinfo_destroy_appinfo(app_info);
+    }
+
+    return comp_type;
+  }
+
+ private:
+  bool debug_info_initialized_ = false;
+  watch_holder_h watch_holder_ = nullptr;
+  View view_;
+  std::string watch_pkgid_;
+};
+
+}  // namespace
+
+int main(int argc, char* argv[]) {
+  ::App app;
+
+  if (setenv("BUFMGR_LOCK_TYPE", "once", 0) < 0)
+    LOGE("setenv(BUFMGR_LOCK_TYPE) is failed");
+
+  if (setenv("BUFMGR_MAP_CACHE", "true", 0) < 0)
+    LOGE("setenv(BUFMGR_MAP_CACHE) is failed");
+
+  return app.Run(argc, argv);
+}
\ No newline at end of file
diff --git a/widget_viewer_sdk/src/view.cc b/widget_viewer_sdk/src/view.cc
new file mode 100644 (file)
index 0000000..ebfde01
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+* Copyright 2021 Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.1 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <app_control.hpp>
+#include <app_control_internal.h>
+#include <bundle_cpp.h>
+#include <dlog.h>
+#include <Elementary.h>
+#include <widget_errno.h>
+#include <widget_viewer_evas.h>
+
+#include "view.h"
+#include "widget.h"
+
+namespace {
+
+constexpr const char LAYOUT_EDJ[] = RESDIR"/edje/widget_viewer_sdk.edj";
+
+}  // namespace
+
+Evas_Object* View::GetBox() const {
+  return box_;
+}
+
+Evas_Object* View::GetWin() const {
+  return win_;
+}
+
+Evas_Object* View::GetLayout() const {
+  return layout_;
+}
+
+Evas_Object* View::GetBg() const {
+  return bg_;
+}
+
+int View::GetW() const {
+  return w_;
+}
+
+int View::GetH() const {
+  return h_;
+}
+
+Ecore_Timer* View::GetLongPressTimer() const {
+  return long_press_;
+}
+
+void View::SetLongPressTimer(Ecore_Timer* timer) {
+  long_press_ = timer;
+}
+
+bool View::Init() {
+  Evas_Object* scroller;
+  win_ = elm_win_add(nullptr, "Widget Viewer (SDK)", ELM_WIN_BASIC);
+  if (!win_) {
+    LOGD("Failed to create a window\n");
+    return false;
+  }
+
+  elm_app_base_scale_set(2.6);
+  elm_win_screen_size_get(win_, nullptr, nullptr, &w_, &h_);
+  LOGD("Window: %dx%d\n", w_, h_);
+
+  elm_win_alpha_set(win_, EINA_FALSE);
+  elm_win_indicator_mode_set(win_, ELM_WIN_INDICATOR_SHOW);
+
+  layout_ = elm_layout_add(win_);
+  if (!layout_) {
+    evas_object_del(box_);
+    evas_object_del(bg_);
+    evas_object_del(win_);
+    box_ = nullptr;
+    win_ = nullptr;
+    bg_ = nullptr;
+    return false;
+  }
+
+  if (elm_layout_file_set(layout_, LAYOUT_EDJ, "layout") != EINA_TRUE) {
+    LOGE("Failed to load an edje\n");
+    evas_object_del(bg_);
+    evas_object_del(layout_);
+    evas_object_del(win_);
+    bg_ = nullptr;
+    layout_ = nullptr;
+    win_ = nullptr;
+    return false;
+  }
+
+  evas_object_size_hint_weight_set(layout_, EVAS_HINT_EXPAND,
+      EVAS_HINT_EXPAND);
+  elm_win_resize_object_add(win_, layout_);
+  evas_object_show(layout_);
+  elm_object_signal_callback_add(layout_, "mouse,clicked,1", "widget,info,bg",
+      HideWidgetInfoCb, nullptr);
+
+  /* Initialize scroller */
+  scroller = elm_scroller_add(layout_);
+  evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
+      EVAS_HINT_EXPAND);
+  elm_win_resize_object_add(layout_, scroller);
+  evas_object_show(scroller);
+
+  /* Initialize box */
+  box_ = elm_box_add(scroller);
+  if (!box_) {
+    evas_object_del(bg_);
+    evas_object_del(win_);
+    bg_ = nullptr;
+    win_ = nullptr;
+    return false;
+  }
+  evas_object_size_hint_fill_set(box_, EVAS_HINT_FILL, EVAS_HINT_FILL);
+  evas_object_size_hint_weight_set(box_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+  elm_box_align_set(box_, 0.0, 0.0);
+
+  elm_object_content_set(scroller, box_);
+  elm_scroller_bounce_set(scroller, EINA_TRUE, EINA_FALSE);
+  elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF,
+      ELM_SCROLLER_POLICY_OFF);
+  elm_scroller_propagate_events_set(scroller, EINA_TRUE);
+  elm_scroller_page_relative_set(scroller, 0, 1);
+  elm_scroller_region_show(scroller, 50, 50, 200, 200);
+
+  elm_object_scroll_lock_x_set(scroller, EINA_FALSE);
+  elm_object_part_content_set(layout_, "widget", scroller);
+
+  /* WIDGET init */
+  widget_viewer_evas_set_option(WIDGET_VIEWER_EVAS_DIRECT_UPDATE, 1);
+  widget_viewer_evas_set_option(WIDGET_VIEWER_EVAS_EVENT_AUTO_FEED, 1);
+  widget_viewer_evas_init(win_);
+  return true;
+}
+
+void View::Show() {
+  evas_object_show(win_);
+}
+
+void View::Resize() {
+  evas_object_resize(win_, w_, h_);
+}
+
+void View::Activate() {
+  elm_win_activate(win_);
+}
+
+void View::Fini() {
+  if (win_) {
+    evas_object_del(win_);
+    win_ = nullptr;
+  }
+}
+
+int View::ExitWidget() {
+  int widget_cnt = widget_info_list_.size();
+  if (widget_cnt == 0)
+    return WIDGET_ERROR_NOT_EXIST;
+
+  widget_info_list_.clear();
+
+  elm_object_part_text_set(layout_, "widget,id", "");
+  elm_object_part_text_set(layout_, "widget,content,info", "");
+  elm_object_part_text_set(layout_, "widget,title", "");
+  elm_object_part_text_set(layout_, "widget,period", "");
+
+  return WIDGET_ERROR_NONE;
+}
+
+int View::LoadWidget(const char* widget_id, Widget* info) {
+  if(!info->Attach(widget_id)) {
+    delete info;
+    return WIDGET_ERROR_FAULT;
+  }
+
+  widget_info_list_.push_back(std::unique_ptr<Widget>(info));
+  return WIDGET_ERROR_NONE;
+}
+
+Eina_Bool View::LazyWidgetLoaderCb(void* data) {
+  Widget* info = reinterpret_cast<Widget*>(data);
+
+  LOGD("Lazy loader expired. load widget [%s]", info->GetId().c_str());
+  info->GetParent()->LoadWidget(info->GetId().c_str(), info);
+  info->GetParent()->lazy_widget_loader_ = nullptr;
+
+  return ECORE_CALLBACK_CANCEL;
+}
+
+void View::HideWidgetInfoCb(void* data, Evas_Object* obj,
+    const char* emission, const char* source) {
+  LOGD("Hide info panel");
+  Widget* info = reinterpret_cast<Widget*>(data);
+  elm_object_signal_emit(info->GetParent()->layout_, "hide", "info");
+}
+
+void View::RunWidget(const std::string& widget_id, app_control_h service,
+    const std::string& lazy_loader) {
+  Widget* info = new Widget(this, widget_id,
+      WIDGET_VIEWER_EVAS_DEFAULT_PERIOD, 20);
+
+  info->Prepare(service);
+  if (lazy_widget_loader_) {
+    Widget* data = reinterpret_cast<Widget*>(ecore_timer_del(
+        lazy_widget_loader_));
+    delete data;
+  }
+
+  if (lazy_loader == "true") {
+    LOGD("Load a watch after some time later (%lf)", lazy_watch_time_);
+    lazy_widget_loader_ = ecore_timer_add(lazy_watch_time_,
+        LazyWidgetLoaderCb, info);
+    if (!lazy_widget_loader_) {
+      LOGE("Unable to fire the timer");
+      LazyWidgetLoaderCb(info);
+    }
+  } else {
+    LOGD("Immediately loads the watch[%s]", widget_id.c_str());
+    LazyWidgetLoaderCb(info);
+  }
+}
\ No newline at end of file
diff --git a/widget_viewer_sdk/src/widget.cc b/widget_viewer_sdk/src/widget.cc
new file mode 100644 (file)
index 0000000..5705fea
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+* Copyright 2021 Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.1 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <app_control.hpp>
+#include <app_control_internal.h>
+#include <bundle_cpp.h>
+#include <dlog.h>
+#include <widget_errno.h>
+#include <widget_viewer_evas.h>
+
+#include "view.h"
+#include "widget.h"
+
+namespace {
+
+constexpr const double LONG_PRESS = 1.0f;
+constexpr const char LAYOUT_EDJ[] = RESDIR"/edje/widget_viewer_sdk.edj";
+
+struct WidgetSizeListItem {
+  Widget* info;
+  int idx;
+};
+
+}  // namespace
+
+Widget::Widget(View* parent, std::string widget_id, double period,
+    int count_of_size_type)
+    : parent_(parent), widget_id_(std::move(widget_id)), period_(period),
+      count_of_size_type_(count_of_size_type) {}
+
+Widget::Widget(Widget&& info) noexcept {
+  parent_ = info.parent_;
+  widget_id_ = std::move(info.widget_id_);
+  content_info_ = std::move(info.content_info_);
+  title_ = std::move(info.title_);
+  period_ = info.period_;
+  widget_ = info.widget_;
+  info.widget_ = nullptr;
+  widget_layout_ = info.widget_layout_;
+  info.widget_layout_ = nullptr;
+  size_types_ = info.size_types_;
+  info.size_types_ = nullptr;
+  count_of_size_type_ = info.count_of_size_type_;
+}
+
+Widget& Widget::operator = (Widget&& info) noexcept {
+  if (this == &info)
+    return *this;
+  if (widget_layout_)
+    elm_box_unpack(parent_->GetBox(), widget_layout_);
+  if (widget_)
+    evas_object_del(widget_);
+  if (widget_layout_)
+    evas_object_del(widget_layout_);
+  free(size_types_);
+
+  parent_ = info.parent_;
+  widget_id_ = std::move(info.widget_id_);
+  content_info_ = std::move(info.content_info_);
+  title_ = std::move(info.title_);
+  period_ = info.period_;
+  widget_ = info.widget_;
+  info.widget_ = nullptr;
+  widget_layout_ = info.widget_layout_;
+  info.widget_layout_ = nullptr;
+  size_types_ = info.size_types_;
+  info.size_types_ = nullptr;
+  count_of_size_type_ = info.count_of_size_type_;
+  return *this;
+}
+
+Widget::~Widget() {
+  const char* tmp = widget_viewer_evas_get_widget_id(widget_);
+  LOGD("Unload previous widget: %s", tmp);
+
+  if (widget_layout_)
+    elm_box_unpack(parent_->GetBox(), widget_layout_);
+  if (widget_)
+    evas_object_del(widget_);
+  if (widget_layout_)
+    evas_object_del(widget_layout_);
+  free(size_types_);
+}
+
+const std::string& Widget::GetId() const {
+  return widget_id_;
+}
+
+const std::string& Widget::GetContent() const {
+  return content_info_;
+}
+
+const std::string& Widget::GetTitle() const {
+  return title_;
+}
+
+double Widget::GetPeriod() const {
+  return period_;
+}
+
+View* Widget::GetParent() const {
+  return parent_;
+}
+
+bool Widget::Attach(const char* widget_id) {
+  Evas_Object* bg = nullptr;
+  int w = 0;
+  int h = 0;
+  int i;
+
+  for (i = 0; i < count_of_size_type_; i++) {
+    if (widget_service_get_size((widget_size_type_e)(size_types_[i]),
+        &w, &h) == WIDGET_ERROR_NONE && w != 0 && h != 0)
+      break;
+  }
+
+  widget_layout_ = elm_layout_add(parent_->GetWin());
+  elm_layout_file_set(widget_layout_, LAYOUT_EDJ, "widget");
+  evas_object_size_hint_weight_set(widget_layout_, EVAS_HINT_EXPAND,
+      EVAS_HINT_EXPAND);
+  evas_object_size_hint_align_set(widget_, 0.0, 0.5);
+  evas_object_show(widget_layout_);
+
+  bg = evas_object_rectangle_add(evas_object_evas_get(parent_->GetLayout()));
+  evas_object_resize(bg, w, h);
+  evas_object_size_hint_min_set(bg, w, h);
+  evas_object_color_set(bg, 255, 255, 255, 0);
+  evas_object_show(bg);
+  elm_object_part_content_set(widget_layout_, "bg", bg);
+
+  widget_ = widget_viewer_evas_add_widget(parent_->GetWin(), widget_id,
+      content_info_.c_str(), period_);
+  if (!widget_) {
+    UpdateMessage("Failed to create a new widget");
+    return false;
+  }
+
+  LOGD("Resize the widget(%s) to [%X] %dx%d", widget_id, size_types_[0], w, h);
+  evas_object_smart_callback_add(widget_, WIDGET_SMART_SIGNAL_UPDATED,
+      UpdatedCb, this);
+  evas_object_smart_callback_add(widget_,
+      WIDGET_SMART_SIGNAL_EXTRA_INFO_UPDATED, ExtraUpdatedCb, this);
+  evas_object_smart_callback_add(widget_,
+      WIDGET_SMART_SIGNAL_PERIOD_CHANGED, PeriodChangedCb, this);
+  evas_object_smart_callback_add(widget_,
+      WIDGET_SMART_SIGNAL_WIDGET_CREATED, WidgetCreatedCb, this);
+  evas_object_smart_callback_add(widget_,
+      WIDGET_SMART_SIGNAL_WIDGET_CREATE_ABORTED, WidgetCreateAbortedCb, this);
+
+  evas_object_resize(widget_, w, h);
+  evas_object_size_hint_align_set(widget_, 0.0, 0.5);
+  evas_object_show(widget_);
+  elm_object_part_content_set(widget_layout_, "widget", widget_);
+
+  elm_box_pack_end(parent_->GetBox(), widget_layout_);
+  elm_object_part_text_set(parent_->GetLayout(), "widget,id", widget_id);
+
+  UpdateMessage(nullptr);
+  elm_box_padding_set(parent_->GetBox(), 0, 5);
+
+  LOGD("Found valid size[%X]: %dx%d", size_types_[i], w, h);
+  evas_object_event_callback_add(widget_, EVAS_CALLBACK_MOUSE_DOWN,
+      LayoutDownCb, this);
+  evas_object_event_callback_add(widget_, EVAS_CALLBACK_MOUSE_UP,
+      LayoutUpCb, this);
+  return true;
+}
+
+void Widget::UpdatedCb(void* data, Evas_Object* obj, void* event_info) {
+  LOGD("Widget updated");
+}
+
+void Widget::ExtraUpdatedCb(void* data, Evas_Object* obj,
+    void* event_info) {
+  Widget* info = reinterpret_cast<Widget*>(data);
+
+  const char* str = widget_viewer_evas_get_title_string(obj);
+  if (str) {
+    info->title_ = str;
+    elm_object_part_text_set(info->parent_->GetLayout(), "widget,title",
+        info->title_.c_str());
+  }
+
+  str = widget_viewer_evas_get_content_info(obj);
+  if (str) {
+    info->content_info_ = str;
+    elm_object_part_text_set(info->parent_->GetLayout(), "widget,content,info",
+        info->content_info_.c_str());
+    LOGD("Content updated: [%s]", info->content_info_.c_str());
+  }
+}
+
+void Widget::WidgetCreateAbortedCb(void* data, Evas_Object* obj,
+    void* event_info) {
+  Widget* info = reinterpret_cast<Widget*>(data);
+  info->UpdateMessage("Create aborted");
+}
+
+void Widget::WidgetCreatedCb(void* data, Evas_Object* obj,
+    void* event_info) {
+  PeriodChangedCb(data, obj, nullptr);
+  ExtraUpdatedCb(data, obj, nullptr);
+}
+
+void Widget::PeriodChangedCb(void* data, Evas_Object* obj,
+    void* event_info) {
+  char buffer[96];
+  Widget* info = reinterpret_cast<Widget*>(data);
+
+  info->period_ = widget_viewer_evas_get_period(obj);
+  snprintf(buffer, sizeof(buffer), "%lf", info->period_);
+  elm_object_part_text_set(info->parent_->GetLayout(), "widget,period", buffer);
+  LOGD("Period updated: %s", buffer);
+}
+
+void Widget::LayoutDownCb(void* data, Evas* e, Evas_Object* obj,
+    void* event_info) {
+  Widget* info = reinterpret_cast<Widget*>(data);
+
+  if (info->parent_->GetLongPressTimer()) {
+    ecore_timer_del(info->parent_->GetLongPressTimer());
+    info->parent_->SetLongPressTimer(nullptr);
+  }
+
+  info->parent_->SetLongPressTimer(ecore_timer_add(LONG_PRESS,
+      ShowWidgetInfoCb, data));
+  if (!info->parent_->GetLongPressTimer())
+    LOGE("Failed to add a timer");
+}
+
+void Widget::LayoutUpCb(void* data, Evas* e, Evas_Object* obj,
+    void* event_info) {
+  Widget* info = reinterpret_cast<Widget*>(data);
+  if (info->parent_->GetLongPressTimer()) {
+    ecore_timer_del(info->parent_->GetLongPressTimer());
+    info->parent_->SetLongPressTimer(nullptr);
+  }
+}
+
+Eina_Bool Widget::ShowWidgetInfoCb(void* data) {
+  LOGD("Show info panel\n");
+  int w;
+  int h;
+  Evas_Object *size_list;
+  Elm_Object_Item *elm_item;
+  Widget *info = (Widget *)data;
+  static Elm_Genlist_Item_Class cls = {
+    .item_style = "1text.1icon",
+    .func = {
+      .text_get = ListItemTextGetCb,
+      .content_get = ListItemContentGetCb,
+      .state_get = NULL,
+      .del = NULL,
+    }
+  };
+
+  LOGD("======== %d", info->count_of_size_type_);
+
+  if (info->count_of_size_type_ <= 1) {
+    elm_object_signal_emit(info->parent_->GetLayout(), "hide", "size,list");
+    return ECORE_CALLBACK_CANCEL;
+  } else {
+    elm_object_signal_emit(info->parent_->GetLayout(), "show", "size,list");
+  }
+
+  size_list = elm_object_part_content_get(info->parent_->GetLayout(),
+      "widget,size,list");
+  if (size_list) {
+    elm_genlist_clear(size_list);
+  } else {
+    size_list = elm_genlist_add(info->parent_->GetWin());
+    if (!size_list) {
+      LOGE("Failed to create a genlist");
+      return ECORE_CALLBACK_RENEW;
+    }
+
+    elm_object_part_content_set(info->parent_->GetLayout(), "widget,size,list",
+        size_list);
+  }
+
+  LOGD("Dump supported size types");
+  for (int i = 0; i < info->count_of_size_type_; i++) {
+    if (widget_service_get_size((widget_size_type_e)(info->size_types_[i]),
+        &w, &h) != WIDGET_ERROR_NONE || w == 0 || h == 0) {
+      LOGD("[%X] is not supported (%dx%d)", info->size_types_[i], w, h);
+      continue;
+    }
+    LOGD("Size[%X]", info->size_types_[i]);
+
+    auto* item = new WidgetSizeListItem();
+    item->info = info;
+    item->idx = i;
+    elm_item = elm_genlist_item_append(size_list, &cls, (void *)item, nullptr,
+        ELM_GENLIST_ITEM_NONE, ListItemClickedCb, (void *)item);
+    if (!elm_item)
+      LOGD("Failed to add a new size elm_item");
+  }
+  LOGD("End of a dump");
+  elm_object_signal_emit(info->parent_->GetLayout(), "show", "info");
+
+  info->parent_->SetLongPressTimer(nullptr);
+  return ECORE_CALLBACK_CANCEL;
+}
+
+char* Widget::ListItemTextGetCb(void* data, Evas_Object* obj,
+    const char* part) {
+  char buffer[256];
+  int ret;
+  int w;
+  int h;
+  WidgetSizeListItem *item = (WidgetSizeListItem *)data;
+
+  ret = widget_service_get_size(
+      (widget_size_type_e)(item->info->size_types_[item->idx]), &w, &h);
+  if (ret != WIDGET_ERROR_NONE)
+    return strdup("Invalid");
+
+  snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
+  LOGD("Size: [%s]", buffer);
+  return strdup(buffer);
+}
+
+Evas_Object* Widget::ListItemContentGetCb(void* data, Evas_Object* obj,
+    const char* part) {
+  Evas_Object* icon = nullptr;
+  WidgetSizeListItem* item = reinterpret_cast<WidgetSizeListItem*>(data);
+  auto* info = item->info;
+  const char* widget_id = widget_viewer_evas_get_widget_id(info->widget_);
+  char* icon_filename = widget_service_get_preview_image_path(widget_id,
+      widget_size_type_e(info->size_types_[item->idx]));
+
+  if (icon_filename) {
+    icon = elm_icon_add(info->parent_->GetWin());
+    if (icon) {
+      elm_image_file_set(icon, icon_filename, NULL);
+      elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
+      evas_object_size_hint_max_set(icon, 100, 100);
+      LOGD("Icon: %s", icon_filename);
+    }
+    free(icon_filename);
+  } else {
+    icon = NULL;
+  }
+
+  return icon;
+}
+
+void Widget::ListItemClickedCb(void* data, Evas_Object* obj,
+    void* event_info) {
+  int w;
+  int h;
+  auto* item = reinterpret_cast<WidgetSizeListItem*>(data);
+
+  if (item == nullptr)
+    return;
+
+  if (widget_service_get_size(
+      (widget_size_type_e)(item->info->size_types_[item->idx]),
+      &w, &h) != WIDGET_ERROR_NONE) {
+    return;
+  }
+
+  evas_object_resize(item->info->widget_, w, h);
+  evas_object_size_hint_min_set(item->info->widget_, w, h);
+  evas_object_size_hint_max_set(item->info->widget_, w, h);
+}
+
+void Widget::UpdateMessage(const char* fmt, ...) {
+  if (!fmt) {
+    elm_object_signal_emit(parent_->GetLayout(), "hide", "message");
+  } else {
+    va_list ap;
+    char buffer[1024];
+
+    va_start(ap, fmt);
+    vsnprintf(buffer, sizeof(buffer) - 1, fmt, ap);
+    va_end(ap);
+
+    elm_object_part_text_set(parent_->GetLayout(), "message", buffer);
+    elm_object_signal_emit(parent_->GetLayout(), "show", "message");
+    LOGE("%s", buffer);
+  }
+}
+
+int Widget::Prepare(app_control_h control) {
+  bundle* b;
+
+  if (app_control_export_as_bundle(control, &b) == APP_CONTROL_ERROR_NONE) {
+    tizen_base::Bundle kb(b, false, true);
+    auto raw = kb.ToRaw();
+    content_info_ = reinterpret_cast<const char*>(raw.first.get());
+    LOGD("Encoded content_info: [%s]", content_info_.c_str());
+  }
+
+  count_of_size_type_ = 20;
+  int ret = widget_service_get_supported_size_types(widget_id_.c_str(),
+      &count_of_size_type_, &size_types_);
+  if (ret != WIDGET_ERROR_NONE)
+    LOGE("Failed to load an widget");
+
+  LOGD("[%s] %d", widget_id_.c_str(), count_of_size_type_);
+  return ret;
+}
\ No newline at end of file