--- /dev/null
+/*
+ * 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 TIZEN_APPFW_WIDGET_APP_HPP_
+#define TIZEN_APPFW_WIDGET_APP_HPP_
+
+#include <widget_app.h>
+#include <widget_app_efl.h>
+
+#include <ctime>
+#include <list>
+#include <memory>
+
+#include <app_common.hpp>
+#include <bundle_cpp.h>
+
+namespace tizen_appfw {
+
+class WidgetAppBase : public app_common::AppBase<
+ decltype(widget_app_add_event_handler)*,
+ decltype(widget_app_remove_event_handler)*> {
+ public:
+ using Remover = decltype(widget_app_remove_event_handler)*;
+
+ WidgetAppBase()
+ : AppBase(widget_app_add_event_handler,
+ widget_app_remove_event_handler) {}
+
+ virtual void OnCreate() {}
+ virtual void OnTerminate() {}
+
+ class InstanceBase {
+ public:
+ class Factory {
+ public:
+ ~Factory() = default;
+ virtual std::unique_ptr<InstanceBase> Create(widget_context_h h) = 0;
+ };
+
+ enum class DestroyType {
+ PERMANENT = 0x00,
+ TEMPORARY = 0x01,
+ };
+
+ InstanceBase(widget_context_h h) : handle_(h) {}
+ virtual ~InstanceBase() = default;
+
+ virtual void OnCreate(const tizen_base::Bundle& content, int w, int h) = 0;
+ virtual void OnDestroy(DestroyType reason, tizen_base::Bundle* content) = 0;
+ virtual void OnPause() = 0;
+ virtual void OnResume() = 0;
+ virtual void OnResize(int w, int h) = 0;
+ virtual void OnUpdate(const tizen_base::Bundle& content, bool force) = 0;
+ widget_context_h GetHandle() const {
+ return handle_;
+ }
+
+ void Finish() {
+ widget_app_terminate_context(handle_);
+ }
+
+ std::string GetId() const {
+ return std::string(widget_app_get_id(handle_));
+ }
+
+ void SetContextInfo(const tizen_base::Bundle& info) {
+ widget_app_context_set_content_info(handle_, info.GetHandle());
+ }
+
+ void SetTitle(const std::string& title) {
+ widget_app_context_set_title(handle_, title.c_str());
+ }
+
+ Evas_Object* GetElmWin() const {
+ Evas_Object* win = nullptr;
+ widget_app_get_elm_win(handle_, &win);
+ return win;
+ }
+
+ private:
+ widget_context_h handle_;
+ };
+
+ int Run(int argc, char** argv,
+ std::unique_ptr<InstanceBase::Factory> factory) {
+ factory_ = std::move(factory);
+ widget_app_lifecycle_callback_s callback = {
+ create : [](void *user_data) -> widget_class_h {
+ WidgetAppBase* b = static_cast<WidgetAppBase*>(user_data);
+ b->OnCreate();
+ widget_instance_lifecycle_callback_s callback = {
+ create : [](widget_context_h context, bundle* content, int w, int h,
+ void* user_data) -> int {
+ WidgetAppBase* b = static_cast<WidgetAppBase*>(user_data);
+ auto i = b->factory_->Create(context);
+ i->OnCreate(tizen_base::Bundle(content, false, false), w, h);
+ b->instances_.push_back(std::move(i));
+ return 0;
+ },
+ destroy : [](widget_context_h context,
+ widget_app_destroy_type_e reason, bundle* content,
+ void* user_data) -> int {
+ WidgetAppBase* b = static_cast<WidgetAppBase*>(user_data);
+
+ for (auto& i : b->instances_) {
+ if (i->GetHandle() == context) {
+ tizen_base::Bundle bd(content, false, false);
+ i->OnDestroy(
+ static_cast<InstanceBase::DestroyType>(reason), &bd);
+ b->instances_.remove(i);
+ break;
+ }
+ }
+
+ return 0;
+ },
+ pause : [](widget_context_h context, void* user_data) -> int {
+ WidgetAppBase* b = static_cast<WidgetAppBase*>(user_data);
+ auto* i = b->FindInst(context);
+ if (!i)
+ return -1;
+ i->OnPause();
+ return 0;
+ },
+ resume : [](widget_context_h context, void* user_data) -> int {
+ WidgetAppBase* b = static_cast<WidgetAppBase*>(user_data);
+ auto* i = b->FindInst(context);
+ if (!i)
+ return -1;
+ i->OnResume();
+ return 0;
+ },
+ resize : [](widget_context_h context, int w, int h,
+ void* user_data) -> int {
+ WidgetAppBase* b = static_cast<WidgetAppBase*>(user_data);
+ auto* i = b->FindInst(context);
+ if (!i)
+ return -1;
+ i->OnResize(w, h);
+ return 0;
+ },
+ update : [](widget_context_h context, bundle* content, int force,
+ void* user_data) -> int {
+ WidgetAppBase* b = static_cast<WidgetAppBase*>(user_data);
+ auto* i = b->FindInst(context);
+ if (!i)
+ return -1;
+ i->OnUpdate(tizen_base::Bundle(content), force);
+ return 0;
+ }
+ };
+ auto h = widget_app_class_create(callback, user_data);
+ return h;
+ },
+ terminate : [](void* user_data) {
+ WidgetAppBase* b = static_cast<WidgetAppBase*>(user_data);
+ b->OnTerminate();
+ }
+ };
+
+ return widget_app_main(argc, argv, &callback, this);
+ }
+
+ void Exit() noexcept {
+ widget_app_exit();
+ }
+
+ private:
+ InstanceBase* FindInst(widget_context_h h) {
+ for (auto& i : instances_) {
+ if (i->GetHandle() == h) {
+ return i.get();
+ }
+ }
+
+ return nullptr;
+ }
+
+ std::unique_ptr<InstanceBase::Factory> factory_;
+ std::list<std::unique_ptr<InstanceBase>> instances_;
+};
+
+} // namespace tizen_appfw
+
+#endif // TIZEN_APPFW_WIDGET_APP_HPP_
--- /dev/null
+/*
+ * 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 <gmock/gmock.h>
+#include <widget_app.hpp>
+
+namespace {
+
+class WidgetApp : public tizen_appfw::WidgetAppBase {
+ public:
+ class Instance : public InstanceBase {
+ public:
+ class Factory : public InstanceBase::Factory {
+ public:
+ std::unique_ptr<InstanceBase> Create(widget_context_h h) override {
+ return std::unique_ptr<InstanceBase>(new Instance(h));
+ }
+ };
+
+ 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 {}
+ void OnResume() override {}
+ void OnResize(int w, int h) override {}
+ void OnUpdate(const tizen_base::Bundle& content, bool force) override {}
+ };
+
+ WidgetApp() {}
+ void OnCreate() override {}
+ void OnTerminate() override {}
+};
+
+} // namespace
+
+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