Refactor appcore-widget 36/254936/29
authorjh9216.park <jh9216.park@samsung.com>
Thu, 11 Mar 2021 01:29:38 +0000 (20:29 -0500)
committerChanggyu Choi <changyu.choi@samsung.com>
Fri, 7 Jan 2022 07:22:39 +0000 (16:22 +0900)
 - Use app-core for C++

Requires:
 - https://review.tizen.org/gerrit/#/c/platform/core/appfw/app-core/+/247812/
 - https://review.tizen.org/gerrit/#/c/platform/core/api/app-common/+/253882/

Change-Id: Ib0b43977c3334cb3942f26bf93c42de933448c24
Signed-off-by: jh9216.park <jh9216.park@samsung.com>
31 files changed:
CMakeLists.txt
include/widget_app.h [changed mode: 0755->0644]
include/widget_base.h
include/widget_base.hh [new file with mode: 0644]
packaging/appcore-widget.manifest [moved from appcore-widget.manifest with 100% similarity]
packaging/appcore-widget.spec
src/base/CMakeLists.txt
src/base/appcore-widget-base.pc.in [moved from appcore-widget-base.pc.in with 90% similarity]
src/base/widget_base.cc [new file with mode: 0644]
src/base/widget_base_legacy.c [moved from src/base/widget_base.c with 99% similarity]
src/common/export_private.hh [new file with mode: 0644]
src/common/log_private.hh [new file with mode: 0644]
src/efl_base/CMakeLists.txt
src/efl_base/capi-appfw-widget-application.pc.in [moved from capi-appfw-widget-application.pc.in with 100% similarity]
src/efl_base/widget-log.h [deleted file]
src/efl_base/widget-private.h [deleted file]
src/efl_base/widget_app.c [deleted file]
src/efl_base/widget_app.cc [new file with mode: 0644]
src/efl_base/widget_app_internal.c [deleted file]
src/efl_base/widget_error.c [deleted file]
test/unit_tests/CMakeLists.txt
test/unit_tests/mock/app_common_mock.h
test/unit_tests/mock/appcore_multiwindow_base_mock.cc
test/unit_tests/mock/appcore_multiwindow_base_mock.h
test/unit_tests/mock/aul_mock.cc
test/unit_tests/mock/aul_mock.h
test/unit_tests/mock/elm_mock.cc
test/unit_tests/mock/widget_service_mock.cc [new file with mode: 0644]
test/unit_tests/mock/widget_service_mock.h [new file with mode: 0644]
test/unit_tests/test_widget_app.cc
test/unit_tests/test_widget_app_cpp.cc

index 7dc63e6..a35ef8d 100644 (file)
@@ -8,12 +8,15 @@ SET(LIBDIR ${LIB_INSTALL_DIR})
 SET(INCLUDEDIR "\${prefix}/include")
 
 ## Compiler flags
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -g -Wall -Werror")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -Werror")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
 
 ## Linker flags
 SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed,--gc-sections -pie")
 
-SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
 
 ## Targets
 SET(TARGET_WIDGET_BASE "appcore-widget-base")
@@ -28,26 +31,21 @@ INCLUDE(ApplyPkgConfig)
 ADD_DEFINITIONS("-DPROJECT_TAG=\"TIZEN_APPCORE_WIDGET\"")
 
 ## Find all needed packages once
+PKG_CHECK_MODULES(APPCORE_COMMON_DEPS REQUIRED app-core-cpp)
+PKG_CHECK_MODULES(APPCORE_MULTIWINDOW_DEPS REQUIRED app-core-multi-window-cpp)
+PKG_CHECK_MODULES(APPCORE_MULTIWINDOW_OLD_DEPS REQUIRED appcore-multiwindow)
+PKG_CHECK_MODULES(AUL_DEP REQUIRED aul)
 PKG_CHECK_MODULES(BUNDLE_DEPS REQUIRED bundle)
+PKG_CHECK_MODULES(CAPI_APP_COMMON_DEP REQUIRED capi-appfw-app-common)
 PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
-PKG_CHECK_MODULES(APPCORE_COMMON_DEPS REQUIRED appcore-common)
-PKG_CHECK_MODULES(WIDGET_SERVICE_DEPS REQUIRED widget_service)
-PKG_CHECK_MODULES(SYSTEM_INFO_DEPS REQUIRED capi-system-info)
 PKG_CHECK_MODULES(ECORE_WL2_DEPS REQUIRED ecore-wl2)
-PKG_CHECK_MODULES(SCREEN_CONNECTOR_PROVIDER_DEPS REQUIRED screen_connector_provider)
-PKG_CHECK_MODULES(APPCORE_MULTIWINDOW_DEPS REQUIRED appcore-multiwindow)
-PKG_CHECK_MODULES(AUL_DEP REQUIRED aul)
 PKG_CHECK_MODULES(ELEMENTARY_DEP REQUIRED elementary)
-PKG_CHECK_MODULES(CAPI_APP_COMMON_DEP REQUIRED capi-appfw-app-common)
 PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0)
-PKG_CHECK_MODULES(GOBJECT_DEPS REQUIRED gobject-2.0)
 PKG_CHECK_MODULES(GMOCK_DEPS REQUIRED gmock)
+PKG_CHECK_MODULES(GOBJECT_DEPS REQUIRED gobject-2.0)
+PKG_CHECK_MODULES(SCREEN_CONNECTOR_PROVIDER_DEPS REQUIRED screen_connector_provider)
+PKG_CHECK_MODULES(SYSTEM_INFO_DEPS REQUIRED capi-system-info)
+PKG_CHECK_MODULES(WIDGET_SERVICE_DEPS REQUIRED widget_service)
 
 ADD_SUBDIRECTORY(src)
 ADD_SUBDIRECTORY(test)
-
-
-
-
-
-
old mode 100755 (executable)
new mode 100644 (file)
index 80e1a57..769c566 100644 (file)
 extern "C" {
 #endif
 
+/* Deprecated APIs. Please use widget_base.hh */
+
+#define WIDGE_BASE_DEPRECATED __attribute__ ((deprecated))
+
 typedef enum widget_base_destroy_type {
        WIDGET_BASE_DESTROY_TYPE_PERMANENT = 0x00,
        WIDGET_BASE_DESTROY_TYPE_TEMPORARY = 0x01,
@@ -85,50 +89,50 @@ typedef struct _widget_base_class {
 
 typedef bool (*widget_base_instance_cb)(widget_base_instance_h instance, void *data);
 
-int widget_base_foreach_context(widget_base_instance_cb cb, void *data);
-int widget_base_terminate_context(widget_base_instance_h instance_h);
+int widget_base_foreach_context(widget_base_instance_cb cb, void *data) WIDGE_BASE_DEPRECATED;
+int widget_base_terminate_context(widget_base_instance_h instance_h) WIDGE_BASE_DEPRECATED;
 int widget_base_add_event_handler(app_event_handler_h *event_handler,
                                        app_event_type_e event_type,
                                        app_event_cb callback,
-                                       void *user_data);
+                                       void *user_data) WIDGE_BASE_DEPRECATED;
 int widget_base_remove_event_handler(app_event_handler_h
-                                               event_handler);
+                                               event_handler) WIDGE_BASE_DEPRECATED;
 int widget_base_context_set_content_info(widget_base_instance_h instance_h,
-               bundle *content_info);
-int widget_base_context_get_tag(widget_base_instance_h instance_h, void **tag);
-int widget_base_context_set_tag(widget_base_instance_h instance_h, void *tag);
-void *widget_base_context_get_user_data(widget_base_instance_h instance_h);
+               bundle *content_info) WIDGE_BASE_DEPRECATED;
+int widget_base_context_get_tag(widget_base_instance_h instance_h, void **tag) WIDGE_BASE_DEPRECATED;
+int widget_base_context_set_tag(widget_base_instance_h instance_h, void *tag) WIDGE_BASE_DEPRECATED;
+void *widget_base_context_get_user_data(widget_base_instance_h instance_h) WIDGE_BASE_DEPRECATED;
 int widget_base_context_set_user_data(widget_base_instance_h instance_h,
-               void *user_data);
-int widget_base_context_get_id(widget_base_instance_h instance_h, char **id);
-const char *widget_base_get_viewer_endpoint(void);
-int widget_base_init(widget_base_ops ops, int argc, char **argv, void *data);
-int widget_base_on_create(void);
-int widget_base_on_terminate(void);
-int widget_base_on_init(int argc, char **argv);
-void widget_base_on_finish(void);
-void widget_base_on_run(void);
-void widget_base_on_exit(void);
-int widget_base_on_trim_memory(void);
-widget_base_ops widget_base_get_default_ops(void);
-void widget_base_fini(void);
-int widget_base_exit(void);
+               void *user_data) WIDGE_BASE_DEPRECATED;
+int widget_base_context_get_id(widget_base_instance_h instance_h, char **id) WIDGE_BASE_DEPRECATED;
+const char *widget_base_get_viewer_endpoint(void) WIDGE_BASE_DEPRECATED;
+int widget_base_init(widget_base_ops ops, int argc, char **argv, void *data) WIDGE_BASE_DEPRECATED;
+int widget_base_on_create(void) WIDGE_BASE_DEPRECATED;
+int widget_base_on_terminate(void) WIDGE_BASE_DEPRECATED;
+int widget_base_on_init(int argc, char **argv) WIDGE_BASE_DEPRECATED;
+void widget_base_on_finish(void) WIDGE_BASE_DEPRECATED;
+void widget_base_on_run(void) WIDGE_BASE_DEPRECATED;
+void widget_base_on_exit(void) WIDGE_BASE_DEPRECATED;
+int widget_base_on_trim_memory(void) WIDGE_BASE_DEPRECATED;
+widget_base_ops widget_base_get_default_ops(void) WIDGE_BASE_DEPRECATED;
+void widget_base_fini(void) WIDGE_BASE_DEPRECATED;
+int widget_base_exit(void) WIDGE_BASE_DEPRECATED;
 int widget_base_context_window_bind(
                widget_base_instance_h instance_h, const char *id,
-               Ecore_Wl2_Window *wl_win);
+               Ecore_Wl2_Window *wl_win) WIDGE_BASE_DEPRECATED;
 int widget_base_class_on_create(widget_base_instance_h instance_h,
-               bundle *content, int w, int h);
-int widget_base_class_on_pause(widget_base_instance_h instance_h);
-int widget_base_class_on_resume(widget_base_instance_h instance_h);
+               bundle *content, int w, int h) WIDGE_BASE_DEPRECATED;
+int widget_base_class_on_pause(widget_base_instance_h instance_h) WIDGE_BASE_DEPRECATED;
+int widget_base_class_on_resume(widget_base_instance_h instance_h) WIDGE_BASE_DEPRECATED;
 int widget_base_class_on_resize(widget_base_instance_h instance_h,
-               int w, int h);
+               int w, int h) WIDGE_BASE_DEPRECATED;
 int widget_base_class_on_update(widget_base_instance_h instance_h,
-               bundle *content, int force);
+               bundle *content, int force) WIDGE_BASE_DEPRECATED;
 int widget_base_class_on_destroy(widget_base_instance_h instance_h,
-               widget_base_destroy_type_e reason, bundle *content);
-widget_base_class widget_base_class_get_default(void);
+               widget_base_destroy_type_e reason, bundle *content) WIDGE_BASE_DEPRECATED;
+widget_base_class widget_base_class_get_default(void) WIDGE_BASE_DEPRECATED;
 widget_base_class *widget_base_class_add(widget_base_class cls,
-               const char *class_id, void *class_data);
+               const char *class_id, void *class_data) WIDGE_BASE_DEPRECATED;
 
 #ifdef __cplusplus
 }
diff --git a/include/widget_base.hh b/include/widget_base.hh
new file mode 100644 (file)
index 0000000..8f0c043
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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_BASE_HH_
+#define WIDGET_BASE_HH_
+
+#include <app_common.h>
+
+#include <memory>
+#include <string>
+
+#include <app_core_multi_window_base.hh>
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+namespace tizen_cpp {
+
+class EXPORT_API WidgetBase : public AppCoreMultiWindowBase {
+ public:
+  WidgetBase();
+  virtual ~WidgetBase();
+
+  std::string GetViewerEndpoint();
+  void Run(int argc, char** argv) override;
+  void Exit() override;
+  int OnControl(tizen_base::Bundle b) override;
+  int OnCreate() override;
+  int OnTerminate() override;
+  int OnReceive(aul_type type, tizen_base::Bundle b) override;
+  void ExitContext(std::shared_ptr<Context> context) override;
+
+ protected:
+  void Dispose() override;
+
+ private:
+  friend class WidgetContext;
+  class Impl;
+  std::unique_ptr<Impl> impl_;
+};
+
+class EXPORT_API WidgetContext : public AppCoreMultiWindowBase::Context {
+ public:
+  enum class DestroyType {
+    PERMANENT,
+    TEMPORARY
+  };
+
+  WidgetContext(std::string context_id, std::string inst_id,
+      AppCoreMultiWindowBase* app);
+  virtual ~WidgetContext();
+  virtual bool OnCreate(const tizen_base::Bundle& contents, int w, int h) = 0;
+  virtual void OnDestroy(DestroyType reason,
+      const tizen_base::Bundle& contents) = 0;
+  virtual void OnPause();
+  virtual void OnResume();
+  virtual void OnResize(int w, int h);
+  virtual void OnUpdate(const tizen_base::Bundle& contents, bool force);
+  void ExitAsync();
+  int SetContents(const tizen_base::Bundle& contents);
+  int WindowBind(std::string id, Ecore_Wl2_Window* wl_win);
+
+ private:
+  using AppCoreMultiWindowBase::Context::WindowBind;
+  void OnCreate() override;
+  void OnTerminate() override;
+
+ private:
+  friend class WidgetBase;
+  class Impl;
+  std::unique_ptr<Impl> impl_;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // WIDGET_BASE_HH_
index b84fa32..a750a1a 100644 (file)
@@ -4,15 +4,17 @@ Version:    1.3.14
 Release:    1
 Group:      Application Framework/Libraries
 License:    Apache-2.0
-Source0:    appcore-widget-%{version}.tar.gz
+Source0:    %{name}-%{version}.tar.gz
+Source1001: %{name}.manifest
 BuildRequires:  pkgconfig(aul)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(elementary)
-BuildRequires:  pkgconfig(appcore-common)
+BuildRequires:  pkgconfig(app-core-cpp)
 BuildRequires:  pkgconfig(capi-appfw-app-common)
 BuildRequires:  pkgconfig(widget_service)
 BuildRequires:  pkgconfig(capi-system-info)
 BuildRequires:  pkgconfig(ecore-wl2)
+BuildRequires:  pkgconfig(app-core-multi-window-cpp)
 BuildRequires:  pkgconfig(appcore-multiwindow)
 BuildRequires:  pkgconfig(screen_connector_provider)
 BuildRequires:  pkgconfig(gmock)
@@ -71,6 +73,7 @@ gcov objects of a widget application library
 
 %prep
 %setup -q
+cp %{SOURCE1001} .
 
 %build
 %if 0%{?gcov:1}
@@ -99,9 +102,6 @@ mkdir -p %{buildroot}%{_datadir}/gcov/obj
 install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj
 %endif
 
-mkdir -p %{buildroot}%{_libdir}/pkgconfig
-cp capi-appfw-widget-application.pc %{buildroot}%{_libdir}/pkgconfig
-
 %check
 export LD_LIBRARY_PATH=../../src/base:../../src/efl_base
 ctest -V
@@ -123,11 +123,11 @@ install -m 0644 appcore-widget.zip %{buildroot}%{_datadir}/gcov/
 %license LICENSE
 
 %files -n appcore-widget-base-devel
+/usr/include/appfw/widget_base.hh
 /usr/include/appfw/widget_base.h
 %{_libdir}/pkgconfig/appcore-widget-base.pc
 %{_libdir}/libappcore-widget-base.so
 
-
 %files -n appcore-widget
 %manifest %{name}.manifest
 %defattr(-,root,root,-)
index 13314c5..eccf4f2 100644 (file)
@@ -4,8 +4,12 @@ ADD_LIBRARY(${TARGET_WIDGET_BASE} SHARED ${WIDGET_BASE_SRCS})
 SET_TARGET_PROPERTIES(${TARGET_WIDGET_BASE} PROPERTIES SOVERSION ${MAJORVER})
 SET_TARGET_PROPERTIES(${TARGET_WIDGET_BASE} PROPERTIES VERSION ${FULLVER})
 
-TARGET_INCLUDE_DIRECTORIES(${TARGET_WIDGET_BASE} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../)
-TARGET_INCLUDE_DIRECTORIES(${TARGET_WIDGET_BASE} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include/)
+TARGET_INCLUDE_DIRECTORIES(${TARGET_WIDGET_BASE} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}/
+  ${CMAKE_CURRENT_SOURCE_DIR}/../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../include/
+  ${CMAKE_CURRENT_SOURCE_DIR}/../common/)
 
 APPLY_PKG_CONFIG(${TARGET_WIDGET_BASE} PUBLIC
   DLOG_DEPS
@@ -15,9 +19,13 @@ APPLY_PKG_CONFIG(${TARGET_WIDGET_BASE} PUBLIC
   ECORE_WL2_DEPS
   SCREEN_CONNECTOR_PROVIDER_DEPS
   APPCORE_MULTIWINDOW_DEPS
+  APPCORE_MULTIWINDOW_OLD_DEPS
   CAPI_APP_COMMON_DEP
 )
 
-CONFIGURE_FILE(../../appcore-widget-base.pc.in ../../appcore-widget-base.pc @ONLY)
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/appcore-widget-base.pc.in
+  ${CMAKE_CURRENT_SOURCE_DIR}/appcore-widget-base.pc @ONLY)
 INSTALL(TARGETS ${TARGET_WIDGET_BASE} DESTINATION ${LIB_INSTALL_DIR})
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../appcore-widget-base.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/appcore-widget-base.pc
+  DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/appfw/)
similarity index 90%
rename from appcore-widget-base.pc.in
rename to src/base/appcore-widget-base.pc.in
index f2d3717..53779bf 100644 (file)
@@ -8,6 +8,6 @@ includedir=@INCLUDEDIR@
 Name: appcore-widget-base
 Description: widget base library
 Version: @VERSION@
