Fix build break issue
[platform/core/appfw/app-core.git] / tizen-cpp / app-core-ui-cpp / app_core_ui_base.cc
1 /*
2  * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "app-core-ui-cpp/app_core_ui_base.hh"
18
19 #include <Ecore_Wl2.h>
20 #include <aul_app_lifecycle.h>
21 #include <aul_rpc_port.h>
22 #include <aul_svc.h>
23 #include <bundle_internal.h>
24 #include <sys/types.h>
25 #include <ttrace.h>
26 #include <unistd.h>
27
28 #include <list>
29 #include <memory>
30 #include <string>
31 #include <thread>
32
33 #include "app-core-cpp/app_core_base.hh"
34 #include "app-core-ui-cpp/api/app_core_ui_base.h"
35 #include "app-core-ui-cpp/app_core_task_base.hh"
36 #include "app-core-ui-cpp/app_core_ui_delegator_private.hh"
37 #include "app-core-ui-cpp/app_core_ui_plugin_private.hh"
38 #include "app-core-ui-cpp/wayland_handler_private.hh"
39 #include "common/ecore_handler.hh"
40 #include "common/glib_private.hh"
41 #include "common/log_private.hh"
42
43 namespace tizen_cpp {
44
45 class AppCoreUiBase::Impl {
46  public:
47   Impl(AppCoreUiBase* parent, unsigned int hint)
48       : parent_(parent),
49         hint_(hint),
50         handler_(std::make_shared<EcoreHandler>(parent)),
51         wl_handler_(new WaylandHandler()) {
52   }
53
54  private:
55   friend class AppCoreUiBase;
56   AppCoreUiBase* parent_;
57
58   enum AppState {
59     AS_NONE,
60     AS_CREATED,
61     AS_RUNNING,
62     AS_PAUSED,
63     AS_DYING,
64   };
65
66   enum VisibilityType {
67     VT_NONE,
68     VT_UNOBSCURED,
69     VT_FULLY_OBSCURED,
70   };
71
72   enum WinStatus {
73     WS_NONE,
74     WS_PAUSE,
75     WS_RESUME,
76   };
77
78   struct WinNode {
79     unsigned int win_;
80     unsigned int surf_;
81     int vis_;
82     WinNode(unsigned int win, unsigned int surf)
83         : win_(win), surf_(surf), vis_(VT_NONE) {
84     }
85   };
86
87   void ExitFromSuspend();
88   void PrepareToSuspend();
89   void DoStart(tizen_base::Bundle b);
90   void DoResume();
91   void DoPause();
92   bool CheckVisible();
93   int IsLegacyLifecycle();
94   std::shared_ptr<struct WinNode> FindWin(unsigned int win);
95   bool AddWin(unsigned int win, unsigned int surf);
96   bool DeleteWin(unsigned int win);
97   bool UpdateWin(unsigned int win, unsigned int surf, int vis);
98   void RaiseWin();
99   void PauseWin();
100   void ApplyBgState(bool bg_state);
101   void SetAppId();
102   int InitWl();
103   int FiniWl();
104   void PluginInit(int argc, char** argv);
105   void PluginFini();
106   void Run(int argc, char** argv);
107   void Exit();
108
109   std::list<std::shared_ptr<WinNode>> winnode_list_;
110   unsigned int hint_;
111   std::string below_app_;
112   bool first_launch_ = true;
113   bool bg_state_ = false;
114   bool resource_reclaiming_ = true;
115   std::string appid_;
116   AppState state_ = AS_NONE;
117   WinStatus w_status_ = WS_NONE;
118   std::shared_ptr<EcoreHandler> handler_;
119   std::unique_ptr<WaylandHandler> wl_handler_;
120   IAppCoreUi* core_ui_delegator_ = nullptr;
121   std::unique_ptr<AppCoreUiDelegator> plugin_delegator_;
122   std::unique_ptr<AppCoreUiPlugin> plugin_;
123   std::unique_ptr<AppCoreTaskBase> service_;
124   GMainContext* context_ = nullptr;
125   std::thread thread_;
126 };
127
128 AppCoreUiBase::AppCoreUiBase(unsigned int hint)
129     : impl_(new Impl(this, hint)) {
130 }
131
132 AppCoreUiBase::~AppCoreUiBase() = default;
133
134 std::shared_ptr<AppCoreUiBase::Impl::WinNode> AppCoreUiBase::Impl::FindWin(
135     unsigned int win) {
136   for (auto& i : winnode_list_) {
137     if (i->win_ == win)
138       return i;
139   }
140
141   return nullptr;
142 }
143
144 bool AppCoreUiBase::Impl::AddWin(unsigned int win, unsigned int surf) {
145   _D("[EVENT_TEST][EVENT] __add_win WIN: %u", win);
146   std::shared_ptr<AppCoreUiBase::Impl::WinNode> node = FindWin(win);
147   if (node != nullptr) {
148     _D("[EVENT_TEST][EVENT] ERROR There is already window: %u", win);
149     return false;
150   }
151
152   winnode_list_.emplace_back(new WinNode(win, surf));
153   return true;
154 }
155
156 bool AppCoreUiBase::Impl::DeleteWin(unsigned int win) {
157   std::shared_ptr<struct AppCoreUiBase::Impl::WinNode> node = FindWin(win);
158   if (node == nullptr) {
159     _D("[EVENT_TEST][EVENT] ERROR There is no window: %u", win);
160     return false;
161   }
162
163   winnode_list_.remove_if(
164       [win](std::shared_ptr<struct AppCoreUiBase::Impl::WinNode> node) {
165         return node->win_ == win;
166       });
167   return true;
168 }
169
170 bool AppCoreUiBase::Impl::UpdateWin(unsigned int win, unsigned int surf,
171     int vis) {
172   std::shared_ptr<AppCoreUiBase::Impl::WinNode> node = FindWin(win);
173   if (node == nullptr) {
174     _D("[EVENT_TEST][EVENT] ERROR There is no window: %u", win);
175     return false;
176   }
177
178   node->win_ = win;
179   if (surf != 0)
180     node->surf_ = surf;
181   if (vis != VT_NONE)
182     node->vis_ = vis;
183
184   return true;
185 }
186
187 void AppCoreUiBase::Impl::RaiseWin() {
188   if (!(hint_ & HINT_WINDOW_STACK_CONTROL))
189     return;
190
191   unsigned int win_id = parent_->GetMainWindow();
192   _I("Raise window: %u", win_id);
193   handler_->RaiseWin(win_id);
194 }
195
196 void AppCoreUiBase::Impl::PauseWin() {
197   if (!(hint_ & HINT_WINDOW_STACK_CONTROL))
198     return;
199
200   _D("Pause window");
201   for (auto& i : winnode_list_) {
202     _D("Pause window: %u", i->win_);
203     handler_->PauseWin(i->win_);
204   }
205 }
206
207 unsigned int AppCoreUiBase::GetMainWindow() {
208   if (impl_->winnode_list_.empty())
209     return 0;
210
211   return impl_->winnode_list_.begin()->get()->win_;
212 }
213
214 unsigned int AppCoreUiBase::GetMainSurface() {
215   if (impl_->winnode_list_.empty())
216     return 0;
217
218   return impl_->winnode_list_.begin()->get()->surf_;
219 }
220
221 void AppCoreUiBase::SetCoreUiDelegator(IAppCoreUi* delegator) {
222   impl_->core_ui_delegator_ = delegator;
223 }
224
225 void AppCoreUiBase::SetWindowDelegator(IWindow* delegator) {
226   impl_->handler_->SetWindow(delegator);
227 }
228
229 int AppCoreUiBase::Impl::InitWl() {
230   return wl_handler_->Init();
231 }
232
233 int AppCoreUiBase::Impl::FiniWl() {
234   wl_handler_->Fini();
235   return 0;
236 }
237
238 void AppCoreUiBase::Impl::ApplyBgState(bool bg_state) {
239   if (wl_handler_->Init() < 0)
240     return;
241
242   if (bg_state)
243     wl_handler_->SetBgState();
244   else
245     wl_handler_->UnsetBgState();
246
247   parent_->SetBgState(bg_state);
248 }
249
250 void AppCoreUiBase::Impl::SetAppId() {
251   if (wl_handler_->Init() < 0)
252     return;
253
254   wl_handler_->SetAppId(appid_);
255 }
256
257 void AppCoreUiBase::Impl::PluginInit(int argc, char** argv) {
258   plugin_.reset(AppCoreUiPlugin::Load());
259   if (plugin_ == nullptr)
260     return;
261
262   app_core_ui_base_ops ops;
263   ops.base.create = [](void* data) -> int {
264     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
265     return base->OnCreate();
266   };
267
268   ops.base.control = [](bundle* b, void* data) -> int {
269     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
270     return base->OnControl(tizen_base::Bundle(b));
271   };
272
273   ops.base.terminate = [](void* data) -> int {
274     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
275     return base->OnTerminate();
276   };
277
278   ops.base.receive = [](aul_type type, bundle* b, void* data) -> int {
279     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
280     return base->OnReceive(type, tizen_base::Bundle(b));
281   };
282
283   ops.base.set_i18n = [](void* data) -> int {
284     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
285     return base->OnSetI18n();
286   };
287
288   ops.base.init = [](int argc, char** argv, void* data) {
289     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
290     base->OnLoopInit(argc, argv);
291   };
292
293   ops.base.finish = [](void* data) {
294     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
295     base->OnLoopFinish();
296   };
297
298   ops.base.run = [](void* data) {
299     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
300     base->OnLoopRun();
301   };
302
303   ops.base.exit = [](void* data) {
304     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
305     base->OnLoopExit();
306   };
307
308   ops.base.set_event = [](app_core_ui_base_event_e event, void* data) {
309     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
310     base->OnSetEvent(static_cast<IAppCore::IEvent::Type>(event));
311   };
312
313   ops.base.unset_event = [](app_core_ui_base_event_e event, void* data) {
314     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
315     base->OnUnsetEvent(static_cast<IAppCore::IEvent::Type>(event));
316   };
317
318   ops.base.trim_memory = [](void* data) {
319     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
320     base->OnTrimMemory();
321   };
322
323   ops.pause = [](void* data) -> int {
324     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
325     return base->OnPause();
326   };
327
328   ops.resume = [](void* data) -> int {
329     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
330     return base->OnResume();
331   };
332
333   ops.window.show = [](int type, void* event, void* data) {
334     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
335     base->OnShow(type, event);
336   };
337
338   ops.window.hide = [](int type, void* event, void* data) {
339     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
340     base->OnHide(type, event);
341   };
342
343   ops.window.lower = [](int type, void* event, void* data) {
344     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
345     base->OnLower(type, event);
346   };
347
348   ops.window.visibility = [](int type, void* event, void* data) {
349     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
350     base->OnVisibility(type, event);
351   };
352
353   ops.window.pre_visibility = [](int type, void* event, void* data) {
354     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
355     base->OnPreVisibility(type, event);
356   };
357
358   ops.window.aux_message = [](int type, void* event, void* data) {
359     auto* base = reinterpret_cast<AppCoreUiBase*>(data);
360     base->OnAuxMessage(type, event);
361   };
362
363   plugin_->Init(parent_, &ops, argc, argv, &hint_);
364   plugin_delegator_.reset(new AppCoreUiDelegator(ops, parent_));
365   parent_->SetCoreDelegator(plugin_delegator_.get());
366   parent_->SetLoopDelegator(plugin_delegator_.get());
367   parent_->SetCoreUiDelegator(plugin_delegator_.get());
368   parent_->SetWindowDelegator(plugin_delegator_.get());
369 }
370
371 void AppCoreUiBase::Impl::PluginFini() {
372   if (plugin_ == nullptr)
373     return;
374
375   plugin_->Fini(parent_);
376 }
377
378 void AppCoreUiBase::DoRun(int argc, char** argv) {
379   SetCoreDelegator(nullptr);
380   SetLoopDelegator(nullptr);
381   SetCoreUiDelegator(nullptr);
382   SetWindowDelegator(this);
383   impl_->plugin_delegator_.reset();
384   impl_->PluginInit(argc, argv);
385
386   char appid[PATH_MAX] = {0, };
387   int ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
388   if (ret != 0)
389     _E("Fail to get appid. pid(%d)", getpid());
390
391   impl_->handler_->Init();
392   impl_->state_ = Impl::AS_NONE;
393   impl_->w_status_ = Impl::WS_NONE;
394   impl_->appid_ = std::string(appid);
395   LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:main:done]", appid);
396   if (impl_->hint_ & HINT_BG_LAUNCH_CONTROL) {
397     tizen_base::Bundle b(bundle_import_from_argv(argc, argv), false, true);
398     if (!b.IsEmpty()) {
399       std::string bg_launch = b.GetString(AUL_SVC_K_BG_LAUNCH);
400       if (bg_launch.compare("enable") == 0)
401         impl_->ApplyBgState(true);
402     }
403   }
404
405   if (impl_->hint_ & HINT_WINDOW_ID_CONTROL)
406     impl_->SetAppId();
407
408   AppCoreBase::Run(argc, argv);
409 }
410
411 void AppCoreUiBase::DoExit() {
412   AppCoreBase::Exit();
413 }
414
415 void AppCoreUiBase::Impl::Run(int argc, char** argv) {
416   if (hint_ & HINT_DUAL_THREAD) {
417     // For the loader case
418     while (ecore_shutdown() != 0);
419
420     service_ = parent_->CreateTask();
421     context_ = g_main_context_new();
422     std::string env = std::to_string(GPOINTER_TO_UINT(context_));
423     setenv("TIZEN_GLIB_CONTEXT", env.c_str(), 1);
424
425     thread_ = std::thread([&] {
426           parent_->DoRun(argc, argv);
427         });
428
429     service_->Run(argc, argv);
430
431     if (thread_.joinable())
432       thread_.join();
433
434     setenv("TIZEN_GLIB_CONTEXT", "", 1);
435     g_main_context_unref(context_);
436     context_ = nullptr;
437     return;
438   }
439
440   parent_->DoRun(argc, argv);
441 }
442
443 void AppCoreUiBase::Impl::Exit() {
444   if (hint_ & HINT_DUAL_THREAD) {
445     GLib::IdleAdd(context_, [](gpointer user_data) {
446           auto* impl = static_cast<AppCoreUiBase::Impl*>(user_data);
447           impl->parent_->DoExit();
448           return G_SOURCE_REMOVE;
449         }, this);
450
451     service_->Exit();
452     return;
453   }
454
455   parent_->DoExit();
456 }
457
458 void AppCoreUiBase::Run(int argc, char** argv) {
459   impl_->Run(argc, argv);
460 }
461
462 void AppCoreUiBase::Exit() {
463   impl_->Exit();
464 }
465
466 void AppCoreUiBase::Dispose() {
467   impl_->handler_->Fini();
468   impl_->FiniWl();
469
470   impl_->appid_.clear();
471
472   AppCoreBase::Dispose();
473   impl_->PluginFini();
474 }
475
476 std::unique_ptr<AppCoreTaskBase> AppCoreUiBase::CreateTask() {
477   return std::make_unique<AppCoreTaskBase>();
478 }
479
480 void AppCoreUiBase::Impl::PrepareToSuspend() {
481   if (parent_->IsBgAllowed() && !parent_->IsSuspended()) {
482     SuspendedState suspend = SUSPENDED_STATE_WILL_ENTER_SUSPEND;
483     parent_->RaiseEvent(suspend, IEvent::Type::SUSPENDED_STATE_CHANGE);
484     parent_->ToggleSuspendedState();
485   }
486 }
487
488 void AppCoreUiBase::Impl::ExitFromSuspend() {
489   if (parent_->IsSuspended()) {
490     SuspendedState suspend = SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
491     parent_->RaiseEvent(suspend, IEvent::Type::SUSPENDED_STATE_CHANGE);
492     parent_->ToggleSuspendedState();
493   }
494 }
495
496 void AppCoreUiBase::Impl::DoPause() {
497   if (state_ == AS_RUNNING) {
498     aul_app_lifecycle_update_state(AUL_APP_LIFECYCLE_STATE_PAUSED);
499     state_ = AS_PAUSED;
500     traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:PAUSE");
501     _D("Call pause callback");
502     if (parent_->GetHint() & HINT_DUAL_THREAD)
503       service_->Post(AppCoreTaskBase::UiState::PAUSED);
504
505     int ret;
506     if (core_ui_delegator_)
507       ret = core_ui_delegator_->OnPause();
508     else
509       ret = parent_->OnPause();
510
511     traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
512     if (ret >= 0 && resource_reclaiming_)
513       parent_->AddSuspendTimer();
514
515     PrepareToSuspend();
516   }
517
518   aul_status_update(STATUS_BG);
519 }
520
521 void AppCoreUiBase::Impl::DoResume() {
522   if (state_ == AS_PAUSED || state_ == AS_CREATED) {
523     aul_app_lifecycle_update_state(AUL_APP_LIFECYCLE_STATE_RESUMED);
524     ExitFromSuspend();
525     state_ = AS_RUNNING;
526     LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:start]", appid_.c_str());
527     traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:RESUME");
528     _D("Call resume callback");
529     if (parent_->GetHint() & HINT_DUAL_THREAD)
530       service_->Post(AppCoreTaskBase::UiState::RESUMED);
531
532     parent_->RemoveSuspendTimer();
533     if (core_ui_delegator_)
534       core_ui_delegator_->OnResume();
535     else
536       parent_->OnResume();
537
538     traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
539     LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:done]", appid_.c_str());
540   }
541
542   aul_status_update(STATUS_VISIBLE);
543 }
544
545 void AppCoreUiBase::Impl::DoStart(tizen_base::Bundle b) {
546   if (parent_->GetHint() & HINT_WINDOW_STACK_CONTROL)
547     below_app_ = b.GetString(AUL_SVC_K_RELOCATE_BELOW);
548
549   if (first_launch_) {
550     first_launch_ = false;
551     return;
552   }
553
554   if (parent_->GetHint() & HINT_BG_LAUNCH_CONTROL) {
555     std::string bg_launch = b.GetString(AUL_SVC_K_BG_LAUNCH);
556     if (!bg_launch.empty() && bg_launch.compare("enable") == 0) {
557       if (!bg_state_ && state_ != AS_RUNNING)
558         ApplyBgState(true);
559     } else {
560       if (bg_state_)
561         ApplyBgState(false);
562     }
563   }
564
565   if (parent_->GetHint() & HINT_WINDOW_AUTO_CONTROL) {
566     if (!bg_state_) {
567       std::string rpc_port = b.GetString(AUL_K_RPC_PORT);
568       if (rpc_port.empty())
569         RaiseWin();
570     }
571   }
572 }
573
574 int AppCoreUiBase::Impl::IsLegacyLifecycle() {
575   static int is_legacy = -1;
576   if (__builtin_expect(is_legacy != -1, 1))
577     return is_legacy;
578
579   const char* api_version = getenv("TIZEN_API_VERSION");
580   if (api_version) {
581     if (strverscmp("2.4", api_version) > 0 &&
582         strverscmp("2.2.1", api_version) < 0)
583       is_legacy = 1;
584     else
585       is_legacy = 0;
586   } else {
587     is_legacy = 0;
588   }
589
590   return is_legacy;
591 }
592
593 int AppCoreUiBase::OnPause() {
594   return 0;
595 }
596
597 int AppCoreUiBase::OnResume() {
598   return 0;
599 }
600
601 int AppCoreUiBase::OnReceive(aul_type type, tizen_base::Bundle b) {
602   if (impl_->state_ == Impl::AS_DYING) {
603     _E("Skip the event in dying state");
604     return 0;
605   }
606
607   if ((type == AUL_TERMINATE_BGAPP || type == AUL_TERMINATE_BG_INST) &&
608       impl_->state_ != Impl::AS_PAUSED)
609     return 0;
610
611   if (type == AUL_START)
612     impl_->ExitFromSuspend();
613
614   AppCoreBase::OnReceive(type, b);
615
616   switch (type) {
617   case AUL_START:
618     impl_->DoStart(b);
619     if (GetHint() & HINT_LEGACY_CONTROL) {
620       if (impl_->bg_state_ && impl_->IsLegacyLifecycle()) {
621         _D("Legacy lifecycle");
622         impl_->DoResume();
623       }
624     }
625     break;
626   case AUL_RESUME:
627     if (impl_->bg_state_)
628       impl_->ApplyBgState(false);
629
630     impl_->RaiseWin();
631     break;
632   case AUL_TERMINATE:
633     if (impl_->state_ == Impl::AS_RUNNING) {
634       _D("Call pause callback");
635       if (impl_->core_ui_delegator_)
636         impl_->core_ui_delegator_->OnPause();
637       else
638         OnPause();
639     }
640     impl_->state_ = Impl::AS_DYING;
641     break;
642   case AUL_TERMINATE_BGAPP:
643   case AUL_TERMINATE_BG_INST:
644   case AUL_TERMINATE_INST:
645     _D("[APP %d] TERMINATE", getpid());
646     if (impl_->state_ == Impl::AS_RUNNING) {
647       _D("Call pause callback");
648       if (impl_->core_ui_delegator_)
649         impl_->core_ui_delegator_->OnPause();
650       else
651         OnPause();
652     }
653     impl_->state_ = Impl::AS_DYING;
654     aul_status_update(STATUS_DYING);
655     Exit();
656     break;
657   case AUL_PAUSE:
658     impl_->PauseWin();
659     break;
660   default:
661     break;
662   }
663
664   return 0;
665 }
666
667 int AppCoreUiBase::OnCreate() {
668   AppCoreBase::OnCreate();
669   impl_->state_ = Impl::AS_CREATED;
670   LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:create:done]",
671       impl_->appid_.c_str());
672   return 0;
673 }
674
675 int AppCoreUiBase::OnTerminate() {
676   if (impl_->state_ == Impl::AS_RUNNING) {
677     _D("Call pause callback");
678     OnPause();
679   }
680
681   impl_->state_ = Impl::AS_DYING;
682   AppCoreBase::OnTerminate();
683   return 0;
684 }
685
686 int AppCoreUiBase::OnTrimMemory() {
687   return AppCoreBase::OnTrimMemory();
688 }
689
690 int AppCoreUiBase::GroupAdd() {
691   _D("Group attach");
692   static bool attached = false;
693   if (attached)
694     return 0;
695
696   int wid = GetMainSurface();
697   if (wid == 0) {
698     _E("window wasn't ready");
699     return -1;
700   }
701
702   int ret = aul_app_group_set_window(wid);
703   if (ret < 0) {
704     _E("Failed to set app group window. error(%d)", ret);
705     return ret;
706   }
707
708   attached = true;
709   return 0;
710 }
711
712 void AppCoreUiBase::GroupRemove() {
713   _D("Group lower");
714   int exit = 0;
715   aul_app_group_lower(&exit);
716   if (exit) {
717     _W("Sub App");
718     Exit();
719   }
720 }
721
722 void AppCoreUiBase::OnShow(int type, void* event) {
723   auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Show*>(event);
724   if (ev->parent_win != 0)
725     return;
726
727   unsigned int win = static_cast<unsigned int>(ev->win);
728   unsigned int surf = static_cast<unsigned int>(ev->data[0]);
729   _D("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN: %u, %u", win, surf);
730
731   if (!impl_->FindWin(win))
732     impl_->AddWin(win, surf);
733   else
734     impl_->UpdateWin(win, surf, Impl::VT_NONE);
735
736   if (surf != 0)
737     GroupAdd();
738 }
739
740 bool AppCoreUiBase::Impl::CheckVisible() {
741   _D("[EVENT_TEST][EVENT] __check_visible");
742   for (auto& i : winnode_list_) {
743     _D("win : %u visibility : %d", i->win_, i->vis_);
744     if (i->vis_ == VT_UNOBSCURED)
745       return true;
746   }
747
748   return false;
749 }
750
751 void AppCoreUiBase::OnHide(int type, void* event) {
752   auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Hide*>(event);
753   _D("[EVENT_TEST][EVENT] GET HIDE EVENT!!!. WIN :%d", ev->win);
754   if (impl_->FindWin((unsigned int)ev->win)) {
755     impl_->DeleteWin((unsigned int)ev->win);
756     bool bvisibility = impl_->CheckVisible();
757     if (!bvisibility && impl_->w_status_ != Impl::WS_PAUSE) {
758       _D("Go to Pasue state");
759       impl_->w_status_ = Impl::WS_PAUSE;
760       impl_->DoPause();
761     }
762   }
763 }
764
765 void AppCoreUiBase::OnLower(int type, void* event) {
766   auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Lower*>(event);
767   if (!ev)
768     return;
769
770   _D("ECORE_WL2_EVENT_WINDOW_LOWER window id: %u", ev->win);
771   if (!(impl_->hint_ & HINT_WINDOW_GROUP_CONTROL))
772     return;
773
774   GroupRemove();
775 }
776
777 void AppCoreUiBase::OnVisibility(int type, void* event) {
778   auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Visibility_Change*>(event);
779   impl_->UpdateWin((unsigned int)ev->win, 0,
780       ev->fully_obscured ? Impl::VT_FULLY_OBSCURED : Impl::VT_UNOBSCURED);
781   bool bvisibility = impl_->CheckVisible();
782   _D("bvisibility %d, w_status_ %d", bvisibility, impl_->w_status_);
783
784   if (bvisibility && (impl_->hint_ & HINT_WINDOW_STACK_CONTROL) &&
785       !impl_->below_app_.empty()) {
786     aul_app_group_activate_below(impl_->below_app_.c_str());
787     impl_->below_app_.clear();
788   }
789
790   if (bvisibility && impl_->w_status_ != Impl::WS_RESUME) {
791     _D("Go to Resume state");
792     impl_->w_status_ = Impl::WS_RESUME;
793     impl_->DoResume();
794   } else if (!bvisibility && impl_->w_status_ != Impl::WS_PAUSE) {
795     _D("Go to Pasue state");
796     impl_->w_status_ = Impl::WS_PAUSE;
797     impl_->DoPause();
798   } else {
799     _D("No change state");
800   }
801 }
802
803 void AppCoreUiBase::OnPreVisibility(int type, void* event) {
804   auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Pre_Visibility_Change*>(
805       event);
806   if (ev && ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED) {
807     impl_->UpdateWin((unsigned int)ev->win, 0, Impl::VT_UNOBSCURED);
808     bool bvisibility = impl_->CheckVisible();
809
810     _D("bvisibility %d, w_status_ %d", bvisibility, impl_->w_status_);
811     if (bvisibility && impl_->w_status_ != Impl::WS_RESUME) {
812       _D(" Go to Resume state");
813       impl_->w_status_ = Impl::WS_RESUME;
814       impl_->DoResume();
815     }
816   }
817 }
818
819 void AppCoreUiBase::OnAuxMessage(int type, void* event) {
820   auto* ev = reinterpret_cast<Ecore_Wl2_Event_Aux_Message*>(event);
821   if (ev->key && !strcmp(ev->key, "dpms_wm")) {
822     if (ev->val && !strcmp(ev->val, "on")) {
823       _D("Display state: on");
824       SetDisplayState(DISPLAY_STATE_ON);
825     } else if (ev->val && !strcmp(ev->val, "off")) {
826       _D("Display state: off");
827       SetDisplayState(DISPLAY_STATE_OFF);
828     } else {
829       _E("Unknown state: %s", ev->val);
830     }
831   }
832 }
833
834 void AppCoreUiBase::Pause() {
835   impl_->DoPause();
836 }
837
838 void AppCoreUiBase::Resume() {
839   impl_->DoResume();
840 }
841
842 bool AppCoreUiBase::IsResumed() {
843   return impl_->state_ == Impl::AS_RUNNING;
844 }
845
846 int AppCoreUiBase::GetHint() {
847   return impl_->hint_;
848 }
849
850 bool AppCoreUiBase::GetBgState() {
851   return impl_->bg_state_;
852 }
853
854 void AppCoreUiBase::SetBgState(bool bg_state) {
855   impl_->bg_state_ = bg_state;
856 }
857
858 void AppCoreUiBase::SetSystemResourceReclaiming(bool enable) {
859   impl_->resource_reclaiming_ = enable;
860 }
861
862 }  // namespace tizen_cpp