Release version 1.25.4
[platform/core/appfw/app-core.git] / tizen-cpp / app-core-efl-cpp / app_core_efl_base.cc
1 /*
2  * Copyright (c) 2021 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 <Elementary.h>
18 #include <glib.h>
19 #include <stdlib.h>
20
21 #include <condition_variable>
22 #include <memory>
23 #include <mutex>
24 #include <string>
25 #include <thread>
26
27 #include "app-core-efl-cpp/app_core_efl_base.hh"
28 #include "app-core-efl-cpp/voice_elm_private.hh"
29 #include "common/glib_private.hh"
30 #include "common/log_private.hh"
31 #include "common/log_tracer.hh"
32
33 namespace tizen_cpp {
34
35 class AppCoreEflBase::Impl {
36  public:
37   Impl(AppCoreEflBase* parent);
38   ~Impl();
39
40   void Init(int argc, char** argv);
41   void Finish();
42   void LoopRun();
43   void LoopExit();
44   void TrimMemory();
45
46  private:
47   friend class AppCoreEflBase;
48   AppCoreEflBase* parent_;
49
50   std::thread thread_;
51   bool thread_started_ = false;
52   std::condition_variable cond_;
53   std::unique_ptr<VoiceElm> vc_elm_;
54   guint source_id_ = 0;
55   std::mutex mutex_;
56   bool initialized_ = false;
57 };
58
59 AppCoreEflBase::Impl::Impl(AppCoreEflBase* parent) : parent_(parent) {}
60
61 AppCoreEflBase::Impl::~Impl() {
62   if (thread_.joinable())
63     thread_.join();
64
65   if (source_id_ != 0)
66     GLib::SourceRemove(source_id_);
67 }
68
69 void AppCoreEflBase::Impl::Init(int argc, char** argv) {
70   LogTracer tracer("AppCoreEflBase::Impl::Init()");
71   if (initialized_)
72     return;
73
74   elm_init(argc, argv);
75   unsigned int hint = parent_->GetHint();
76   if ((hint & HINT_HW_ACC_CONTROL) && !getenv("AUL_HWACC")) {
77     const char* hwacc = getenv("HWACC");
78     if (hwacc == nullptr) {
79       _D("elm_config_accel_preference_set is not called");
80     } else if (strcmp(hwacc, "USE") == 0) {
81       elm_config_accel_preference_set("hw");
82       _D("elm_config_accel_preference_set : hw");
83     } else if (strcmp(hwacc, "NOT_USE") == 0) {
84       elm_config_accel_preference_set("none");
85       _D("elm_config_accel_preference_set : none");
86     } else {
87       _D("elm_config_accel_preference_set is not called");
88     }
89   }
90
91   if (VoiceElm::IsVtAutoMode()) {
92     std::unique_lock<std::mutex> lock(mutex_);
93     thread_ = std::thread([&] {
94         std::unique_lock<std::mutex> lock(mutex_);
95         thread_started_ = true;
96         cond_.notify_one();
97
98         int retry_count = 3;
99         do {
100           if (vc_elm_.get() == nullptr)
101               vc_elm_.reset(VoiceElm::Load());
102
103           if (vc_elm_.get() != nullptr) {
104             source_id_ = GLib::IdleAdd([](gpointer user_data) {
105                   auto* impl = static_cast<AppCoreEflBase::Impl*>(user_data);
106                   if (impl->vc_elm_.get() != nullptr)
107                     impl->vc_elm_->Init();
108
109                   impl->source_id_ = 0;
110                   return G_SOURCE_REMOVE;
111                 }, this);
112             break;
113           }
114         } while (retry_count--);
115     });
116     cond_.wait(lock, [&] { return thread_started_; });
117   }
118
119   initialized_ = true;
120 }
121
122 void AppCoreEflBase::Impl::Finish() {
123   LogTracer tracer("AppCoreEflBase::Impl::Finish()");
124   if (!initialized_)
125     return;
126
127   if (thread_.joinable())
128     thread_.join();
129
130   thread_started_ = false;
131
132   if (source_id_ != 0) {
133     GLib::SourceRemove(source_id_);
134     source_id_ = 0;
135   }
136
137   elm_shutdown();
138
139   // Check loader case
140   const char* env = getenv("AUL_LOADER_INIT");
141   if (env && env[0] == '1') {
142     setenv("AUL_LOADER_INIT", "0", 1);
143     elm_shutdown();
144   }
145
146   initialized_ = false;
147 }
148
149 void AppCoreEflBase::Impl::LoopRun() {
150   elm_run();
151 }
152
153 void AppCoreEflBase::Impl::LoopExit() {
154   elm_exit();
155 }
156
157 void AppCoreEflBase::Impl::TrimMemory() {
158   elm_cache_all_flush();
159 }
160
161 AppCoreEflBase::AppCoreEflBase(unsigned int hint)
162     : AppCoreUiBase(hint),
163       impl_(new Impl(this)) {
164 }
165
166 AppCoreEflBase::~AppCoreEflBase() = default;
167
168 void AppCoreEflBase::OnLoopInit(int argc, char** argv) {
169   impl_->Init(argc, argv);
170 }
171
172 void AppCoreEflBase::OnLoopFinish() {
173   impl_->Finish();
174 }
175
176 void AppCoreEflBase::OnLoopRun() {
177   impl_->LoopRun();
178 }
179
180 void AppCoreEflBase::OnLoopExit() {
181   impl_->LoopExit();
182 }
183
184 int AppCoreEflBase::OnTrimMemory() {
185   _D("Trim memory");
186   impl_->TrimMemory();
187   return AppCoreUiBase::OnTrimMemory();
188 }
189
190 }  // namespace tizen_cpp