-Requires: aul dlog capi-appfw-app-common widget_service appcore-multiwindow
+Requires: aul dlog capi-appfw-app-common widget_service appcore-multiwindow app-core-multi-window-cpp
 Libs: -L${libdir} -lappcore-widget-base
 Cflags: -I${includedir} -I${includedir}/appfw
diff --git a/src/base/widget_base.cc b/src/base/widget_base.cc
new file mode 100644 (file)
index 0000000..45ec082
--- /dev/null
@@ -0,0 +1,781 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 <aul.h>
+#include <aul_app_com.h>
+#include <aul_widget.h>
+#include <bundle_internal.h>
+#include <dlog.h>
+#include <glib.h>
+#include <screen_connector_provider.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <widget_errno.h>
+#include <widget_instance.h>
+
+#include <app_core_multi_window_base.hh>
+
+#include "common/log_private.hh"
+#include "include/widget_base.hh"
+
+namespace tizen_cpp {
+namespace {
+
+constexpr const char kStatusForeground[] = "fg";
+constexpr const char kStatusBackground[] = "bg";
+
+class AppContext {
+ public:
+  void SetAppId(const std::string& app_id) {
+    app_id_ = app_id;
+  }
+
+  const std::string& GetAppId() const {
+    return app_id_;
+  }
+
+  void SetPackageId(const std::string& package_id) {
+    package_id_ = package_id;
+  }
+
+  const std::string& GetPackageId() const {
+    return package_id_;
+  }
+
+  void SetViewerEndpoint(const std::string& viewer_endpoint) {
+    viewer_endpoint_ = viewer_endpoint;
+  }
+
+  const std::string& GetViewerEndpoint() const {
+    return viewer_endpoint_;
+  }
+
+  void SetPermanent(bool permanent) {
+    permanent_ = permanent;
+  }
+
+  bool IsPermanent() const {
+    return permanent_;
+  }
+
+  void SetFgSignal(bool fg_signal) {
+    fg_signal_ = fg_signal;
+  }
+
+  bool IsFgSignal() const {
+    return fg_signal_;
+  }
+
+  int SendUpdateStatus(const std::string& class_id,
+      const std::string& instance_id, int status, int err,
+      bundle* extra) {
+    int ret = aul_widget_send_status_to_viewer(class_id.c_str(),
+        instance_id.c_str(), viewer_endpoint_.c_str(), status, err, extra);
+    if (ret != AUL_R_OK)
+      return ret;
+
+    int lifecycle = widget_instance_convert_event_to_lifecycle_status(status);
+    if (lifecycle > -1) {
+      ret = aul_widget_send_status_to_service(class_id.c_str(),
+          instance_id.c_str(), package_id_.c_str(), lifecycle);
+    }
+
+    return ret;
+  }
+
+ private:
+  std::string app_id_;
+  std::string package_id_;
+  std::string viewer_endpoint_;
+  bool permanent_ = false;
+  bool fg_signal_ = false;
+};
+
+AppContext __context;
+
+}  // namespace
+
+class WidgetBase::Impl {
+ public:
+  explicit Impl(WidgetBase* parent) : parent_(parent) {}
+
+ private:
+  friend class WidgetBase;
+  WidgetBase* parent_;
+
+  void ControlCreate(const std::string& class_id, const std::string& id,
+      const tizen_base::Bundle& b);
+  void ControlDestroy(const std::string& class_id, const std::string& id,
+      const tizen_base::Bundle& b);
+  void ControlResume(const std::string& class_id, const std::string& id,
+      const tizen_base::Bundle& b);
+  void ControlPause(const std::string& class_id, const std::string& id,
+      const tizen_base::Bundle& b);
+  void ControlChangePeriod(const std::string& class_id, const std::string& id,
+      const tizen_base::Bundle& b);
+  void ControlUpdate(const std::string& class_id, const std::string& id,
+      const tizen_base::Bundle& b);
+  void ControlResize(const std::string& class_id, const std::string& id,
+      const tizen_base::Bundle& b);
+  void GetContent(tizen_base::Bundle& b);
+};
+
+WidgetBase* __widget;
+
+class WidgetContext::Impl {
+ public:
+  explicit Impl(WidgetContext* parent) : parent_(parent) {}
+
+  ~Impl() {
+    UnsetPeriodicTimer();
+  }
+
+ private:
+  void UpdateProcess(const tizen_base::Bundle& b);
+  void OnUpdate(bool force);
+  void SetPeriod(double period);
+  void SetPeriodicTimer();
+  void UnsetPeriodicTimer();
+  static gboolean TimedOutCb(gpointer user_data);
+
+ private:
+  friend class WidgetContext;
+  friend class WidgetBase;
+  friend class WidgetBase::Impl;
+
+  WidgetContext* parent_;
+
+  std::unique_ptr<tizen_base::Bundle> args_;
+  std::string content_;
+  double period_;
+  guint periodic_timer_ = 0;
+  bool pending_update_;
+  std::string pending_content_;
+};
+
+void WidgetBase::Impl::ControlCreate(const std::string& class_id,
+    const std::string& id, const tizen_base::Bundle& b) {
+  if (parent_->FindById(id).get() != nullptr) {
+    _E("Already exists. ID(%s)", id.c_str());
+    return;
+  }
+
+  std::shared_ptr<Context> context;
+  try {
+    context = parent_->CreateContext(class_id, id);
+  } catch (std::runtime_error& e) {
+    _E("runtime_error exception occurs");
+    return;
+  }
+
+  WidgetContext* wc = dynamic_cast<WidgetContext*>(context.get());
+  if (wc == nullptr)
+    return;
+
+  wc->impl_->args_.reset(new tizen_base::Bundle(b));
+  auto ctx = parent_->RunContext(context);
+  if (ctx.get() == nullptr)
+    return;
+
+  wc->impl_->args_.reset();
+  wc->impl_->content_ = b.GetString(WIDGET_K_CONTENT_INFO);
+}
+
+void WidgetBase::Impl::ControlDestroy(const std::string& class_id,
+    const std::string& id, const tizen_base::Bundle& b) {
+  auto context = parent_->FindById(id);
+  if (context.get() == nullptr) {
+    _E("Failed to find widget context. ID(%s)", id.c_str());
+    aul_widget_instance_del(class_id.c_str(), id.c_str());
+    return;
+  }
+
+  WidgetContext* wc = dynamic_cast<WidgetContext*>(context.get());
+  if (wc == nullptr)
+    return;
+
+  wc->impl_->args_.reset(new tizen_base::Bundle(b));
+  parent_->ExitContext(context);
+}
+
+void WidgetBase::Impl::ControlResume(const std::string& class_id,
+    const std::string& id, const tizen_base::Bundle& b) {
+  auto context = parent_->FindById(id);
+  if (context.get() == nullptr) {
+    _E("Failed to find widget context. ID(%s)", id.c_str());
+    return;
+  }
+
+  context->Resume();
+}
+
+void WidgetBase::Impl::ControlPause(const std::string& class_id,
+    const std::string& id, const tizen_base::Bundle& b) {
+  auto context = parent_->FindById(id);
+  if (context.get() == nullptr) {
+    _E("Failed to find widget context. ID(%s)", id.c_str());
+    return;
+  }
+
+  context->Pause();
+}
+
+void WidgetBase::Impl::ControlUpdate(const std::string& class_id,
+    const std::string& id, const tizen_base::Bundle& b) {
+  if (id.empty()) {
+    for (auto& i : parent_->GetContexts()) {
+      if (i->GetContextId() == class_id) {
+        WidgetContext* cxt = dynamic_cast<WidgetContext*>(i.get());
+        if (cxt == nullptr)
+          continue;
+
+        cxt->impl_->UpdateProcess(b);
+      }
+    }
+    return;
+  }
+
+  auto context = parent_->FindById(id);
+  if (context.get() == nullptr) {
+    _E("Failed to find widget context. ID(%s)", id.c_str());
+    return;
+  }
+
+  WidgetContext* wc = dynamic_cast<WidgetContext*>(context.get());
+  if (wc == nullptr)
+    return;
+
+  wc->impl_->UpdateProcess(b);
+}
+
+void WidgetBase::Impl::ControlResize(const std::string& class_id,
+    const std::string& id, const tizen_base::Bundle& b) {
+  auto context = parent_->FindById(id);
+  if (context.get() == nullptr) {
+    _E("Failed to find widget context. ID(%s)", id.c_str());
+    return;
+  }
+
+  int w = 0;
+  std::string w_str = b.GetString(WIDGET_K_WIDTH);
+  if (!w_str.empty()) {
+    char* remain = nullptr;
+    w = static_cast<int>(g_ascii_strtoll(w_str.c_str(), &remain, 10));
+  }
+
+  int h = 0;
+  std::string h_str = b.GetString(WIDGET_K_HEIGHT);
+  if (!h_str.empty()) {
+    char* remain = nullptr;
+    h = static_cast<int>(g_ascii_strtoll(h_str.c_str(), &remain, 10));
+  }
+
+  WidgetContext* wc = dynamic_cast<WidgetContext*>(context.get());
+  if (wc == nullptr)
+    return;
+
+  wc->OnResize(w, h);
+
+  _D("WidgetContext(%s) is resized to %dx%d", id.c_str(), w, h);
+  __context.SendUpdateStatus(class_id, id,
+      WIDGET_INSTANCE_EVENT_SIZE_CHANGED, 0, nullptr);
+}
+
+void WidgetBase::Impl::ControlChangePeriod(const std::string& class_id,
+    const std::string& id, const tizen_base::Bundle& b) {
+  auto context = parent_->FindById(id);
+  if (context.get() == nullptr) {
+    _E("Failed to find widget context. ID(%s)", id.c_str());
+    return;
+  }
+
+  WidgetContext* wc = dynamic_cast<WidgetContext*>(context.get());
+  if (wc == nullptr)
+    return;
+
+  wc->impl_->UnsetPeriodicTimer();
+
+  auto v = b.GetByte(WIDGET_K_PERIOD);
+  if (v.empty())
+    return;
+
+  const double* period = reinterpret_cast<double*>(v.data());
+  wc->impl_->SetPeriod(*period);
+  wc->impl_->SetPeriodicTimer();
+}
+
+void WidgetBase::Impl::GetContent(tizen_base::Bundle& b) {
+  std::string instance_id = b.GetString(AUL_K_WIDGET_INSTANCE_ID);
+  if (instance_id.empty()) {
+    _E("Instance ID is nullptr");
+    return;
+  }
+
+  auto context = parent_->FindById(instance_id);
+  if (context.get() == nullptr) {
+    _E("Failed to find widget context. ID(%s)", instance_id.c_str());
+    return;
+  }
+
+  WidgetContext* wc = dynamic_cast<WidgetContext*>(context.get());
+  if (wc == nullptr)
+    return;
+
+  if (!wc->impl_->content_.empty()) {
+    b.Add(AUL_K_WIDGET_CONTENT_INFO, wc->impl_->content_);
+    _D("Content info of %s found", instance_id.c_str());
+  } else {
+    b.Add(AUL_K_WIDGET_CONTENT_INFO, "");
+    _D("Empty content info added");
+  }
+}
+
+WidgetBase::WidgetBase() : impl_(std::make_unique<WidgetBase::Impl>(this)) {
+}
+
+WidgetBase::~WidgetBase() = default;
+
+std::string WidgetBase::GetViewerEndpoint() {
+  return __context.GetViewerEndpoint();
+}
+
+void WidgetBase::Run(int argc, char** argv) {
+  bundle* kb = bundle_import_from_argv(argc, argv);
+  if (kb) {
+    tizen_base::Bundle b(kb, false, true);
+    __context.SetViewerEndpoint(b.GetString(AUL_K_WIDGET_VIEWER));
+    if (!__context.GetViewerEndpoint().empty())
+      _D("Viewer endpoint :%s", __context.GetViewerEndpoint().c_str());
+    else
+      _E("Endpoint is missing");
+  } else {
+    _E("Failed to get launch argv");
+    throw std::runtime_error("Failed to get launch argv");
+  }
+
+  AppCoreMultiWindowBase::Run(argc, argv);
+}
+
+void WidgetBase::Dispose() {
+  AppCoreMultiWindowBase::Dispose();
+  if (getenv("AUL_LOADER_INIT")) {
+      unsetenv("AUL_LOADER_INIT");
+      OnLoopFinish();
+  }
+}
+
+void WidgetBase::ExitContext(
+    std::shared_ptr<AppCoreMultiWindowBase::Context> context) {
+  AppCoreMultiWindowBase::ExitContext(context);
+  int cnt = GetContextCnt();
+  if (cnt == 0)
+    Exit();
+
+  aul_widget_write_log(LOG_TAG,
+      "[%s:%d] instance_id(%s)", __FUNCTION__, __LINE__,
+      context->GetInstId().c_str());
+}
+
+void WidgetBase::Exit() {
+  AppCoreMultiWindowBase::Exit();
+  int cnt = GetContextCnt();
+  int ret = 0;
+  if (cnt == 0 && __context.IsPermanent())
+    ret = aul_notify_exit();
+
+  aul_widget_write_log(LOG_TAG,
+      "[%s:%d] exit : ret(%d), cnt(%d), permanent(%d)",
+      __FUNCTION__, __LINE__, ret, cnt, __context.IsPermanent());
+}
+
+int WidgetBase::OnCreate() {
+  AppCoreMultiWindowBase::OnCreate();
+
+  char appid[256] = { 0, };
+  int ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
+  if (ret != AUL_R_OK) {
+    _E("aul_app_get_appid_bypid() is failed. error(%d)", ret);
+    return -1;
+  }
+
+  __context.SetAppId(appid);
+
+  char pkgid[256] = { 0, };
+  ret = aul_app_get_pkgid_bypid(getpid(), pkgid, sizeof(pkgid));
+  if (ret != AUL_R_OK) {
+    _E("aul_app_get_pkgid_bypid() is failed. error(%d)", ret);
+    return -1;
+  }
+
+  __context.SetPackageId(pkgid);
+
+  screen_connector_provider_init();
+  _D("Widget base is created");
+  __widget = this;
+  return 0;
+}
+
+int WidgetBase::OnTerminate() {
+  screen_connector_provider_fini();
+  __widget = nullptr;
+
+  AppCoreMultiWindowBase::OnTerminate();
+  _D("Widget base is terminated");
+  return 0;
+}
+
+int WidgetBase::OnReceive(aul_type type, tizen_base::Bundle b) {
+  AppCoreMultiWindowBase::OnReceive(type,
+      tizen_base::Bundle(b.GetHandle(), false, false));
+
+  switch (type) {
+    case AUL_RESUME: {
+        for (auto& i : GetContexts())
+          i->Resume();
+      }
+      break;
+    case AUL_TERMINATE:
+      Exit();
+      break;
+    case AUL_WIDGET_CONTENT:
+      impl_->GetContent(b);
+      break;
+    default:
+      break;
+  }
+
+  return 0;
+}
+
+int WidgetBase::OnControl(tizen_base::Bundle b) {
+  AppCoreMultiWindowBase::OnControl(
+      tizen_base::Bundle(b.GetHandle(), false, false));
+
+  std::string class_id = b.GetString(WIDGET_K_CLASS);
+  /* for previous version compatibility, use appid for default class id */
+  if (class_id.empty())
+    class_id = __context.GetAppId();
+
+  std::string id = b.GetString(AUL_K_WIDGET_INSTANCE_ID);
+  std::string operation = b.GetString(WIDGET_K_OPERATION);
+  if (operation.empty()) {
+    _E("Operation is empty");
+    return 0;
+  }
+
+  _I("Operation(%s)", operation.c_str());
+  if (operation == "create")
+    impl_->ControlCreate(class_id, id, b);
+  else if (operation == "resize")
+    impl_->ControlResize(class_id, id, b);
+  else if (operation == "update")
+    impl_->ControlUpdate(class_id, id, b);
+  else if (operation == "destroy")
+    impl_->ControlDestroy(class_id, id, b);
+  else if (operation == "resume")
+    impl_->ControlResume(class_id, id, b);
+  else if (operation == "pause")
+    impl_->ControlPause(class_id, id, b);
+  else if (operation == "terminate")
+    impl_->ControlDestroy(class_id, id, b);
+  else if (operation == "period")
+    impl_->ControlChangePeriod(class_id, id, b);
+
+  return 0;
+}
+
+void WidgetContext::Impl::OnUpdate(bool force) {
+  parent_->OnUpdate(pending_content_.empty() ? tizen_base::Bundle() :
+      tizen_base::Bundle(pending_content_), force);
+
+  std::string class_id = parent_->GetContextId();
+  std::string id = parent_->GetInstId();
+  __context.SendUpdateStatus(class_id, id,
+      WIDGET_INSTANCE_EVENT_UPDATE, 0, nullptr);
+  _D("Updated: %s", id.c_str());
+}
+
+void WidgetContext::Impl::UpdateProcess(const tizen_base::Bundle& b) {
+  bool force;
+  std::string force_str = b.GetString(WIDGET_K_FORCE);
+  if (force_str == "true")
+    force = true;
+  else
+    force = false;
+
+  std::string content_raw = b.GetString(WIDGET_K_CONTENT_INFO);
+  if (!parent_->IsResumed() && !force) {
+    pending_content_ = content_raw;
+    pending_update_ = true;
+  } else {
+    parent_->OnUpdate(content_raw.empty() ? tizen_base::Bundle() :
+        tizen_base::Bundle(content_raw), force);
+
+    std::string class_id = parent_->GetContextId();
+    std::string id = parent_->GetInstId();
+    __context.SendUpdateStatus(class_id, id,
+        WIDGET_INSTANCE_EVENT_UPDATE, 0, nullptr);
+    _D("Updated: %s", id.c_str());
+  }
+}
+
+void WidgetContext::Impl::SetPeriod(double period) {
+  period_ = period;
+}
+
+void WidgetContext::Impl::SetPeriodicTimer() {
+  if (periodic_timer_)
+    return;
+
+  if (period_ > 0) {
+    _D("Restart timer!");
+    periodic_timer_ = g_timeout_add_seconds(period_,
+        TimedOutCb, parent_);
+  }
+}
+
+void WidgetContext::Impl::UnsetPeriodicTimer() {
+  if (periodic_timer_) {
+    _D("Remove timer!");
+    g_source_remove(periodic_timer_);
+    periodic_timer_ = 0;
+  }
+}
+
+gboolean WidgetContext::Impl::TimedOutCb(gpointer user_data) {
+  WidgetContext* wc = reinterpret_cast<WidgetContext*>(user_data);
+  if (wc->IsResumed()) {
+    _D("Periodic update!");
+    wc->OnUpdate(tizen_base::Bundle(), false);
+
+    __context.SendUpdateStatus(wc->GetContextId(), wc->GetInstId(),
+        WIDGET_INSTANCE_EVENT_UPDATE, 0, nullptr);
+    _D("Updated: %s", wc->GetInstId().c_str());
+  } else {
+    wc->impl_->pending_update_ = true;
+    wc->impl_->UnsetPeriodicTimer();
+  }
+
+  return G_SOURCE_CONTINUE;
+}
+
+WidgetContext::WidgetContext(std::string context_id, std::string inst_id,
+    AppCoreMultiWindowBase* app)
+    : AppCoreMultiWindowBase::Context(
+          std::move(context_id), std::move(inst_id), app),
+      impl_(std::make_unique<WidgetContext::Impl>(this)) {
+}
+
+WidgetContext::~WidgetContext() = default;
+
+void WidgetContext::OnPause() {
+  std::string id = GetInstId();
+  _D("WidgetContext(%s) is paused", id.c_str());
+  std::string class_id = GetContextId();
+  __context.SendUpdateStatus(class_id.c_str(), id.c_str(),
+      WIDGET_INSTANCE_EVENT_PAUSE, 0, nullptr);
+
+  if (__context.IsFgSignal()) {
+    _D("Send bg signal to resourceD");
+    aul_widget_instance_change_status(class_id.c_str(), kStatusBackground);
+    __context.SetFgSignal(false);
+  }
+}
+
+void WidgetContext::OnResume() {
+  if (impl_->pending_update_) {
+    _D("Pending update!");
+    impl_->pending_update_ = false;
+    impl_->OnUpdate(false);
+    impl_->SetPeriodicTimer();
+  }
+
+  std::string id = GetInstId();
+  _D("WidgetContext(%s) is resumed", id.c_str());
+  std::string class_id = GetContextId();
+  __context.SendUpdateStatus(class_id.c_str(), id.c_str(),
+      WIDGET_INSTANCE_EVENT_RESUME, 0, nullptr);
+
+  if (!__context.IsFgSignal()) {
+    _D("Send fg signal to resourceD");
+    aul_widget_instance_change_status(class_id.c_str(), kStatusForeground);
+    __context.SetFgSignal(true);
+  }
+}
+
+void WidgetContext::OnResize(int w, int h) {
+}
+
+void WidgetContext::OnUpdate(const tizen_base::Bundle& contents, bool force) {
+}
+
+void WidgetContext::ExitAsync() {
+  tizen_base::Bundle b;
+  b.Add(WIDGET_K_OPERATION, "terminate");
+
+  impl_->args_.reset(new tizen_base::Bundle(std::move(b)));
+  g_idle_add([](gpointer user_data) -> gboolean {
+    if (__widget == nullptr)
+      return G_SOURCE_REMOVE;
+
+    WidgetContext* wc = static_cast<WidgetContext*>(user_data);
+
+    std::string id = wc->GetInstId();
+    auto context = __widget->FindById(id);
+    if (context.get() == nullptr) {
+      _E("Failed to find context. ID(%s)", id.c_str());
+      return G_SOURCE_REMOVE;
+    }
+
+    __widget->ExitContext(context);
+    return G_SOURCE_REMOVE;
+  }, this);
+}
+
+int WidgetContext::SetContents(const tizen_base::Bundle& contents) {
+  std::string id = GetInstId();
+  if (id.empty())
+    return WIDGET_ERROR_FAULT;
+
+  std::string class_id = GetContextId();
+  if (class_id.empty())
+    return WIDGET_ERROR_FAULT;
+
+  int ret = __context.SendUpdateStatus(class_id, id,
+      WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, 0, contents.GetHandle());
+  if (ret < 0) {
+    _E("Failed to send content info: %s of %s (%d)",
+        id.c_str(), class_id.c_str(), ret);
+    return WIDGET_ERROR_FAULT;
+  }
+
+  return WIDGET_ERROR_NONE;
+}
+
+int WidgetContext::WindowBind(std::string id, Ecore_Wl2_Window* wl_win) {
+  wl_surface* surface = ecore_wl2_window_surface_get(wl_win);
+  if (surface == nullptr) {
+    _E("Failed to get surface, wl_win(%p)", wl_win);
+    return -1;
+  }
+
+  screen_connector_provider_remote_enable(id.c_str(), surface);
+  WindowBind(wl_win);
+  return 0;
+}
+
+void WidgetContext::OnCreate() {
+  auto& b = impl_->args_;
+  std::string class_id = b->GetString(WIDGET_K_CLASS);
+  /* For previous version compatibility, use appid for default class id */
+  if (class_id.empty())
+    class_id = __context.GetAppId();
+
+  std::string id = b->GetString(AUL_K_WIDGET_INSTANCE_ID);
+  std::string operation = b->GetString(WIDGET_K_OPERATION);
+  if (operation.empty()) {
+    _E("Operation is empty");
+    return;
+  }
+
+  std::string w_str = b->GetString(WIDGET_K_WIDTH);
+  int w = 0;
+  if (!w_str.empty()) {
+    char* remain = nullptr;
+    w = static_cast<int>(g_ascii_strtoll(w_str.c_str(), &remain, 10));
+  }
+
+  std::string h_str = b->GetString(WIDGET_K_HEIGHT);
+  int h = 0;
+  if (!h_str.empty()) {
+    char* remain = nullptr;
+    h = static_cast<int>(g_ascii_strtoll(h_str.c_str(), &remain, 10));
+  }
+
+  tizen_base::Bundle content_info;
+  std::string content = b->GetString(WIDGET_K_CONTENT_INFO);
+  try {
+    if (!content.empty())
+      content_info = tizen_base::Bundle(content);
+  } catch (std::bad_alloc& e) {
+    _W("Failed to decode content info(%s)", content.c_str());
+  }
+
+  bool r = OnCreate(content_info, w, h);
+  if (!r) {
+    _W("Create callback returns error");
+    int ret = __context.SendUpdateStatus(class_id, id,
+        WIDGET_INSTANCE_EVENT_CREATE_ABORTED, WIDGET_ERROR_CANCELED, nullptr);
+    if (ret != 0)
+      _E("Failed to send abrot status. error(%d)", ret);
+
+    throw std::runtime_error("Create callback returns error");
+  } else {
+    _D("WidgetContext(%s) is created", id.c_str());
+    aul_widget_instance_add(class_id.c_str(), id.c_str());
+    int ret = __context.SendUpdateStatus(class_id, id,
+        WIDGET_INSTANCE_EVENT_CREATE, 0, nullptr);
+    if (ret != 0)
+      _E("Failed to send create status. error(%d)", ret);
+
+    auto v = b->GetByte(WIDGET_K_PERIOD);
+    if (v.empty())
+      return;
+
+    const double* period = reinterpret_cast<double*>(v.data());
+    if (*period > 0) {
+      _I("Set periodic update timer. period(%lf)", *period);
+      impl_->SetPeriod(*period);
+      impl_->SetPeriodicTimer();
+    }
+  }
+}
+
+void WidgetContext::OnTerminate() {
+  DestroyType reason = DestroyType::TEMPORARY;
+  int event = WIDGET_INSTANCE_EVENT_TERMINATE;
+  std::string id = GetInstId();
+  std::string class_id = GetContextId();
+  auto& b = impl_->args_;
+  if (b.get()) {
+    std::string operation = b->GetString(WIDGET_K_OPERATION);
+    if (operation == "destroy")
+      reason = DestroyType::PERMANENT;
+  }
+
+  tizen_base::Bundle content_info = impl_->content_.empty() ?
+      tizen_base::Bundle() : tizen_base::Bundle(impl_->content_);
+
+  OnDestroy(reason, content_info);
+
+  _W("WidgetContext(%s) is destroyed. reason(%s)", id.c_str(),
+      reason == DestroyType::TEMPORARY ? "TEMPORARY" : "PERMANENT");
+  if (reason == DestroyType::PERMANENT) {
+    __context.SetPermanent(true);
+    event = WIDGET_INSTANCE_EVENT_DESTROY;
+    aul_widget_instance_del(class_id.c_str(), id.c_str());
+  } else {
+    __context.SetPermanent(false);
+    __context.SendUpdateStatus(class_id.c_str(), id.c_str(),
+        WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, 0, content_info.GetHandle());
+  }
+
+  impl_->UnsetPeriodicTimer();
+
+  __context.SendUpdateStatus(class_id.c_str(), id.c_str(), event, 0, nullptr);
+}
+
+}  // namespace tizen_cpp
similarity index 99%
rename from src/base/widget_base.c
rename to src/base/widget_base_legacy.c
index ec0d02d..40115b7 100644 (file)
@@ -1,46 +1,42 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
  *
- * Licensed under the Apache License, Version 2.0 (the License);
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
+ * 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 <stdlib.h>
-#include <stdbool.h>
-
-#include <bundle.h>
-#include <bundle_internal.h>
+#include <Ecore_Wl2.h>
+#include <appcore_multiwindow_base.h>
 #include <aul.h>
+#include <aul_app_com.h>
 #include <aul_widget.h>
+#include <bundle.h>
+#include <bundle_internal.h>
 #include <dlog.h>
-#include <glib.h>
 #include <glib-object.h>
+#include <glib.h>
+#include <screen_connector_provider.h>
+#include <stdbool.h>
 #include <stdlib.h>
+#include <stdlib.h>
+#include <system_info.h>
 #include <unistd.h>
 #include <widget_errno.h>
 #include <widget_instance.h>
-#include <aul_app_com.h>
-#include <Ecore_Wl2.h>
-#include <system_info.h>
-#include <screen_connector_provider.h>
-#include <appcore_multiwindow_base.h>
-
-#include "widget_base.h"
 
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
+#include "common/export_private.hh"
+#include "common/log_private.hh"
+#include "include/widget_base.h"
 
-#define LOG_TAG "CAPI_WIDGET_APPLICATION"
 #define APP_TYPE_WIDGET "widgetapp"
 #define STATUS_FOREGROUND "fg"
 #define STATUS_BACKGROUND "bg"
diff --git a/src/common/export_private.hh b/src/common/export_private.hh
new file mode 100644 (file)
index 0000000..1102d02
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 COMMON_EXPORT_PRIVATE_HH_
+#define COMMON_EXPORT_PRIVATE_HH_
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__ ((visibility("default")))
+
+#undef API
+#define API extern "C" EXPORT_API
+
+#endif  // COMMON_EXPORT_PRIVATE_HH_
diff --git a/src/common/log_private.hh b/src/common/log_private.hh
new file mode 100644 (file)
index 0000000..52b17e6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 COMMON_LOG_PRIVATE_HH_
+#define COMMON_LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "CAPI_WIDGET_APPLICATION"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif  // COMMON_LOG_PRIVATE_HH_
index 610bb00..357f9cc 100644 (file)
@@ -1,25 +1,38 @@
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} WIDGET_APPLICATION_SRCS)
 
 ADD_LIBRARY(${TARGET_WIDGET_APPLICATION} SHARED ${WIDGET_APPLICATION_SRCS})
-SET_TARGET_PROPERTIES(${TARGET_WIDGET_APPLICATION} PROPERTIES SOVERSION ${MAJORVER})
-SET_TARGET_PROPERTIES(${TARGET_WIDGET_APPLICATION} PROPERTIES VERSION ${FULLVER})
-TARGET_LINK_LIBRARIES(${TARGET_WIDGET_APPLICATION} PRIVATE ${TARGET_WIDGET_BASE})
 
-TARGET_INCLUDE_DIRECTORIES(${TARGET_WIDGET_APPLICATION} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../)
-TARGET_INCLUDE_DIRECTORIES(${TARGET_WIDGET_APPLICATION} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../include/)
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_APPLICATION}
+  PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_APPLICATION}
+  PROPERTIES VERSION ${FULLVER})
+TARGET_LINK_LIBRARIES(${TARGET_WIDGET_APPLICATION}
+  PRIVATE ${TARGET_WIDGET_BASE})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_WIDGET_APPLICATION} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}/
+  ${CMAKE_CURRENT_SOURCE_DIR}/../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../include/
+  ${CMAKE_CURRENT_SOURCE_DIR}/../base/
+  ${CMAKE_CURRENT_SOURCE_DIR}/../common/)
 
 APPLY_PKG_CONFIG(${TARGET_WIDGET_APPLICATION} PUBLIC
   AUL_DEP
   DLOG_DEPS
   APPCORE_COMMON_DEPS
   ELEMENTARY_DEP
+  SYSTEM_INFO_DEPS
   WIDGET_SERVICE_DEPS
   CAPI_APP_COMMON_DEP
 )
 
-CONFIGURE_FILE(../../capi-appfw-widget-application.pc.in ../../capi-appfw-widget-application.pc @ONLY)
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/capi-appfw-widget-application.pc.in
+  ${CMAKE_CURRENT_SOURCE_DIR}/capi-appfw-widget-application.pc @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/capi-appfw-widget-application.pc
+  DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
 INSTALL(TARGETS ${TARGET_WIDGET_APPLICATION} DESTINATION ${LIB_INSTALL_DIR})
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/../../capi-appfw-widget-application.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/appfw/
        FILES_MATCHING
        PATTERN "*.h*"
diff --git a/src/efl_base/widget-log.h b/src/efl_base/widget-log.h
deleted file mode 100644 (file)
index a316028..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2015 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
- *
- * 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 __APPFW_WIDGET_LOG_H__
-#define __APPFW_WIDGET_LOG_H__
-
-#include <dlog.h>
-
-#define _E(fmt, arg...) LOGE(fmt, ##arg)
-#define _I(fmt, arg...) LOGI(fmt, ##arg)
-#define _D(fmt, arg...) LOGD(fmt, ##arg)
-#define _W(fmt, arg...) LOGW(fmt, ##arg)
-
-#ifndef EXPORT_API
-#define EXPORT_API __attribute__ ((visibility("default")))
-#endif
-
-#ifndef _E
-#define _E(fmt, arg...) LOGE(fmt, ##arg)
-#endif
-
-#ifndef _I
-#define _I(...) LOGI(__VA_ARGS__)
-#endif
-
-#ifndef _D
-#define _D(...) LOGD(__VA_ARGS__)
-#endif
-
-#ifndef _W
-#define _W(...) LOGW(__VA_ARGS__)
-#endif
-
-#define _warn_if(expr, fmt, arg...)            \
-       do {                                    \
-               if (expr)                       \
-                       _ERR(fmt, ##arg);       \
-       } while (0)
-
-#define _ret_if(expr)                          \
-       do {                                    \
-               if (expr)                       \
-                       return;                 \
-       } while (0)
-
-#define _retv_if(expr, val)                    \
-       do {                                    \
-               if (expr)                       \
-                       return (val);           \
-       } while (0)
-
-#define _retm_if(expr, fmt, arg...)            \
-       do {                                    \
-               if (expr) {                     \
-                       _ERR(fmt, ##arg);       \
-                       return;                 \
-               }                               \
-       } while (0)
-
-#define _retvm_if(expr, val, fmt, arg...)      \
-       do {                                    \
-               if (expr) {                     \
-                       _ERR(fmt, ##arg);       \
-                       return (val);           \
-               }                               \
-       } while (0)
-
-#endif /* __APPFW_WIDGET_LOG_H_ */
-
diff --git a/src/efl_base/widget-private.h b/src/efl_base/widget-private.h
deleted file mode 100644 (file)
index 34fdc5f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2015 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
- *
- * 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 __APPCORE_WIDGET_PRIVATE_H__
-#define __APPCORE_WIDGET_PRIVATE_H__
-
-#include <glib.h>
-
-#include <Elementary.h>
-#include <widget_app.h>
-#include <app_common.h>
-#include <widget_errno.h>
-
-int widget_app_error(widget_error_e error, const char *function,
-               const char *description);
-
-#endif /* __APPCORE_WIDGET_PRIVATE_H__ */
-
diff --git a/src/efl_base/widget_app.c b/src/efl_base/widget_app.c
deleted file mode 100644 (file)
index 174195f..0000000
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * Copyright (c) 2015 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
- *
- * 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 <stdlib.h>
-#include <glib.h>
-
-#include <bundle.h>
-#include <aul.h>
-#include <aul_widget.h>
-#include <dlog.h>
-#include <Elementary.h>
-#include <widget_errno.h>
-#include <widget_instance.h>
-
-#include "widget_base.h"
-#include "widget_app.h"
-#include "widget-log.h"
-#include "widget-private.h"
-#include "widget_app_internal.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "CAPI_WIDGET_APPLICATION"
-#define ICONIFY_TIMEOUT 500
-
-struct instance_data {
-       Evas_Object *win;
-       guint iconify_timer;
-       bool is_iconified;
-};
-
-struct app_cb_info {
-       widget_app_lifecycle_callback_s *callback;
-       void *user_data;
-};
-
-struct app_class_cb_info {
-       widget_instance_lifecycle_callback_s callback;
-       void *user_data;
-};
-
-static GList *__class_data_list;
-
-static int __class_resize(widget_base_instance_h instance_h, int w, int h,
-               void *class_data)
-{
-       int ret = 0;
-       struct instance_data *data;
-       struct app_class_cb_info *callback_data =
-                       (struct app_class_cb_info *)class_data;
-
-       widget_base_class_on_resize(instance_h, w, h);
-       data = (struct instance_data *)
-                       widget_base_context_get_user_data(instance_h);
-
-       if (!data) {
-               _E("widget_base_context_get_user_data() returns null");
-
-               return -1;
-       }
-
-       if (data->win)
-               evas_object_resize(data->win, w, h);
-       else
-               _E("unable to find window");
-
-       if (callback_data && callback_data->callback.resize) {
-               ret = callback_data->callback.resize(
-                               (widget_context_h)instance_h,
-                               w, h, callback_data->user_data);
-       }
-
-       return ret;
-}
-
-static int __class_update(widget_base_instance_h instance_h, bundle *content,
-               int force, void *class_data)
-{
-       int ret = 0;
-       struct app_class_cb_info *callback_data =
-                       (struct app_class_cb_info *)class_data;
-
-       widget_base_class_on_update(instance_h, content, force);
-       if (callback_data && callback_data->callback.update) {
-               ret = callback_data->callback.update(
-                               (widget_context_h)instance_h,
-                               content, force, callback_data->user_data);
-       }
-
-       return ret;
-}
-
-static int __class_create(widget_base_instance_h instance_h, bundle *content,
-               int w, int h, void *class_data)
-{
-       int ret = -1;
-       struct app_class_cb_info *callback_data =
-                       (struct app_class_cb_info *)class_data;
-
-       widget_base_class_on_create(instance_h, content, w, h);
-       if (callback_data && callback_data->callback.create) {
-               ret = callback_data->callback.create(
-                               (widget_context_h)instance_h,
-                               content, w, h, callback_data->user_data);
-               aul_widget_write_log(LOG_TAG, "[%s:%d]  ret : %d",
-                       __FUNCTION__, __LINE__, ret);
-       }
-       return ret;
-}
-
-static int __class_destroy(widget_base_instance_h instance_h,
-               widget_base_destroy_type_e reason, bundle *content,
-               void *class_data)
-{
-       int ret = 0;
-       struct instance_data *data;
-       struct app_class_cb_info *callback_data =
-                       (struct app_class_cb_info *)class_data;
-
-       if (callback_data && callback_data->callback.destroy) {
-               ret = callback_data->callback.destroy(
-                               (widget_context_h)instance_h,
-                               reason, content, callback_data->user_data);
-               aul_widget_write_log(LOG_TAG, "[%s:%d]  ret : %d",
-                       __FUNCTION__, __LINE__, ret);
-       }
-
-       data = (struct instance_data *)widget_base_context_get_user_data(instance_h);
-       if (data != NULL) {
-               widget_base_context_set_user_data(instance_h, NULL);
-               if (data->iconify_timer > 0)
-                       g_source_remove(data->iconify_timer);
-               free(data);
-       }
-
-       widget_base_class_on_destroy(instance_h, reason, content);
-
-       return ret;
-}
-
-static gboolean __iconify_timeout_cb(gpointer user_data)
-{
-       struct instance_data *data = user_data;
-       Ecore_Wl2_Window *win = ecore_evas_wayland2_window_get(
-                       ecore_evas_ecore_evas_get(evas_object_evas_get(data->win)));
-
-       if (win) {
-               ecore_wl2_window_iconified_set(win, EINA_TRUE);
-               data->is_iconified = true;
-               _D("set iconify true");
-       }
-
-       data->iconify_timer = 0;
-
-       return G_SOURCE_REMOVE;
-}
-
-static int __class_pause(widget_base_instance_h instance_h, void *class_data)
-{
-       int ret = 0;
-       struct app_class_cb_info *callback_data =
-                       (struct app_class_cb_info *)class_data;
-       struct instance_data *data = (struct instance_data *)
-                       widget_base_context_get_user_data(instance_h);
-
-       if (data->iconify_timer > 0)
-               g_source_remove(data->iconify_timer);
-
-       data->iconify_timer = g_timeout_add(ICONIFY_TIMEOUT,
-                       __iconify_timeout_cb, data);
-
-       widget_base_class_on_pause(instance_h);
-       if (callback_data && callback_data->callback.pause) {
-               ret = callback_data->callback.pause(
-                               (widget_context_h)instance_h,
-                               callback_data->user_data);
-       }
-
-       return ret;
-}
-
-static int __class_resume(widget_base_instance_h instance_h, void *class_data)
-{
-       int ret = 0;
-       struct app_class_cb_info *callback_data =
-                       (struct app_class_cb_info *)class_data;
-       Ecore_Wl2_Window *win;
-       struct instance_data *data = (struct instance_data *)
-                       widget_base_context_get_user_data(instance_h);
-
-       if (data->iconify_timer > 0) {
-               g_source_remove(data->iconify_timer);
-               data->iconify_timer = 0;
-       }
-
-       if (data->is_iconified) {
-               win = ecore_evas_wayland2_window_get(
-                       ecore_evas_ecore_evas_get(evas_object_evas_get(data->win)));
-               if (win) {
-                       ecore_wl2_window_iconified_set(win, EINA_FALSE);
-                       data->is_iconified = false;
-                       _D("set iconify false");
-               }
-       }
-
-       widget_base_class_on_resume(instance_h);
-       if (callback_data && callback_data->callback.resume) {
-               ret = callback_data->callback.resume(
-                               (widget_context_h)instance_h,
-                               callback_data->user_data);
-       }
-
-       return ret;
-}
-
-static int __widget_app_create(void *data)
-{
-       struct app_cb_info *cb_info = (struct app_cb_info *)data;
-       widget_app_lifecycle_callback_s *callback;
-
-       widget_base_on_create();
-       if (cb_info && cb_info->callback && cb_info->callback->create) {
-               callback = cb_info->callback;
-               if (callback->create(cb_info->user_data) == NULL) {
-                       _D("fail to create widget");
-                       return -1;
-               }
-               _D("widget app is created");
-               aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
-               return 0;
-       }
-
-       return -1;
-}
-
-static int __widget_app_terminate(void *data)
-{
-       struct app_cb_info *cb_info = (struct app_cb_info *)data;
-       widget_app_lifecycle_callback_s *callback;
-
-       if (cb_info && cb_info->callback && cb_info->callback->terminate) {
-               callback = cb_info->callback;
-               callback->terminate(cb_info->user_data);
-               widget_base_on_terminate();
-               _D("widget app is terminated");
-               aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
-               return 0;
-       }
-
-       widget_base_on_terminate();
-
-       return -1;
-}
-
-static void __widget_app_init(int argc, char **argv, void *data)
-{
-       elm_init(argc, argv);
-}
-
-static void __widget_app_finish(void)
-{
-       elm_shutdown();
-}
-
-static void __widget_app_run(void *data)
-{
-       elm_run();
-}
-
-static void __widget_app_exit(void *data)
-{
-       elm_exit();
-}
-
-static void __widget_app_trim_memory(void *data)
-{
-       _D("Trim memory");
-       elm_cache_all_flush();
-       widget_base_on_trim_memory();
-}
-
-EXPORT_API int widget_app_main(int argc, char **argv,
-               widget_app_lifecycle_callback_s *callback, void *user_data)
-{
-       widget_base_ops ops;
-       struct app_cb_info cb_info;
-       int r;
-
-       if (argc <= 0 || argv == NULL || callback == NULL)
-               return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
-                               __FUNCTION__, NULL);
-
-       if (callback->create == NULL)
-               return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
-                               __FUNCTION__,
-                               "widget_app_create_cb() callback must be "
-                               "registered");
-
-       ops.create = __widget_app_create;
-       ops.terminate = __widget_app_terminate;
-       ops.init = __widget_app_init;
-       ops.finish = __widget_app_finish;
-       ops.run = __widget_app_run;
-       ops.exit = __widget_app_exit;
-       ops.trim_memory = __widget_app_trim_memory;
-
-       cb_info.callback = callback;
-       cb_info.user_data = user_data;
-
-       r = widget_base_init(ops, argc, argv, &cb_info);
-       widget_base_fini();
-
-       if (__class_data_list) {
-               g_list_free_full(__class_data_list, free);
-               __class_data_list = NULL;
-       }
-
-       return r;
-}
-
-EXPORT_API int widget_app_exit(void)
-{
-       return widget_base_exit();
-}
-
-EXPORT_API int widget_app_terminate_context(widget_context_h context)
-{
-       return widget_base_terminate_context((widget_base_instance_h)context);
-}
-
-EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data)
-{
-       return widget_base_foreach_context((widget_base_instance_cb)cb, data);
-}
-
-EXPORT_API int widget_app_add_event_handler(app_event_handler_h *event_handler,
-                                       app_event_type_e event_type,
-                                       app_event_cb callback,
-                                       void *user_data)
-{
-       return widget_base_add_event_handler(event_handler, event_type,
-                                       callback, user_data);
-}
-
-EXPORT_API int widget_app_remove_event_handler(app_event_handler_h
-                                               event_handler)
-{
-       return widget_base_remove_event_handler(event_handler);
-}
-
-EXPORT_API const char *widget_app_get_id(widget_context_h context)
-{
-       int ret;
-       char *id;
-
-       if (!context) {
-               set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
-               return NULL;
-       }
-
-       ret = widget_base_context_get_id((widget_base_instance_h)context, &id);
-       if (ret != WIDGET_BASE_ERROR_NONE) {
-               _E("failed to get context id"); /* LCOV_EXCL_LINE */
-               set_last_result(ret); /* LCOV_EXCL_LINE */
-               return NULL; /* LCOV_EXCL_LINE */
-       }
-
-       set_last_result(WIDGET_ERROR_NONE);
-       return id;
-}
-
-static void __win_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
-       char *plug_id;
-       plug_id = evas_object_data_del(obj, "___PLUGID");
-       free(plug_id);
-}
-
-EXPORT_API int widget_app_get_elm_win(widget_context_h context,
-                                       Evas_Object **win)
-{
-       Evas_Object *ret_win = NULL;
-       Ecore_Wl2_Window *wl_win;
-       struct instance_data *data;
-       char buffer[256];
-       int rots[3] = {0};
-       int win_id;
-       char *id;
-       int ret;
-
-       if (context == NULL || win == NULL)
-               return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
-                               __FUNCTION__, NULL);
-
-       ret = widget_base_context_get_id((widget_base_instance_h)context, &id);
-       if (ret != WIDGET_BASE_ERROR_NONE) {
-               _E("failed to get context id"); /* LCOV_EXCL_LINE */
-               goto fault; /* LCOV_EXCL_LINE */
-       }
-
-       ret_win = elm_win_add(NULL, id, ELM_WIN_BASIC);
-       if (ret_win == NULL) {
-               _E("failed to create window"); /* LCOV_EXCL_LINE */
-               goto fault; /* LCOV_EXCL_LINE */
-       }
-
-       elm_win_wm_rotation_preferred_rotation_set(ret_win, -1);
-       elm_win_wm_rotation_available_rotations_set(ret_win, rots, 1);
-
-       wl_win = ecore_evas_wayland2_window_get(ecore_evas_ecore_evas_get(evas_object_evas_get(ret_win)));
-       if (wl_win == NULL) {
-               _E("failed to get wayland window"); /* LCOV_EXCL_LINE */
-               goto fault;
-       }
-
-       ecore_wl2_window_class_set(wl_win, id);
-       elm_win_aux_hint_add(ret_win, "wm.policy.win.user.geometry", "1");
-       widget_base_context_window_bind((widget_base_instance_h)context,        id, wl_win);
-
-       /* Set data to use in accessibility */
-       snprintf(buffer, sizeof(buffer), "%s:%d", id, getpid());
-       evas_object_data_set(ret_win, "___PLUGID", strdup(buffer));
-       evas_object_event_callback_add(ret_win, EVAS_CALLBACK_DEL, __win_del_cb, NULL);
-
-       win_id = ecore_wl2_window_id_get(wl_win);
-       _D("window created: %d", win_id);
-
-       data = (struct instance_data *)widget_base_context_get_user_data(
-                       (widget_base_instance_h)context);
-       if (data == NULL) {
-               data = calloc(1, sizeof(struct instance_data));
-               if (data == NULL) {
-                       _E("failed to alloc instance_data"); /* LCOV_EXCL_LINE */
-                       goto fault; /* LCOV_EXCL_LINE */
-               }
-
-               ret = widget_base_context_set_user_data((widget_base_instance_h)context, data);
-               if (ret != WIDGET_BASE_ERROR_NONE) {
-                       _E("fail to set extra data"); /* LCOV_EXCL_LINE */
-                       goto fault; /* LCOV_EXCL_LINE */
-               }
-       }
-
-       data->win = ret_win;
-       *win = ret_win;
-
-       return WIDGET_ERROR_NONE;
-
-fault:
-       if (ret_win)    /* LCOV_EXCL_LINE */
-               evas_object_del(ret_win); /* LCOV_EXCL_LINE */
-
-       return WIDGET_ERROR_FAULT; /* LCOV_EXCL_LINE */
-}
-
-EXPORT_API widget_class_h widget_app_class_add(widget_class_h widget_class,
-               const char *class_id,
-               widget_instance_lifecycle_callback_s callback, void *user_data)
-{
-       widget_base_class cls;
-       struct app_class_cb_info *callback_data;
-       widget_class_h wc;
-
-       cls = widget_base_class_get_default();
-
-       /* override methods */
-       cls.ops.create = __class_create;
-       cls.ops.destroy = __class_destroy;
-       cls.ops.pause = __class_pause;
-       cls.ops.resume = __class_resume;
-       cls.ops.resize = __class_resize;
-       cls.ops.update = __class_update;
-
-       callback_data = calloc(1, sizeof(struct app_class_cb_info));
-       if (!callback_data) {
-               _E("failed to calloc : %s", __FUNCTION__);
-               set_last_result(WIDGET_ERROR_OUT_OF_MEMORY);
-               return NULL;
-       }
-       callback_data->callback = callback;
-       callback_data->user_data = user_data;
-
-       wc = (widget_class_h)widget_base_class_add(cls, class_id,
-                       callback_data);
-
-       if (!wc) {
-               free(callback_data);
-               return NULL;
-       }
-
-       __class_data_list = g_list_append(__class_data_list, callback_data);
-       set_last_result(WIDGET_ERROR_NONE);
-
-       return wc;
-}
-
-EXPORT_API widget_class_h widget_app_class_create(
-               widget_instance_lifecycle_callback_s callback, void *user_data)
-{
-       char *appid;
-       widget_class_h wc;
-
-       app_get_id(&appid);
-       if (!appid) {
-               LOGE("appid is NULL");
-               return NULL;
-       }
-
-       wc = (widget_class_h)widget_app_class_add(NULL, appid, callback,
-                       user_data);
-       free(appid);
-
-       return wc;
-}
-
-EXPORT_API int widget_app_context_set_tag(widget_context_h context, void *tag)
-{
-       int ret = 0;
-
-       ret = widget_base_context_set_tag((widget_base_instance_h)context, tag);
-       if (ret != WIDGET_BASE_ERROR_NONE)
-               return widget_app_error(ret, __FUNCTION__, NULL);
-
-       return WIDGET_ERROR_NONE;
-}
-
-EXPORT_API int widget_app_context_get_tag(widget_context_h context, void **tag)
-{
-       int ret = 0;
-
-       ret = widget_base_context_get_tag((widget_base_instance_h)context, tag);
-       if (ret != WIDGET_BASE_ERROR_NONE)
-               return widget_app_error(ret, __FUNCTION__, NULL);
-
-       return WIDGET_ERROR_NONE;
-}
-
-EXPORT_API int widget_app_context_set_content_info(widget_context_h context,
-               bundle *content_info)
-{
-       int ret = 0;
-
-       ret = widget_base_context_set_content_info(
-                       (widget_base_instance_h)context, content_info);
-       if (ret != WIDGET_BASE_ERROR_NONE)
-               return widget_app_error(ret, __FUNCTION__, NULL);
-
-       return WIDGET_ERROR_NONE;
-}
-
-EXPORT_API int widget_app_context_set_title(widget_context_h context,
-               const char *title)
-{
-       struct instance_data *data = NULL;
-       int ret;
-
-       if (!context || !title) {
-               _E("Invalid parameter %p %p", context, title);
-               return WIDGET_ERROR_INVALID_PARAMETER;
-       }
-
-       data = (struct instance_data *)widget_base_context_get_user_data(
-                       (widget_base_instance_h)context);
-       if (data == NULL) {
-               data = calloc(1, sizeof(struct instance_data));
-               if (data == NULL) {
-                       return widget_app_error(WIDGET_ERROR_FAULT,
-                                       __FUNCTION__, NULL);
-               }
-               ret = widget_base_context_set_user_data(context, data);
-               if (ret != WIDGET_BASE_ERROR_NONE)
-                       widget_app_error(ret, __FUNCTION__, NULL);
-       }
-
-       if (data->win)
-               elm_win_title_set(data->win, title);
-
-       return WIDGET_ERROR_NONE;
-}
diff --git a/src/efl_base/widget_app.cc b/src/efl_base/widget_app.cc
new file mode 100644 (file)
index 0000000..17cd02f
--- /dev/null
@@ -0,0 +1,718 @@
+/*
+* Copyright (c) 2015 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+*
+* 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 <Elementary.h>
+#include <app_event_internal.hh>
+#include <aul.h>
+#include <aul_app_com.h>
+#include <aul_widget.h>
+#include <dlog.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <system_info.h>
+#include <widget_errno.h>
+#include <widget_instance.h>
+
+#include "common/export_private.hh"
+#include "common/log_private.hh"
+#include "include/widget_app.h"
+#include "include/widget_app_internal.h"
+#include "include/widget_base.hh"
+
+using namespace tizen_cpp;
+namespace {
+
+constexpr const int kIconifyTimeout = 500;
+constexpr const char kFeatureShellAppWidget[] =
+    "http://tizen.org/feature/shell.appwidget";
+constexpr int APP_EVENT_MAX = 7;
+constexpr IAppCore::IEvent::Type __app_event_converter[APP_EVENT_MAX] = {
+  [APP_EVENT_LOW_MEMORY] = IAppCore::IEvent::Type::LOW_MEMORY,
+  [APP_EVENT_LOW_BATTERY] = IAppCore::IEvent::Type::LOW_BATTERY,
+  [APP_EVENT_LANGUAGE_CHANGED] = IAppCore::IEvent::Type::LANG_CHANGE,
+  [APP_EVENT_DEVICE_ORIENTATION_CHANGED]
+      = IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED,
+  [APP_EVENT_REGION_FORMAT_CHANGED] = IAppCore::IEvent::Type::REGION_CHANGE,
+  [APP_EVENT_SUSPENDED_STATE_CHANGED]
+      = IAppCore::IEvent::Type::SUSPENDED_STATE_CHANGE,
+};
+
+class AppWidget : public WidgetBase {
+ public:
+  AppWidget(widget_app_lifecycle_callback_s* callback, void* user_data)
+      : callback_(callback), user_data_(user_data) {}
+
+  int OnCreate() override {
+    WidgetBase::OnCreate();
+    if (callback_ && callback_->create) {
+      if (callback_->create(user_data_) == nullptr) {
+        _E("Failed to create widget");
+        return -1;
+      }
+
+      _D("Widget app is created");
+      aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
+      return 0;
+    }
+
+    return -1;
+  }
+
+  int OnTerminate() override {
+    if (callback_ && callback_->terminate) {
+      callback_->terminate(user_data_);
+      WidgetBase::OnTerminate();
+      _D("Widget app is terminated");
+      aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
+      return 0;
+    }
+
+    WidgetBase::OnTerminate();
+    return -1;
+  }
+
+  void OnLoopInit(int argc, char** argv) override {
+    elm_init(argc, argv);
+  }
+
+  void OnLoopFinish() override {
+    elm_shutdown();
+  }
+
+  void OnLoopRun() override {
+    elm_run();
+  }
+
+  void OnLoopExit() override {
+    elm_exit();
+  }
+
+  int OnTrimMemory() override {
+    _D("Trim memory");
+    elm_cache_all_flush();
+    return WidgetBase::OnTrimMemory();
+  }
+
+ private:
+  widget_app_lifecycle_callback_s* callback_;
+  void* user_data_;
+};
+
+class AppWidgetContext : public WidgetContext {
+ public:
+  class Factory : public AppCoreMultiWindowBase::Context::IFactory {
+   public:
+    Factory(std::string widget_id,
+        widget_instance_lifecycle_callback_s callback, void* user_data)
+        : widget_id_(std::move(widget_id)),
+          callback_(callback),
+          user_data_(user_data) {
+    }
+
+    std::unique_ptr<Context> Create(std::string inst_id,
+        AppCoreMultiWindowBase* app) override {
+      return std::unique_ptr<Context>(
+          new AppWidgetContext(widget_id_, std::move(inst_id), app,
+              callback_, user_data_));
+    }
+
+   private:
+    std::string widget_id_;
+    widget_instance_lifecycle_callback_s callback_;
+    void* user_data_;
+  };
+
+  AppWidgetContext(std::string context_id, std::string inst_id,
+      AppCoreMultiWindowBase* app,
+      widget_instance_lifecycle_callback_s callback, void* user_data)
+      : WidgetContext(std::move(context_id), std::move(inst_id), app),
+          callback_(callback), user_data_(user_data) {}
+
+  bool OnCreate(const tizen_base::Bundle& contents, int w, int h) override {
+    int ret = -1;
+    if (callback_.create) {
+      ret = callback_.create(reinterpret_cast<widget_context_h>(this),
+          contents.GetHandle(), w, h, user_data_);
+      aul_widget_write_log(LOG_TAG, "[%s:%d]  ret : %d",
+          __FUNCTION__, __LINE__, ret);
+    }
+
+    return ret == 0;
+  }
+
+  void OnDestroy(DestroyType reason,
+      const tizen_base::Bundle& contents) override {
+    if (callback_.destroy) {
+      callback_.destroy(reinterpret_cast<widget_context_h>(this),
+          reason == DestroyType::PERMANENT ? WIDGET_APP_DESTROY_TYPE_PERMANENT :
+          WIDGET_APP_DESTROY_TYPE_TEMPORARY, contents.GetHandle(), user_data_);
+      aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
+    }
+
+    UnsetIconifyTimer();
+  }
+
+  void OnPause() override {
+    UnsetIconifyTimer();
+    SetIconifyTimer();
+
+    WidgetContext::OnPause();
+    if (callback_.pause) {
+      callback_.pause(reinterpret_cast<widget_context_h>(this), user_data_);
+    }
+  }
+
+  void OnResume() override {
+    UnsetIconifyTimer();
+
+    if (is_iconified_) {
+      Ecore_Wl2_Window* win = ecore_evas_wayland2_window_get(
+          ecore_evas_ecore_evas_get(evas_object_evas_get(win_)));
+      if (win) {
+        ecore_wl2_window_iconified_set(win, EINA_FALSE);
+        is_iconified_ = false;
+        _D("Set iconify false");
+      }
+    }
+
+    WidgetContext::OnResume();
+    if (callback_.resume) {
+      callback_.resume(reinterpret_cast<widget_context_h>(this), user_data_);
+    }
+  }
+
+  void OnResize(int w, int h) override {
+    WidgetContext::OnResize(w, h);
+
+    if (win_)
+      evas_object_resize(win_, w, h);
+    else
+      _E("Failed to find window");
+
+    if (callback_.resize) {
+      callback_.resize(reinterpret_cast<widget_context_h>(this),
+          w, h, user_data_);
+    }
+  }
+
+  void OnUpdate(const tizen_base::Bundle& contents, bool force) override {
+    WidgetContext::OnUpdate(contents, force);
+    if (callback_.update) {
+      callback_.update(reinterpret_cast<widget_context_h>(this),
+          contents.GetHandle(), force, user_data_);
+    }
+  }
+
+  void SetTag(void* tag) {
+    tag_ = tag;
+  }
+
+  void* GetTag() const {
+    return tag_;
+  }
+
+  Evas_Object* GetWindow() const {
+    return win_;
+  }
+
+  void SetWindow(Evas_Object* win) {
+    win_ = win;
+  }
+
+ private:
+  void SetIconifyTimer() {
+    if (iconify_timer_)
+      return;
+
+    iconify_timer_ = g_timeout_add(kIconifyTimeout,
+        [](gpointer user_data) -> gboolean{
+          AppWidgetContext* cxt = static_cast<AppWidgetContext*>(user_data);
+          Ecore_Wl2_Window* win = ecore_evas_wayland2_window_get(
+              ecore_evas_ecore_evas_get(evas_object_evas_get(cxt->win_)));
+          if (win) {
+            ecore_wl2_window_iconified_set(win, EINA_TRUE);
+            cxt->is_iconified_ = true;
+            _D("Set iconify true");
+          }
+
+          cxt->iconify_timer_ = 0;
+          return G_SOURCE_REMOVE;
+        }, this);
+  }
+
+  void UnsetIconifyTimer() {
+    if (iconify_timer_) {
+      g_source_remove(iconify_timer_);
+      iconify_timer_ = 0;
+    }
+  }
+
+ private:
+  widget_instance_lifecycle_callback_s callback_;
+  void* user_data_;
+  Evas_Object* win_ = nullptr;
+  guint iconify_timer_ = 0;
+  bool is_iconified_ = false;
+  void* tag_ = nullptr;
+};
+
+std::unique_ptr<AppWidget> __app_widget;
+std::list<std::shared_ptr<AppEvent>> __pending_app_events;
+
+}  // namespace
+
+API int widget_app_main(int argc, char** argv,
+    widget_app_lifecycle_callback_s* callback, void* user_data) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (argc <= 0 || argv == nullptr || callback == nullptr) {
+    _E("Invalid parameter");
+    return WIDGET_ERROR_INVALID_PARAMETER;
+  }
+
+  if (callback->create == nullptr) {
+    _E("widget_app_create_cb() callback must be registered");
+    return WIDGET_ERROR_INVALID_PARAMETER;
+  }
+
+  try {
+    __app_widget = std::make_unique<AppWidget>(callback, user_data);
+    for (auto& i : __pending_app_events)
+      __app_widget->AddEvent(i);
+
+    __app_widget->Run(argc, argv);
+  } catch (std::runtime_error& e) {
+    return WIDGET_ERROR_FAULT;
+  }
+
+  return WIDGET_ERROR_NONE;
+}
+
+API int widget_app_exit(void) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (__app_widget.get() == nullptr)
+    return WIDGET_ERROR_FAULT;
+
+  __app_widget->Exit();
+  return WIDGET_ERROR_NONE;
+}
+
+API int widget_app_terminate_context(widget_context_h context) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (context == nullptr) {
+    _E("Invalid parameter");
+    return WIDGET_ERROR_INVALID_PARAMETER;
+  }
+
+  auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
+  cxt->ExitAsync();
+  return WIDGET_ERROR_NONE;
+}
+
+API int widget_app_foreach_context(widget_context_cb cb, void* data) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (cb == nullptr) {
+    _E("Invalid parameter");
+    return WIDGET_ERROR_INVALID_PARAMETER;
+  }
+
+  if (__app_widget.get() == nullptr)
+    return WIDGET_ERROR_FAULT;
+
+  auto l = __app_widget->GetContexts();
+  for (auto& i : l) {
+    if (!cb(reinterpret_cast<widget_context_h>(i.get()), data))
+      break;
+  }
+
+  return WIDGET_ERROR_NONE;
+}
+
+API int widget_app_add_event_handler(app_event_handler_h* event_handler,
+    app_event_type_e event_type, app_event_cb callback, void* user_data) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (event_handler == nullptr || callback == nullptr)
+    return WIDGET_ERROR_INVALID_PARAMETER;
+
+  if (event_type < APP_EVENT_LOW_MEMORY ||
+      event_type > APP_EVENT_REGION_FORMAT_CHANGED)
+    return WIDGET_ERROR_INVALID_PARAMETER;
+
+  if (event_type == APP_EVENT_DEVICE_ORIENTATION_CHANGED)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  auto* app_event = new (std::nothrow) AppEvent(
+      ::__app_event_converter[event_type], callback, user_data);
+  if (app_event == nullptr) {
+    _E("Out of memory");
+    return WIDGET_ERROR_OUT_OF_MEMORY;
+  }
+
+  auto* h = new (std::nothrow) std::shared_ptr<AppEvent>(app_event);
+  if (h == nullptr) {
+    _E("Out of memory");
+    delete app_event;
+    return WIDGET_ERROR_OUT_OF_MEMORY;
+  }
+
+  if (__app_widget.get() != nullptr)
+    __app_widget->AddEvent(*h);
+  else
+    __pending_app_events.push_back(*h);
+
+  *event_handler = reinterpret_cast<app_event_handler_h>(h);
+  return WIDGET_ERROR_NONE;
+}
+
+API int widget_app_remove_event_handler(app_event_handler_h event_handler) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (event_handler == nullptr)
+    return WIDGET_ERROR_INVALID_PARAMETER;
+
+  auto* h = reinterpret_cast<std::shared_ptr<AppEvent>*>(event_handler);
+
+  if (__app_widget.get() != nullptr) {
+    if (!__app_widget->RemoveEvent(*h))
+      return WIDGET_ERROR_INVALID_PARAMETER;
+  } else {
+    __pending_app_events.remove(*h);
+  }
+
+  delete h;
+  return WIDGET_ERROR_NONE;
+}
+
+API const char* widget_app_get_id(widget_context_h context) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0) {
+    set_last_result(WIDGET_ERROR_FAULT);
+    return nullptr;
+  }
+
+  if (!feature) {
+    set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
+    return nullptr;
+  }
+
+  if (context == nullptr) {
+    set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
+    return nullptr;
+  }
+
+  auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
+  const std::string& id = cxt->GetInstId();
+  set_last_result(WIDGET_ERROR_NONE);
+  return id.c_str();
+}
+
+API int widget_app_get_elm_win(widget_context_h context, Evas_Object** win) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (context == nullptr || win == nullptr) {
+    _E("Invalid parameter");
+    return WIDGET_ERROR_INVALID_PARAMETER;
+  }
+
+  auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
+  const std::string& id = cxt->GetInstId();
+
+  Evas_Object* ret_win = elm_win_add(nullptr, id.c_str(), ELM_WIN_BASIC);
+  if (ret_win == nullptr) {
+    _E("Failed to create window");
+    return WIDGET_ERROR_FAULT;
+  }
+
+  elm_win_wm_rotation_preferred_rotation_set(ret_win, -1);
+  int rots[3] = { 0, };
+  elm_win_wm_rotation_available_rotations_set(ret_win, rots, 1);
+
+  Ecore_Wl2_Window* wl_win = ecore_evas_wayland2_window_get(
+      ecore_evas_ecore_evas_get(evas_object_evas_get(ret_win)));
+  if (wl_win == nullptr) {
+    _E("Failed to get wayland window");
+    evas_object_del(ret_win);
+    return WIDGET_ERROR_FAULT;
+  }
+
+  ecore_wl2_window_class_set(wl_win, id.c_str());
+  elm_win_aux_hint_add(ret_win, "wm.policy.win.user.geometry", "1");
+  cxt->WindowBind(id, wl_win);
+
+  /* Set data to use in accessibility */
+  std::string plug_id = id + ":" + std::to_string(getpid());
+  evas_object_data_set(ret_win, "___PLUGID", strdup(plug_id.c_str()));
+  evas_object_event_callback_add(ret_win, EVAS_CALLBACK_DEL,
+      [](void *data, Evas *e, Evas_Object *obj, void *event_info) {
+        char* plug_id = static_cast<char*>(
+            evas_object_data_del(obj, "___PLUGID"));
+        free(plug_id);
+      }, nullptr);
+
+  int win_id = ecore_wl2_window_id_get(wl_win);
+  _D("Window created: %d", win_id);
+
+  cxt->SetWindow(ret_win);
+  *win = ret_win;
+  return WIDGET_ERROR_NONE;
+}
+
+API widget_class_h widget_app_class_add(widget_class_h widget_class,
+    const char* class_id, widget_instance_lifecycle_callback_s callback,
+    void* user_data) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0) {
+    set_last_result(WIDGET_ERROR_FAULT);
+    return nullptr;
+  }
+
+  if (!feature) {
+    set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
+    return nullptr;
+  }
+
+  if (class_id == nullptr || callback.create == nullptr) {
+    _E("Invalid parameter");
+    set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
+    return nullptr;
+  }
+
+  if (__app_widget.get() == nullptr) {
+    set_last_result(WIDGET_ERROR_FAULT);
+    return nullptr;
+  }
+
+  auto factory = std::shared_ptr<AppCoreMultiWindowBase::Context::IFactory>(
+      new (std::nothrow) AppWidgetContext::Factory(
+          class_id, callback, user_data));
+  if (factory.get() == nullptr) {
+    set_last_result(WIDGET_ERROR_OUT_OF_MEMORY);
+    return nullptr;
+  }
+
+  __app_widget->AddContextFactory(std::move(factory), class_id);
+  set_last_result(WIDGET_ERROR_NONE);
+  int dummy;
+  widget_class_h cls = reinterpret_cast<widget_class_h>(&dummy);
+  return cls;
+}
+
+API widget_class_h widget_app_class_create(
+    widget_instance_lifecycle_callback_s callback, void* user_data) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0) {
+    set_last_result(WIDGET_ERROR_FAULT);
+    return nullptr;
+  }
+
+  if (!feature) {
+    set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
+    return nullptr;
+  }
+
+  if (callback.create == nullptr) {
+    _E("Invalid parameter");
+    set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
+    return nullptr;
+  }
+
+  char* appid = nullptr;
+  app_get_id(&appid);
+  if (appid == nullptr) {
+    LOGE("app_get_id() is failed");
+    return nullptr;
+  }
+  std::unique_ptr<char, decltype(std::free)*> ptr(appid, std::free);
+
+  return static_cast<widget_class_h>(
+      widget_app_class_add(nullptr, appid, callback, user_data));
+}
+
+API int widget_app_context_set_tag(widget_context_h context, void* tag) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (context == nullptr) {
+    _E("Invalid parameter");
+    return WIDGET_ERROR_INVALID_PARAMETER;
+  }
+
+  auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
+  cxt->SetTag(tag);
+  return WIDGET_ERROR_NONE;
+}
+
+API int widget_app_context_get_tag(widget_context_h context, void** tag) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (context == nullptr || tag == nullptr) {
+    _E("Invalid parameter");
+    return WIDGET_ERROR_INVALID_PARAMETER;
+  }
+
+  auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
+  *tag = cxt->GetTag();
+  return WIDGET_ERROR_NONE;
+}
+
+API int widget_app_context_set_content_info(widget_context_h context,
+    bundle* content_info) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (context == nullptr || content_info == nullptr) {
+    _E("Invalid parameter");
+    return WIDGET_ERROR_INVALID_PARAMETER;
+  }
+
+  auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
+  ret = cxt->SetContents(tizen_base::Bundle(content_info));
+  if (ret != WIDGET_ERROR_NONE) {
+    _E("Failed to set content");
+    return static_cast<widget_error_e>(ret);
+  }
+
+  return WIDGET_ERROR_NONE;
+}
+
+API int widget_app_context_set_title(widget_context_h context,
+    const char* title) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (context == nullptr || title == nullptr) {
+    _E("Invalid parameter");
+    return WIDGET_ERROR_INVALID_PARAMETER;
+  }
+
+  auto* cxt = reinterpret_cast<AppWidgetContext*>(context);
+  if (cxt->GetWindow())
+    elm_win_title_set(cxt->GetWindow(), title);
+
+  return WIDGET_ERROR_NONE;
+}
+
+API int widget_app_restart(void) {
+  bool feature;
+  int ret = system_info_get_platform_bool(kFeatureShellAppWidget, &feature);
+  if (ret < 0)
+    return WIDGET_ERROR_FAULT;
+
+  if (!feature)
+    return WIDGET_ERROR_NOT_SUPPORTED;
+
+  if (__app_widget.get() == nullptr)
+    return WIDGET_ERROR_IO_ERROR;
+
+  std::string class_id;
+  auto l = __app_widget->GetContexts();
+  for (auto& i : l) {
+    class_id = i->GetContextId();
+    break;
+  }
+
+  if (class_id.empty())
+    return WIDGET_ERROR_IO_ERROR;
+
+  tizen_base::Bundle b;
+  int status = AUL_WIDGET_INSTANCE_EVENT_APP_RESTART_REQUEST;
+  std::vector<unsigned char> v;
+  auto* p = reinterpret_cast<const uint8_t*>(&status);
+  std::copy(p, p + sizeof(int), std::back_inserter(v));
+
+  b.Add(AUL_K_WIDGET_ID, class_id);
+  b.Add(AUL_K_WIDGET_STATUS, v);
+
+  std::string endpoint = __app_widget->GetViewerEndpoint();
+  ret = aul_app_com_send(endpoint.empty() ? nullptr : endpoint.c_str(),
+      b.GetHandle());
+  if (ret != AUL_R_OK) {
+    _E("Failed to send restart request");
+    return WIDGET_ERROR_IO_ERROR;
+  }
+
+  return WIDGET_ERROR_NONE;
+}
diff --git a/src/efl_base/widget_app_internal.c b/src/efl_base/widget_app_internal.c
deleted file mode 100644 (file)
index cbd7e4c..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
- *
- * 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 <stdlib.h>
-
-#include <glib.h>
-#include <glib-object.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <aul.h>
-#include <aul_app_com.h>
-#include <dlog.h>
-#include <appcore_multiwindow_base.h>
-
-#include "widget_app.h"
-#include "widget-log.h"
-#include "widget-private.h"
-#include "widget_app_internal.h"
-#include "widget-private.h"
-#include "widget_base.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "CAPI_WIDGET_APPLICATION"
-static char *__class_id;
-
-/* LCOV_EXCL_START */
-static void __inst_cb(const char *class_id, const char *id,
-               appcore_multiwindow_base_instance_h cxt, void *data)
-{
-       if (!__class_id)
-               __class_id = strdup(class_id);
-}
-/* LCOV_EXCL_STOP */
-
-EXPORT_API int widget_app_restart(void)
-{
-       int ret;
-       int status = AUL_WIDGET_INSTANCE_EVENT_APP_RESTART_REQUEST;
-       bundle *kb;
-
-       appcore_multiwindow_base_instance_foreach_full(__inst_cb, NULL);
-
-       kb = bundle_create();
-       bundle_add_str(kb, AUL_K_WIDGET_ID, __class_id);
-       bundle_add_byte(kb, AUL_K_WIDGET_STATUS, &status, sizeof(int));
-       ret = aul_app_com_send(widget_base_get_viewer_endpoint(), kb);
-       bundle_free(kb);
-       if (__class_id) {
-               free(__class_id);
-               __class_id = NULL;
-       }
-
-       if (ret != AUL_R_OK) {
-               _E("failed to kill app");
-               return WIDGET_ERROR_IO_ERROR;
-       }
-       return WIDGET_ERROR_NONE;
-}
-
diff --git a/src/efl_base/widget_error.c b/src/efl_base/widget_error.c
deleted file mode 100644 (file)
index cd79e5f..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2015 - 2017 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
- *
- * 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 <string.h>
-#include <libintl.h>
-
-#include <dlog.h>
-#include <widget_errno.h>
-
-#include "widget-private.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "CAPI_WIDGET_APPLICATION"
-
-static const char *widget_app_error_to_string(widget_error_e error)
-{
-       switch (error) {
-       case WIDGET_ERROR_NONE:
-               return "NONE";
-       case WIDGET_ERROR_INVALID_PARAMETER:
-               return "INVALID_PARAMETER";
-       case WIDGET_ERROR_OUT_OF_MEMORY:
-               return "OUT_OF_MEMORY"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_RESOURCE_BUSY:
-               return "RESOURCE_BUSY"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_PERMISSION_DENIED:
-               return "PERMISSION_DENIED"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_CANCELED:
-               return "CANCELED"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_IO_ERROR:
-               return "IO_ERROR"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_TIMED_OUT:
-               return "TIMED_OUT"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_NOT_SUPPORTED:
-               return "NOT_SUPPORTED"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_FILE_NO_SPACE_ON_DEVICE:
-               return "FILE_NO_SPACE_ON_DEVICE"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_FAULT:
-               return "FAULT"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_ALREADY_EXIST:
-               return "ALREADY_EXIST"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_ALREADY_STARTED:
-               return "ALREADY_STARTED"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_NOT_EXIST:
-               return "NOT_EXIST"; /* LCOV_EXCL_LINE */
-       case WIDGET_ERROR_DISABLED:
-               return "DISABLED"; /* LCOV_EXCL_LINE */
-       default:
-               return "UNKNOWN"; /* LCOV_EXCL_LINE */
-       }
-}
-
-int widget_app_error(widget_error_e error, const char *function,
-               const char *description)
-{
-       if (description) {
-               LOGE("[%s] %s(0x%08x) : %s", function,
-                               widget_app_error_to_string(error), error,
-                               description);
-       } else {
-               LOGE("[%s] %s(0x%08x)", function,
-                               widget_app_error_to_string(error), error);
-       }
-
-       return error;
-}
-
index 64fd8a4..7a2beb7 100644 (file)
@@ -1,25 +1,40 @@
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ UNIT_TESTS_SRCS)
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/mock/ UNIT_TESTS_SRCS)
-ADD_EXECUTABLE(${TARGET_WIDGET_APPLICATION_UNIT_TEST}
-  ${UNIT_TESTS_SRCS}
-)
+
+ADD_EXECUTABLE(${TARGET_WIDGET_APPLICATION_UNIT_TEST} ${UNIT_TESTS_SRCS})
 
 TARGET_INCLUDE_DIRECTORIES(${TARGET_WIDGET_APPLICATION_UNIT_TEST} PUBLIC
-  "${CMAKE_CURRENT_SOURCE_DIR}/../"
-  "${CMAKE_CURRENT_SOURCE_DIR}/../../include"
-  "${CMAKE_CURRENT_SOURCE_DIR}/../../src/efl_base"
+  ${CMAKE_CURRENT_SOURCE_DIR}/../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../include
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../src/
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../src/base
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../src/efl_base
 )
 
 APPLY_PKG_CONFIG(${TARGET_WIDGET_APPLICATION_UNIT_TEST} PUBLIC
+  APPCORE_COMMON_DEPS
+  APPCORE_MULTIWINDOW_DEPS
+  APPCORE_MULTIWINDOW_OLD_DEPS
+  AUL_DEP
+  BUNDLE_DEPS
+  CAPI_APP_COMMON_DEP
+  DLOG_DEPS
+  ECORE_WL2_DEPS
+  ELEMENTARY_DEP
   GLIB_DEPS
   GMOCK_DEPS
-  BUNDLE_DEPS
-  GOBJECT_DEPS
+  SCREEN_CONNECTOR_PROVIDER_DEPS
+  SYSTEM_INFO_DEPS
+  WIDGET_SERVICE_DEPS
 )
 
-TARGET_LINK_LIBRARIES(${TARGET_WIDGET_APPLICATION_UNIT_TEST} PUBLIC ${TARGET_WIDGET_BASE} ${TARGET_WIDGET_APPLICATION})
-SET_TARGET_PROPERTIES(${TARGET_WIDGET_APPLICATION_UNIT_TEST} PROPERTIES COMPILE_FLAGS "-fPIE")
-SET_TARGET_PROPERTIES(${TARGET_WIDGET_APPLICATION_UNIT_TEST} PROPERTIES LINK_FLAGS "-pie")
+TARGET_LINK_LIBRARIES(${TARGET_WIDGET_APPLICATION_UNIT_TEST} PUBLIC
+  ${TARGET_WIDGET_APPLICATION})
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_APPLICATION_UNIT_TEST}
+  PROPERTIES COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_APPLICATION_UNIT_TEST}
+  PROPERTIES LINK_FLAGS "-pie")
 
 ADD_TEST(
   NAME ${TARGET_WIDGET_APPLICATION_UNIT_TEST}
index 5fa214e..7219d89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
 #define UNIT_TESTS_MOCK_APP_COMMON_MOCK_H_
 
 #include <gmock/gmock.h>
-#include <appcore_multiwindow_base.h>
 
 #include "mock/module_mock.h"
 
index fe09a24..c66bd8e 100644 (file)
 #include "unit_tests/mock/mock_hook.h"
 #include "unit_tests/mock/test_fixture.h"
 
-extern "C" int appcore_multiwindow_base_init(
-        appcore_multiwindow_base_ops ops, int argc, char **argv, void *data) {
-  return MOCK_HOOK_P4(MultiWindowBaseMock, appcore_multiwindow_base_init,
-        ops, argc, argv, data);
-}
-
-extern "C" const char *appcore_multiwindow_base_instance_get_id(
-        appcore_multiwindow_base_instance_h context) {
-  return MOCK_HOOK_P1(MultiWindowBaseMock,
-        appcore_multiwindow_base_instance_get_id, context);
-}
-
-extern "C" void *appcore_multiwindow_base_instance_get_extra(
-        appcore_multiwindow_base_instance_h context) {
-  return MOCK_HOOK_P1(MultiWindowBaseMock,
-        appcore_multiwindow_base_instance_get_extra, context);
-}
-
-extern "C" const char* appcore_multiwindow_base_instance_get_class_id(
-        appcore_multiwindow_base_instance_h context) {
-  return MOCK_HOOK_P1(MultiWindowBaseMock,
-        appcore_multiwindow_base_instance_get_class_id, context);
-}
 
-extern "C" void appcore_multiwindow_base_class_add(
-        appcore_multiwindow_base_class cls) {
-  return MOCK_HOOK_P1(MultiWindowBaseMock,
-        appcore_multiwindow_base_class_add, cls);
-}
+namespace tizen_cpp {
 
-extern "C" void appcore_multiwindow_base_instance_drop(
-      appcore_multiwindow_base_instance_h context) {
-  return MOCK_HOOK_P1(MultiWindowBaseMock,
-        appcore_multiwindow_base_instance_drop, context);
+void AppCoreMultiWindowBase::Run(int argc, char** argv) {
+  TestFixture::GetMock<MultiWindowBaseMock>().real_ = this;
+  TestFixture::GetMock<MultiWindowBaseMock>().Run(argc, argv);
+  TestFixture::GetMock<MultiWindowBaseMock>().real_ = nullptr;
 }
 
-extern "C" appcore_multiwindow_base_instance_h
-      appcore_multiwindow_base_instance_find(const char *id) {
-  return MOCK_HOOK_P1(MultiWindowBaseMock,
-        appcore_multiwindow_base_instance_find, id);
+int AppCoreMultiWindowBase::OnCreate() {
+  return TestFixture::GetMock<MultiWindowBaseMock>().OnCreate();
 }
 
-extern "C" const appcore_multiwindow_base_class *
-      appcore_multiwindow_base_instance_get_class(
-            appcore_multiwindow_base_instance_h context) {
-  return MOCK_HOOK_P1(MultiWindowBaseMock,
-        appcore_multiwindow_base_instance_get_class, context);
-}
-
-extern "C" void appcore_multiwindow_base_instance_exit(
-      appcore_multiwindow_base_instance_h context) {
-  return MOCK_HOOK_P1(MultiWindowBaseMock,
-        appcore_multiwindow_base_instance_exit, context);
-}
-
-extern "C" void appcore_multiwindow_base_instance_pause(
-      appcore_multiwindow_base_instance_h context) {
-  return MOCK_HOOK_P1(MultiWindowBaseMock,
-        appcore_multiwindow_base_instance_pause, context);
-}
-
-extern "C" void appcore_multiwindow_base_instance_resume(
-      appcore_multiwindow_base_instance_h context) {
-  return MOCK_HOOK_P1(MultiWindowBaseMock,
-        appcore_multiwindow_base_instance_resume, context);
-}
+}  // namespace tizen_cpp
index 06ec917..0f044f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
 #define UNIT_TESTS_MOCK_APPCORE_MULTIWINDOW_BASE_MOCK_H_
 
 #include <gmock/gmock.h>
-#include <appcore_multiwindow_base.h>
+#include <app_core_multi_window_base.hh>
 
 #include "mock/module_mock.h"
 
@@ -26,28 +26,10 @@ class MultiWindowBaseMock : public virtual ModuleMock {
  public:
   virtual ~MultiWindowBaseMock() {}
 
-  MOCK_METHOD4(appcore_multiwindow_base_init,
-      int(appcore_multiwindow_base_ops, int, char **, void *));
-  MOCK_METHOD1(appcore_multiwindow_base_instance_get_id,
-      const char *(appcore_multiwindow_base_instance_h));
-  MOCK_METHOD1(appcore_multiwindow_base_instance_get_extra,
-      void *(appcore_multiwindow_base_instance_h));
-  MOCK_METHOD1(appcore_multiwindow_base_instance_get_class_id,
-      const char *(appcore_multiwindow_base_instance_h));
-  MOCK_METHOD1(appcore_multiwindow_base_class_add,
-      void(appcore_multiwindow_base_class));
-  MOCK_METHOD1(appcore_multiwindow_base_instance_drop,
-      void(appcore_multiwindow_base_instance_h));
-  MOCK_METHOD1(appcore_multiwindow_base_instance_find,
-      appcore_multiwindow_base_instance_h(const char *));
-  MOCK_METHOD1(appcore_multiwindow_base_instance_get_class,
-      const appcore_multiwindow_base_class *(appcore_multiwindow_base_instance_h));
-  MOCK_METHOD1(appcore_multiwindow_base_instance_exit,
-      void(appcore_multiwindow_base_instance_h));
-  MOCK_METHOD1(appcore_multiwindow_base_instance_pause,
-      void(appcore_multiwindow_base_instance_h));
-  MOCK_METHOD1(appcore_multiwindow_base_instance_resume,
-      void(appcore_multiwindow_base_instance_h));
+  MOCK_METHOD2(Run, void(int, char**));
+  MOCK_METHOD0(OnCreate, int());
+
+  tizen_cpp::AppCoreMultiWindowBase* real_ = nullptr;
 };
 
 #endif  // UNIT_TESTS_MOCK_APPCORE_MULTIWINDOW_BASE_MOCK_H_
index 76ed247..65f947c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include "unit_tests/mock/mock_hook.h"
 #include "unit_tests/mock/test_fixture.h"
 
-extern "C" int aul_app_get_pkgid_bypid(int pid, char *pkgid, int len) {
+extern "C" int aul_app_get_appid_bypid(int pid, char* appid, int len) {
+  return MOCK_HOOK_P3(AulMock, aul_app_get_appid_bypid, pid, appid, len);
+}
+
+extern "C" int aul_app_get_pkgid_bypid(int pid, char* pkgid, int len) {
   return MOCK_HOOK_P3(AulMock, aul_app_get_pkgid_bypid, pid, pkgid, len);
 }
+
+extern "C" int aul_widget_send_status_to_service(const char* class_id,
+    const char *instance_id, const char *sender_pkgid, int status) {
+  return MOCK_HOOK_P4(AulMock, aul_widget_send_status_to_service,
+      class_id, instance_id, sender_pkgid, status);
+}
+
+extern "C" int aul_widget_send_status_to_viewer(const char* class_id,
+    const char *instance_id, const char *viewer_endpoint,
+    int status, int err, bundle *extra) {
+  return MOCK_HOOK_P6(AulMock, aul_widget_send_status_to_viewer,
+      class_id, instance_id, viewer_endpoint, status, err, extra);
+}
+
+extern "C" int aul_notify_exit(void) {
+  return MOCK_HOOK_P0(AulMock, aul_notify_exit);
+}
+
+extern "C" int aul_widget_write_log(const char* tag, const char* format, ...) {
+  return 0;
+}
+
+extern "C" int aul_widget_instance_del(const char* widget_id,
+    const char* instance_id) {
+  return 0;
+}
+
+extern "C" int aul_status_update(int status) {
+  return 0;
+}
index 359db71..ef0f1e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@
 #define UNIT_TESTS_MOCK_AUL_MOCK_H_
 
 #include <gmock/gmock.h>
-#include <appcore_multiwindow_base.h>
+#include <bundle.h>
 
 #include "mock/module_mock.h"
 
@@ -26,7 +26,13 @@ class AulMock : public virtual ModuleMock {
  public:
   virtual ~AulMock() {}
 
+  MOCK_METHOD3(aul_app_get_appid_bypid, int (int , char *, int));
   MOCK_METHOD3(aul_app_get_pkgid_bypid, int (int , char *, int));
+  MOCK_METHOD4(aul_widget_send_status_to_service, int (const char*,
+      const char*, const char*, int));
+  MOCK_METHOD6(aul_widget_send_status_to_viewer, int (const char*,
+      const char*, const char*, int, int, bundle*));
+  MOCK_METHOD0(aul_notify_exit, int ());
 };
 
 #endif  // UNIT_TESTS_MOCK_AUL_MOCK_H_
index 05bf369..632e754 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include "unit_tests/mock/test_fixture.h"
 
 
-extern "C" Evas_Object * elm_win_add(Evas_Object *parent,
-        const char *name, Elm_Win_Type type) {
+extern "C" Evas_Object* elm_win_add(Evas_Object* parent,
+        const charname, Elm_Win_Type type) {
   return MOCK_HOOK_P3(ElmMock, elm_win_add, parent, name, type);
 }
 
 extern "C" void elm_win_wm_rotation_preferred_rotation_set(
-        Evas_Object *obj, int rotation) {
+        Evas_Objectobj, int rotation) {
   return MOCK_HOOK_P2(
           ElmMock, elm_win_wm_rotation_preferred_rotation_set, obj, rotation);
 }
 
-extern "C" void elm_win_wm_rotation_available_rotations_set(Elm_Win *obj,
-        const int *rotations, unsigned int count) {
+extern "C" void elm_win_wm_rotation_available_rotations_set(Elm_Winobj,
+        const introtations, unsigned int count) {
   return MOCK_HOOK_P3(
           ElmMock, elm_win_wm_rotation_available_rotations_set,
           obj, rotations, count);
 }
 
-extern "C" int elm_win_aux_hint_add(Evas_Object *obj,
-        const char *hint, const char *val) {
+extern "C" int elm_win_aux_hint_add(Evas_Objectobj,
+        const char* hint, const char* val) {
   return MOCK_HOOK_P3(ElmMock, elm_win_aux_hint_add, obj, hint, val);
 }
+
+extern "C" void elm_exit(void) {
+}
diff --git a/test/unit_tests/mock/widget_service_mock.cc b/test/unit_tests/mock/widget_service_mock.cc
new file mode 100644 (file)
index 0000000..36803b4
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 "unit_tests/mock/widget_service_mock.h"
+
+#include <gio/gio.h>
+
+#include "unit_tests/mock/mock_hook.h"
+#include "unit_tests/mock/test_fixture.h"
+
+extern "C" int widget_instance_convert_event_to_lifecycle_status(int event) {
+  return MOCK_HOOK_P1(WidgetServiceMock,
+      widget_instance_convert_event_to_lifecycle_status, event);
+}
diff --git a/test/unit_tests/mock/widget_service_mock.h b/test/unit_tests/mock/widget_service_mock.h
new file mode 100644 (file)
index 0000000..477777f
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 UNIT_TESTS_MOCK_WIDGET_SERVICE_MOCK_H_
+#define UNIT_TESTS_MOCK_WIDGET_SERVICE_MOCK_H_
+
+#include <gmock/gmock.h>
+
+#include "mock/module_mock.h"
+
+class WidgetServiceMock : public virtual ModuleMock {
+ public:
+  virtual ~WidgetServiceMock() {}
+
+  MOCK_METHOD1(widget_instance_convert_event_to_lifecycle_status, int (int));
+};
+
+#endif  // UNIT_TESTS_MOCK_WIDGET_SERVICE_MOCK_H_
+
index 3b3d2dc..7c73261 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
-#include <stdlib.h>
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
 #include <bundle_cpp.h>
 #include <bundle_internal.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <stdlib.h>
 
 #include <iostream>
 #include <memory>
 
-#include "widget_app.h"
-#include "widget_app_efl.h"
-#include "unit_tests/mock/gio_mock.h"
-#include "unit_tests/mock/ecore_wl2_mock.h"
-#include "unit_tests/mock/system_info_mock.h"
-#include "unit_tests/mock/appcore_multiwindow_base_mock.h"
+#include "include/widget_app.h"
+#include "include/widget_app_efl.h"
 #include "unit_tests/mock/app_common_mock.h"
-#include "unit_tests/mock/elm_mock.h"
+#include "unit_tests/mock/appcore_multiwindow_base_mock.h"
 #include "unit_tests/mock/aul_mock.h"
+#include "unit_tests/mock/ecore_wl2_mock.h"
+#include "unit_tests/mock/elm_mock.h"
+#include "unit_tests/mock/gio_mock.h"
+#include "unit_tests/mock/system_info_mock.h"
 #include "unit_tests/mock/test_fixture.h"
+#include "unit_tests/mock/widget_service_mock.h"
 
 using ::testing::_;
 using ::testing::DoAll;
@@ -40,41 +41,7 @@ using ::testing::Return;
 using ::testing::SetArgPointee;
 using ::testing::Invoke;
 
-typedef struct _widget_base_instance_data {
-  bundle* args;
-  char* id;
-  char* content;
-  void* tag;
-  double period;
-  guint periodic_timer;
-  bool pending_update;
-  char* pending_content;
-  void* user_data;
-} widget_base_instance_data;
-
-struct _widget_context {
-  int context;
-};
-
-class Mocks : public ::testing::NiceMock<GioMock>,
-              public ::testing::NiceMock<MultiWindowBaseMock>,
-              public ::testing::NiceMock<AppCommonMock>,
-              public ::testing::NiceMock<ElmMock>,
-              public ::testing::NiceMock<AulMock>,
-              public ::testing::NiceMock<SystemInfoMock>,
-              public ::testing::NiceMock<EcoreWl2Mock> {};
-
-class WidgetAppTest : public TestFixture {
- public:
-  WidgetAppTest() : TestFixture(std::make_unique<Mocks>()) {}
-  virtual ~WidgetAppTest() {}
-
-  virtual void SetUp() {
-  }
-
-  virtual void TearDown() {
-  }
-};
+namespace {
 
 int __instance_create_cb(widget_context_h context, bundle* content,
     int w, int h, void* user_data) {
@@ -104,10 +71,6 @@ int __instance_update_cb(widget_context_h context,
   return 0;
 }
 
-widget_class_h __app_create_cb(void* user_data) {
-  return nullptr;
-}
-
 void __app_terminate_cb(void* user_data) {
 }
 
@@ -116,187 +79,178 @@ int __app_get_id_fake(char** id) {
   return 0;
 }
 
-int __aul_app_get_pkgid_bypid_fake(int pid, char* pkgid, int len) {
-  snprintf(pkgid, 10, "%s", "test");
+int __aul_app_get_appid_bypid_fake(int pid, char* appid, int len) {
+  snprintf(appid, len, "%s", "test");
   return 0;
 }
 
-struct instance_data {
-  Evas_Object* win;
-  guint iconify_timer;
-  bool is_iconified;
-};
-
-void* __appcore_multiwindow_base_instance_get_extra_fake(
-    appcore_multiwindow_base_instance_h handle) {
-  widget_base_instance_data* data = (widget_base_instance_data*)
-      calloc(1, sizeof(widget_base_instance_data));
-  data->args = bundle_create();
-  bundle_add_str(data->args, "__AUL_WIDGET_ID__", "test");
-  bundle_add_str(data->args, "__WIDGET_OP__", "optest");
-  bundle_add_str(data->args, "__WIDGET_WIDTH__", "320");
-  bundle_add_str(data->args, "__WIDGET_HEIGHT__", "320");
-  data->pending_content = strdup("test");
-  data->content = strdup("test");
-  data->id = strdup("id");
-  data->user_data = calloc(1, sizeof (struct instance_data));
-
-  return data;
-}
-
-const char* __appcore_multiwindow_base_instance_get_id_fake(
-    appcore_multiwindow_base_instance_h handle) {
-  return strdup("test");
+int __aul_app_get_pkgid_bypid_fake(int pid, char* pkgid, int len) {
+  snprintf(pkgid, len, "%s", "test");
+  return 0;
 }
 
-const char* __appcore_multiwindow_base_instance_get_class_id_fake(
-    appcore_multiwindow_base_instance_h context) {
-  return strdup("test");
+void __app_event_cb(app_event_info_h event_info, void *user_data) {
 }
 
-appcore_multiwindow_base_class __cls;
-void __appcore_multiwindow_base_class_add_fake(
-    appcore_multiwindow_base_class cls) {
-  __cls = cls;
-  cls.create(nullptr, nullptr);
-  cls.terminate(nullptr, nullptr);
-  cls.pause((appcore_multiwindow_base_instance_h)
-      calloc(1, sizeof(char)), nullptr);
-  cls.resume((appcore_multiwindow_base_instance_h)
-      calloc(1, sizeof(char)), nullptr);
+bool __widget_context_cb(widget_context_h context, void *user_data) {
+  return true;
 }
 
-int __appcore_multiwindow_base_init_fake(appcore_multiwindow_base_ops ops,
-    int argc, char** argv, void* data) {
-  tizen_base::Bundle b;
-
-  b.Add("__WIDGET_WIDTH__", "320");
-  b.Add("__WIDGET_HEIGHT__", "320");
-  b.Add("__AUL_WIDGET_INSTANCE_ID__", "instance_id");
-  b.Add("__AUL_WIDGET_ID__", "test");
-  b.Add("__WIDGET_OP__", "create");
-  ops.base.control(b.GetHandle(), nullptr);
-
-  b.Delete("__WIDGET_OP__");
-  b.Add("__WIDGET_OP__", "resize");
-  ops.base.control(b.GetHandle(), nullptr);
+}  // namespace
 
-  b.Delete("__WIDGET_OP__");
-  b.Add("__WIDGET_OP__", "update");
-  ops.base.control(b.GetHandle(), nullptr);
-
-  b.Delete("__WIDGET_OP__");
-  b.Add("__WIDGET_OP__", "destroy");
-  ops.base.control(b.GetHandle(), nullptr);
-
-  b.Delete("__WIDGET_OP__");
-  b.Add("__WIDGET_OP__", "resume");
-  ops.base.control(b.GetHandle(), nullptr);
-
-  b.Delete("__WIDGET_OP__");
-  b.Add("__WIDGET_OP__", "pause");
-  ops.base.control(b.GetHandle(), nullptr);
-
-  b.Delete("__WIDGET_OP__");
-  b.Add("__WIDGET_OP__", "terminate");
-  ops.base.control(b.GetHandle(), nullptr);
-
-  b.Delete("__WIDGET_OP__");
-  b.Add("__WIDGET_OP__", "period");
-  ops.base.control(b.GetHandle(), nullptr);
+class Mocks : public ::testing::NiceMock<GioMock>,
+              public ::testing::NiceMock<MultiWindowBaseMock>,
+              public ::testing::NiceMock<AppCommonMock>,
+              public ::testing::NiceMock<WidgetServiceMock>,
+              public ::testing::NiceMock<ElmMock>,
+              public ::testing::NiceMock<AulMock>,
+              public ::testing::NiceMock<SystemInfoMock>,
+              public ::testing::NiceMock<EcoreWl2Mock> {};
 
-  ops.base.create(nullptr);
-  ops.base.terminate(nullptr);
+class WidgetAppTest : public TestFixture {
+ public:
+  WidgetAppTest() : TestFixture(std::make_unique<Mocks>()) {}
+  virtual ~WidgetAppTest() {}
 
-  return 0;
-}
+  virtual void SetUp() {
+  }
 
-TEST_F(WidgetAppTest, widget_app_main) {
-  tizen_base::Bundle b;
-  b.Add("__AUL_WIDGET_VIEWER__", "test");
-  int ret = bundle_add_str(b.GetHandle(), "KEY", "VALUE");
-  ASSERT_EQ(ret, BUNDLE_ERROR_NONE);
+  virtual void TearDown() {
+  }
 
-  char** argv = nullptr;
-  int argc = bundle_export_to_argv(b.GetHandle(), &argv);
-  ASSERT_EQ(get_last_result(), BUNDLE_ERROR_NONE);
-  ASSERT_NE(argv, nullptr);
-  ASSERT_NE(argc, 0);
+  void PrepareTest(widget_app_create_cb created_cb, void* data) {
+    tizen_base::Bundle b;
+    b.Add("__AUL_WIDGET_VIEWER__", "test");
+    int ret = bundle_add_str(b.GetHandle(), "KEY", "VALUE");
+    ASSERT_EQ(ret, BUNDLE_ERROR_NONE);
+
+    char** argv = nullptr;
+    int argc = bundle_export_to_argv(b.GetHandle(), &argv);
+    ASSERT_EQ(get_last_result(), BUNDLE_ERROR_NONE);
+    ASSERT_NE(argv, nullptr);
+    ASSERT_NE(argc, 0);
+
+    widget_app_lifecycle_callback_s callback;
+    callback.create = created_cb;
+    callback.terminate = __app_terminate_cb;
+
+    EXPECT_CALL(GetMock<SystemInfoMock>(),
+        system_info_get_platform_bool(_, _)).
+            WillRepeatedly(DoAll(SetArgPointee<1>(true), Return(0)));
+
+    EXPECT_CALL(GetMock<AulMock>(),
+        aul_app_get_appid_bypid(_, _, _)).
+            WillOnce(Invoke(__aul_app_get_appid_bypid_fake));
+    EXPECT_CALL(GetMock<AulMock>(),
+        aul_app_get_pkgid_bypid(_, _, _)).
+            WillOnce(Invoke(__aul_app_get_pkgid_bypid_fake));
+    EXPECT_CALL(GetMock<AulMock>(),
+        aul_widget_send_status_to_service(_, _, _, _)).
+            WillRepeatedly(Return(0));
+    EXPECT_CALL(GetMock<AulMock>(),
+        aul_widget_send_status_to_viewer(_, _, _, _, _, _)).
+            WillRepeatedly(Return(0));
+    EXPECT_CALL(GetMock<WidgetServiceMock>(),
+        widget_instance_convert_event_to_lifecycle_status(_)).
+            WillRepeatedly(Return(0));
+
+    EXPECT_CALL(GetMock<AppCommonMock>(),
+        app_get_id(_)).WillRepeatedly(Invoke(__app_get_id_fake));
+
+    EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
+        Run(_, _)).WillOnce(Invoke(this, &WidgetAppTest::__run_fake));
+
+    ret = widget_app_main(argc, argv, &callback, data);
+    bundle_free_exported_argv(argc, &argv);
+    EXPECT_EQ(ret, WIDGET_ERROR_NONE);
+  }
 
-  widget_app_lifecycle_callback_s callback;
-  callback.create = __app_create_cb;
-  callback.terminate = __app_terminate_cb;
+  void PrepareContext(widget_instance_create_cb created_cb) {
+    PrepareTest([](void* user_data) -> widget_class_h {
+      widget_instance_lifecycle_callback_s lifecycle;
+      lifecycle.create = reinterpret_cast<widget_instance_create_cb>(user_data);
+      lifecycle.destroy = __instance_destroy_cb;
+      lifecycle.pause = __instance_pause_cb;
+      lifecycle.resume = __instance_resume_cb;
+      lifecycle.resize = __instance_resize_cb;
+      lifecycle.update = __instance_update_cb;
+      widget_class_h cls = widget_app_class_create(lifecycle, nullptr);
+      EXPECT_NE(cls, nullptr);
+      return cls;
+    }, reinterpret_cast<void*>(created_cb));
+  }
 
-  EXPECT_CALL(GetMock<EcoreWl2Mock>(), ecore_wl2_display_disconnect(_)).
-       Times(1);
+  void __run_fake(int argc, char** argv) {
+    tizen_base::Bundle b;
+    auto* p = GetMock<MultiWindowBaseMock>().real_;
 
-  EXPECT_CALL(GetMock<EcoreWl2Mock>(), ecore_wl2_shutdown()).
-       Times(1);
+    p->OnCreate();
 
-  EXPECT_CALL(GetMock<SystemInfoMock>(),
-      system_info_get_platform_bool(_, _)).
-          WillOnce(DoAll(
-                  SetArgPointee<1>(true),
-                  Return(0)));
+    b.Add("__WIDGET_WIDTH__", "320");
+    b.Add("__WIDGET_HEIGHT__", "320");
+    b.Add("__AUL_WIDGET_INSTANCE_ID__", "instance_id");
+    b.Add("__AUL_WIDGET_ID__", "test");
+    b.Add("__WIDGET_OP__", "create");
+    p->OnControl(b);
 
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_init(_, _, _, _)).
-          WillOnce(Invoke(__appcore_multiwindow_base_init_fake));
+    b.Delete("__WIDGET_OP__");
+    b.Add("__WIDGET_OP__", "resize");
+    p->OnControl(b);
 
-  EXPECT_CALL(GetMock<AulMock>(),
-      aul_app_get_pkgid_bypid(_, _, _)).
-          WillOnce(Invoke(__aul_app_get_pkgid_bypid_fake));
+    b.Delete("__WIDGET_OP__");
+    b.Add("__WIDGET_OP__", "update");
+    p->OnControl(b);
 
-  EXPECT_CALL(GetMock<AppCommonMock>(), app_get_id(_)).
-          WillOnce(Invoke(__app_get_id_fake));
+    b.Delete("__WIDGET_OP__");
+    b.Add("__WIDGET_OP__", "destroy");
+    p->OnControl(b);
 
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_find(_)).
-          WillRepeatedly(
-            Return(
-              (appcore_multiwindow_base_instance_h)calloc(1, sizeof(char))));
+    b.Delete("__WIDGET_OP__");
+    b.Add("__WIDGET_OP__", "resume");
+    p->OnControl(b);
 
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_class(_)).
-          WillRepeatedly(
-            Return(&__cls));
+    b.Delete("__WIDGET_OP__");
+    b.Add("__WIDGET_OP__", "pause");
+    p->OnControl(b);
 
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_extra(_)).
-      WillRepeatedly(
-        Invoke(__appcore_multiwindow_base_instance_get_extra_fake));
+    b.Delete("__WIDGET_OP__");
+    b.Add("__WIDGET_OP__", "terminate");
+    p->OnControl(b);
 
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_exit(_)).Times(2);
+    b.Delete("__WIDGET_OP__");
+    b.Add("__WIDGET_OP__", "period");
+    p->OnControl(b);
 
-  ret = widget_app_main(argc, argv, &callback, nullptr);
-  bundle_free_exported_argv(argc, &argv);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
-}
+    p->OnTerminate();
+  }
+};
 
-TEST_F(WidgetAppTest, widget_app_exit) {
+TEST_F(WidgetAppTest, widget_app_exit_n) {
   int ret = widget_app_exit();
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
-}
-
-TEST_F(WidgetAppTest, widget_app_terminate_context) {
-  widget_context_h context =
-      (widget_context_h)calloc(1, sizeof(struct _widget_context));
-  int ret = widget_app_terminate_context(context);
-  free(context);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
-}
-
-bool __widget_context_cb(widget_context_h context, void *user_data) {
-  return true;
+  EXPECT_NE(ret, WIDGET_ERROR_NONE);
 }
 
-TEST_F(WidgetAppTest, widget_app_foreach_context) {
-  int ret = widget_app_foreach_context(__widget_context_cb, nullptr);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
+TEST_F(WidgetAppTest, widget_app_exit) {
+  PrepareContext(
+      [](widget_context_h context, bundle* content,
+          int w, int h, void* user_data) -> int {
+        EXPECT_CALL(GetMock<AulMock>(),
+            aul_notify_exit()).WillRepeatedly(Return(0));
+        int ret = widget_app_exit();
+        EXPECT_EQ(ret, WIDGET_ERROR_NONE);
+        return 0;
+      });
 }
 
-void __app_event_cb(app_event_info_h event_info, void *user_data) {
+TEST_F(WidgetAppTest, widget_app_main) {
+  PrepareContext(
+      [](widget_context_h context, bundle* content,
+          int w, int h, void* user_data) -> int {
+        EXPECT_CALL(GetMock<AulMock>(),
+            aul_notify_exit()).WillRepeatedly(Return(0));
+        widget_app_exit();
+        return 0;
+      });
 }
 
 TEST_F(WidgetAppTest, widget_app_add_event_handler) {
@@ -308,7 +262,7 @@ TEST_F(WidgetAppTest, widget_app_add_event_handler) {
                   Return(0)));
   int ret = widget_app_add_event_handler(&handle, APP_EVENT_LOW_MEMORY,
       __app_event_cb, nullptr);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
+  EXPECT_EQ(ret, WIDGET_ERROR_NONE);
 }
 
 TEST_F(WidgetAppTest, widget_app_remove_event_handler) {
@@ -321,195 +275,158 @@ TEST_F(WidgetAppTest, widget_app_remove_event_handler) {
   int ret = widget_app_add_event_handler(&handle, APP_EVENT_LOW_MEMORY,
       __app_event_cb, nullptr);
   ret = widget_app_remove_event_handler(handle);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
+  EXPECT_EQ(ret, WIDGET_ERROR_NONE);
 }
 
-TEST_F(WidgetAppTest, widget_app_get_id) {
-  widget_context_h context =
-      (widget_context_h)calloc(1, sizeof(struct _widget_context));
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_id(_)).
-          WillOnce(Return("test"));
-
-  const char *id = widget_app_get_id(context);
-  free(context);
-  EXPECT_STREQ(id, "test");
+TEST_F(WidgetAppTest, widget_app_terminate_context) {
+  PrepareContext([](widget_context_h context, bundle* content,
+      int w, int h, void* user_data) -> int {
+        int ret = widget_app_terminate_context(context);
+        EXPECT_EQ(ret, WIDGET_ERROR_NONE);
+        return 0;
+      });
 }
 
-TEST_F(WidgetAppTest, widget_app_class_create) {
-  widget_instance_lifecycle_callback_s lifecycle;
+TEST_F(WidgetAppTest, widget_app_foreach_context) {
+  PrepareTest([](void* user_data) -> widget_class_h {
+    widget_instance_lifecycle_callback_s lifecycle;
+    lifecycle.create = __instance_create_cb;
+    lifecycle.destroy = __instance_destroy_cb;
+    lifecycle.pause = __instance_pause_cb;
+    lifecycle.resume = __instance_resume_cb;
+    lifecycle.resize = __instance_resize_cb;
+    lifecycle.update = __instance_update_cb;
 
-  lifecycle.create = __instance_create_cb;
-  lifecycle.destroy = __instance_destroy_cb;
-  lifecycle.pause = __instance_pause_cb;
-  lifecycle.resume = __instance_resume_cb;
-  lifecycle.resize = __instance_resize_cb;
-  lifecycle.update = __instance_update_cb;
+    widget_class_h cls = widget_app_class_create(lifecycle, nullptr);
+    EXPECT_NE(cls, nullptr);
 
-  EXPECT_CALL(GetMock<AppCommonMock>(), app_get_id(_)).
-          WillOnce(Invoke(__app_get_id_fake));
+    int ret = widget_app_foreach_context(__widget_context_cb, nullptr);
+    EXPECT_EQ(ret, WIDGET_ERROR_NONE);
 
-  widget_class_h cls = widget_app_class_create(lifecycle, nullptr);
-  EXPECT_NE(nullptr, cls);
+    return cls;
+  }, nullptr);
 }
 
-TEST_F(WidgetAppTest, widget_app_context_set_tag) {
-  widget_context_h context =
-      (widget_context_h)calloc(1, sizeof(struct _widget_context));
+TEST_F(WidgetAppTest, widget_app_get_id) {
+  PrepareContext(
+      [](widget_context_h context, bundle* content,
+          int w, int h, void* user_data) -> int {
+        const char *id = widget_app_get_id(context);
+        EXPECT_STREQ(id, "instance_id");
+        return 0;
+      });
+}
 
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_extra(_)).
-      WillOnce(Invoke(__appcore_multiwindow_base_instance_get_extra_fake));
+TEST_F(WidgetAppTest, widget_app_class_create) {
+  PrepareContext(__instance_create_cb);
+}
 
-  int ret = widget_app_context_set_tag(context, (void*)"test");
-  free(context);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
+TEST_F(WidgetAppTest, widget_app_context_set_tag) {
+  PrepareContext(
+      [](widget_context_h context, bundle* content,
+          int w, int h, void* user_data) -> int {
+        int ret = widget_app_context_set_tag(context,
+            reinterpret_cast<void*>(const_cast<char*>("test")));
+        EXPECT_EQ(ret, WIDGET_ERROR_NONE);
+        return 0;
+      });
 }
 
 TEST_F(WidgetAppTest, widget_app_context_get_tag) {
-  widget_context_h context =
-      (widget_context_h)calloc(1, sizeof(struct _widget_context));
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_extra(_)).
-      WillOnce(Invoke(__appcore_multiwindow_base_instance_get_extra_fake));
-
-  void* tag;
-  int ret = widget_app_context_get_tag(context, &tag);
-  free(context);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
+  PrepareContext(
+      [](widget_context_h context, bundle* content,
+          int w, int h, void* user_data) -> int {
+        int ret = widget_app_context_set_tag(context,
+            reinterpret_cast<void*>(const_cast<char*>("test")));
+        EXPECT_EQ(ret, WIDGET_ERROR_NONE);
+        void* tag = nullptr;
+        ret = widget_app_context_get_tag(context, &tag);
+        EXPECT_EQ(ret, WIDGET_ERROR_NONE);
+        return 0;
+      });
 }
 
 TEST_F(WidgetAppTest, widget_app_context_set_content_info) {
-  widget_context_h context =
-      (widget_context_h)calloc(1, sizeof(struct _widget_context));
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_extra(_)).
-      WillOnce(Invoke(__appcore_multiwindow_base_instance_get_extra_fake));
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_id(_)).
-      WillOnce(Invoke(__appcore_multiwindow_base_instance_get_id_fake));
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_class_id(_)).
-      WillOnce(Invoke(__appcore_multiwindow_base_instance_get_class_id_fake));
-
-  bundle* content_info = bundle_create();
-  int ret = widget_app_context_set_content_info(context, content_info);
-  free(context);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
+  PrepareContext(
+      [](widget_context_h context, bundle* content,
+          int w, int h, void* user_data) -> int {
+        bundle* content_info = bundle_create();
+        EXPECT_NE(content_info, nullptr);
+        int ret = widget_app_context_set_content_info(context, content_info);
+        bundle_free(content_info);
+        EXPECT_EQ(ret, WIDGET_ERROR_NONE);
+        return 0;
+      });
 }
 
 TEST_F(WidgetAppTest, widget_app_context_set_title) {
-  widget_context_h context =
-      (widget_context_h)calloc(1, sizeof(struct _widget_context));
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_extra(_)).
-      WillRepeatedly(Invoke(__appcore_multiwindow_base_instance_get_extra_fake));
-
-  int ret = widget_app_context_set_title(context, "title");
-  free(context);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
+  PrepareContext(
+      [](widget_context_h context, bundle* content,
+          int w, int h, void* user_data) -> int {
+        int ret = widget_app_context_set_title(context, "title");
+        EXPECT_EQ(ret, WIDGET_ERROR_NONE);
+        return 0;
+      });
 }
 
 TEST_F(WidgetAppTest, widget_app_class_add) {
-  widget_instance_lifecycle_callback_s lifecycle;
-  lifecycle.create = __instance_create_cb;
-  lifecycle.destroy = __instance_destroy_cb;
-  lifecycle.pause = __instance_pause_cb;
-  lifecycle.resume = __instance_resume_cb;
-  lifecycle.resize = __instance_resize_cb;
-  lifecycle.update = __instance_update_cb;
-
-  widget_class_h cls = widget_app_class_add(
-      nullptr, "test", lifecycle, nullptr);
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_class_add(_)).
-      WillOnce(Invoke(__appcore_multiwindow_base_class_add_fake));
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_extra(_)).
-      WillRepeatedly(Invoke(__appcore_multiwindow_base_instance_get_extra_fake));
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_class_id(_)).
-      WillRepeatedly(Invoke(__appcore_multiwindow_base_instance_get_class_id_fake));
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_drop(_)).
-      Times(1);
-
-  cls = widget_app_class_add(
-      nullptr, "test", lifecycle, nullptr);
-  EXPECT_NE(nullptr, cls);
-
-  tizen_base::Bundle b;
-  b.Add("__AUL_WIDGET_VIEWER__", "test");
-  int ret = bundle_add_str(b.GetHandle(), "KEY", "VALUE");
-  ASSERT_EQ(ret, BUNDLE_ERROR_NONE);
-
-  char** argv = nullptr;
-  int argc = bundle_export_to_argv(b.GetHandle(), &argv);
-  ASSERT_EQ(get_last_result(), BUNDLE_ERROR_NONE);
-  ASSERT_NE(argv, nullptr);
-  ASSERT_NE(argc, 0);
-
-  widget_app_lifecycle_callback_s callback;
-  callback.create = __app_create_cb;
-  callback.terminate = __app_terminate_cb;
-
-  ret = widget_app_main(argc, argv, &callback, nullptr);
-  bundle_free_exported_argv(argc, &argv);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
+  PrepareTest(
+      [](void* user_data) -> widget_class_h {
+        widget_instance_lifecycle_callback_s lifecycle;
+        lifecycle.create = __instance_create_cb;
+        lifecycle.destroy = __instance_destroy_cb;
+        lifecycle.pause = __instance_pause_cb;
+        lifecycle.resume = __instance_resume_cb;
+        lifecycle.resize = __instance_resize_cb;
+        lifecycle.update = __instance_update_cb;
+
+        widget_class_h cls = widget_app_class_add(
+            nullptr, "test", lifecycle, nullptr);
+        EXPECT_NE(cls, nullptr);
+        return cls;
+    }, nullptr);
 }
 
 TEST_F(WidgetAppTest, widget_app_get_elm_win_negative) {
-  Evas_Object* win;
-  widget_context_h context =
-      (widget_context_h)calloc(1, sizeof(struct _widget_context));
-  int ret = widget_app_get_elm_win(context, &win);
-  free(context);
-  EXPECT_EQ(WIDGET_ERROR_FAULT, ret);
+  PrepareContext(
+      [](widget_context_h context, bundle* content,
+          int w, int h, void* user_data) -> int {
+        Evas_Object* win = nullptr;
+        int ret = widget_app_get_elm_win(context, &win);
+        EXPECT_EQ(ret, WIDGET_ERROR_FAULT);
+        return 0;
+      });
 }
 
 TEST_F(WidgetAppTest, widget_app_get_elm_win) {
-  EXPECT_CALL(GetMock<ElmMock>(),
-      elm_win_add(_, _, _)).
-      WillOnce(Return((Evas_Object*)calloc(1, sizeof(char))));
-
-  EXPECT_CALL(GetMock<EcoreWl2Mock>(),
-      ecore_evas_wayland2_window_get(_)).
-      WillOnce(Return((Ecore_Wl2_Window*)calloc(1, sizeof(char))));
-
-  EXPECT_CALL(GetMock<ElmMock>(),
-      elm_win_aux_hint_add(_, _, _)).
-      WillOnce(Return(0));
-
-  EXPECT_CALL(GetMock<EcoreWl2Mock>(),
-      ecore_wl2_window_surface_get(_)).
-      WillOnce(Return(nullptr));
-
-  EXPECT_CALL(GetMock<EcoreWl2Mock>(),
-      evas_object_event_callback_add(_, _, _, _)).
-      Times(1);
-
-  EXPECT_CALL(GetMock<EcoreWl2Mock>(),
-      evas_object_data_set(_, _, _)).
-      Times(1);
-
-  EXPECT_CALL(GetMock<MultiWindowBaseMock>(),
-      appcore_multiwindow_base_instance_get_extra(_)).
-      WillRepeatedly(Invoke(__appcore_multiwindow_base_instance_get_extra_fake));
-
-  Evas_Object* win;
-  widget_context_h context =
-      (widget_context_h)calloc(1, sizeof(struct _widget_context));
-  int ret = widget_app_get_elm_win(context, &win);
-  free(context);
-  EXPECT_EQ(WIDGET_ERROR_NONE, ret);
+  PrepareContext(
+      [](widget_context_h context, bundle* content,
+          int w, int h, void* user_data) -> int {
+        EXPECT_CALL(GetMock<ElmMock>(),
+            elm_win_add(_, _, _)).
+                WillOnce(Return(reinterpret_cast<Evas_Object*>(
+                    calloc(1, sizeof(char)))));
+
+        EXPECT_CALL(GetMock<EcoreWl2Mock>(),
+            ecore_evas_wayland2_window_get(_)).
+                WillOnce(Return(reinterpret_cast<Ecore_Wl2_Window*>(
+                    calloc(1, sizeof(char)))));
+
+        EXPECT_CALL(GetMock<ElmMock>(),
+            elm_win_aux_hint_add(_, _, _)).WillOnce(Return(0));
+
+        EXPECT_CALL(GetMock<EcoreWl2Mock>(),
+            ecore_wl2_window_surface_get(_)).WillOnce(Return(nullptr));
+
+        EXPECT_CALL(GetMock<EcoreWl2Mock>(),
+            evas_object_event_callback_add(_, _, _, _)).Times(1);
+
+        EXPECT_CALL(GetMock<EcoreWl2Mock>(),
+            evas_object_data_set(_, _, _)).Times(1);
+
+        Evas_Object* win = nullptr;
+        int ret = widget_app_get_elm_win(context, &win);
+        EXPECT_EQ(ret, WIDGET_ERROR_NONE);
+        return -1;
+      });
 }
index b41c249..8d5fca5 100644 (file)
  */
 
 #include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include <widget_app.hpp>
 
-namespace {
+#include "include/widget_app.h"
+#include "include/widget_app_efl.h"
+#include "unit_tests/mock/app_common_mock.h"
+#include "unit_tests/mock/appcore_multiwindow_base_mock.h"
+#include "unit_tests/mock/aul_mock.h"
+#include "unit_tests/mock/ecore_wl2_mock.h"
+#include "unit_tests/mock/elm_mock.h"
+#include "unit_tests/mock/gio_mock.h"
+#include "unit_tests/mock/system_info_mock.h"
+#include "unit_tests/mock/test_fixture.h"
+#include "unit_tests/mock/widget_service_mock.h"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+
+class Mocks : public ::testing::NiceMock<GioMock>,
+              public ::testing::NiceMock<MultiWindowBaseMock>,
+              public ::testing::NiceMock<AppCommonMock>,
+              public ::testing::NiceMock<WidgetServiceMock>,
+              public ::testing::NiceMock<ElmMock>,
+              public ::testing::NiceMock<AulMock>,
+              public ::testing::NiceMock<SystemInfoMock>,
+              public ::testing::NiceMock<EcoreWl2Mock> {};
+
+class WidgetAppCppTest : public TestFixture {
+ public:
+  WidgetAppCppTest() : TestFixture(std::make_unique<Mocks>()) {}
+};
 
 class WidgetApp : public tizen_appfw::WidgetAppBase {
  public:
@@ -30,7 +62,7 @@ class WidgetApp : public tizen_appfw::WidgetAppBase {
       }
     };
 
-    Instance(widget_context_h h) : InstanceBase(h) {}
+    explicit Instance(widget_context_h h) : InstanceBase(h) {}
     void OnCreate(const tizen_base::Bundle& content, int w, int h) override {}
     void OnDestroy(DestroyType reason, tizen_base::Bundle* content) override {}
     void OnPause() override {}
@@ -44,13 +76,15 @@ class WidgetApp : public tizen_appfw::WidgetAppBase {
   void OnTerminate() override {}
 };
 
-}  // namespace
+TEST_F(WidgetAppCppTest, Run_InvalidParameter) {
+    EXPECT_CALL(GetMock<SystemInfoMock>(),
+        system_info_get_platform_bool(_, _)).
+            WillRepeatedly(DoAll(SetArgPointee<1>(true), Return(0)));
 
-TEST(WidgetAppCppTest, Run_InvalidParameter) {
   WidgetApp app;
   std::unique_ptr<tizen_appfw::WidgetAppBase::InstanceBase::Factory> factory(
       new WidgetApp::Instance::Factory());
 
   int ret = app.Run(0, nullptr, std::move(factory));
   EXPECT_EQ(ret, APP_ERROR_INVALID_PARAMETER);
-}
\ No newline at end of file
+}