Modify AppCoreUiThreadBase class
[platform/core/appfw/app-core.git] / tizen-cpp / app-core-ui-cpp / app_core_task_base.cc
1 /*
2  * Copyright (c) 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_task_base.hh"
18
19 #include <glib.h>
20 #include <vconf-internal-keys.h>
21
22 #include <memory>
23 #include <mutex>
24 #include <queue>
25 #include <vector>
26
27 #include "common/glib_private.hh"
28
29 namespace tizen_cpp {
30
31 class SystemEvent : public AppCoreBase::EventBase {
32  public:
33   class IEvent {
34    public:
35     virtual ~IEvent() = default;
36     virtual void OnSystemEvent(Type type) = 0;
37   };
38
39   SystemEvent(IAppCore::IEvent::Type type, IEvent* listener);
40
41   void OnEvent(const std::string& value) override;
42   void OnEvent(int value) override;
43
44  private:
45   IEvent* listener_;
46 };
47
48 class AppCoreTaskBase::Impl : public SystemEvent::IEvent {
49  public:
50   Impl(AppCoreTaskBase* parent);
51
52   void LoopInit(int argc, char** argv);
53   void LoopRun();
54   void LoopExit();
55   void LoopFinish();
56   void SetSystemEvents();
57   void UnsetSystemEvents();
58   void Post(UiState state);
59   std::recursive_mutex& GetMutex() const;
60
61  private:
62   void OnSystemEvent(IAppCore::IEvent::Type type) override;
63   DeviceOrientationState ConvertRotationState(int value);
64   LowMemoryState ConvertLowMemoryState(int value);
65   LowBatteryState ConvertLowBatteryState(int value);
66
67  private:
68   friend class AppCoreTaskBase;
69   AppCoreTaskBase* parent_;
70   std::shared_ptr<SystemEvent> low_memory_;
71   std::shared_ptr<SystemEvent> low_battery_;
72   std::shared_ptr<SystemEvent> lang_change_;
73   std::shared_ptr<SystemEvent> device_orientation_changed_;
74   std::shared_ptr<SystemEvent> region_change_;
75   GMainLoop* loop_ = nullptr;
76   std::queue<UiState> queue_;
77   mutable std::recursive_mutex mutex_;
78 };
79
80 SystemEvent::SystemEvent(Type type, SystemEvent::IEvent* listener)
81     : EventBase(type), listener_(listener) {
82 }
83
84 void SystemEvent::OnEvent(const std::string& value) {
85   listener_->OnSystemEvent(GetType());
86 }
87
88 void SystemEvent::OnEvent(int value) {
89   listener_->OnSystemEvent(GetType());
90 }
91
92 AppCoreTaskBase::Impl::Impl(AppCoreTaskBase* parent) : parent_(parent) {
93   low_memory_ = std::make_shared<SystemEvent>(
94       IAppCore::IEvent::Type::LOW_MEMORY, this);
95   low_battery_ = std::make_shared<SystemEvent>(
96       IAppCore::IEvent::Type::LOW_BATTERY, this);
97   lang_change_ = std::make_shared<SystemEvent>(
98       IAppCore::IEvent::Type::LANG_CHANGE, this);
99   device_orientation_changed_ = std::make_shared<SystemEvent>(
100       IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED, this);
101   region_change_ = std::make_shared<SystemEvent>(
102       IAppCore::IEvent::Type::REGION_CHANGE, this);
103 }
104
105 void AppCoreTaskBase::Impl::LoopInit(int argc, char** argv) {
106   loop_ = g_main_loop_new(nullptr, FALSE);
107 }
108
109 void AppCoreTaskBase::Impl::LoopRun() {
110   g_main_loop_run(loop_);
111 }
112
113 void AppCoreTaskBase::Impl::LoopExit() {
114   g_main_loop_quit(loop_);
115 }
116
117 void AppCoreTaskBase::Impl::LoopFinish() {
118   g_main_loop_unref(loop_);
119 }
120
121 void AppCoreTaskBase::Impl::SetSystemEvents() {
122   parent_->AddEvent(low_memory_);
123   parent_->AddEvent(low_battery_);
124   parent_->AddEvent(lang_change_);
125   parent_->AddEvent(device_orientation_changed_);
126   parent_->AddEvent(region_change_);
127 }
128
129 void AppCoreTaskBase::Impl::UnsetSystemEvents() {
130   parent_->RemoveEvent(region_change_);
131   parent_->RemoveEvent(device_orientation_changed_);
132   parent_->RemoveEvent(lang_change_);
133   parent_->RemoveEvent(low_battery_);
134   parent_->RemoveEvent(low_memory_);
135 }
136
137 void AppCoreTaskBase::Impl::OnSystemEvent(IAppCore::IEvent::Type type) {
138   if (type == IAppCore::IEvent::Type::LOW_MEMORY) {
139     parent_->OnLowMemory(ConvertLowMemoryState(low_memory_->GetVal(0)));
140   } else if (type == IAppCore::IEvent::Type::LOW_BATTERY) {
141     parent_->OnLowBattery(ConvertLowBatteryState(low_battery_->GetVal(0)));
142   } else if (type == IAppCore::IEvent::Type::LANG_CHANGE) {
143     parent_->OnLangChanged(lang_change_->GetVal(""));
144   } else if (type == IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED) {
145     parent_->OnDeviceOrientationChanged(
146         ConvertRotationState(device_orientation_changed_->GetVal(0)));
147   } else if (type == IAppCore::IEvent::Type::REGION_CHANGE) {
148     parent_->OnRegionChanged(region_change_->GetVal(""));
149   }
150 }
151
152 void AppCoreTaskBase::Impl::Post(UiState state) {
153   std::lock_guard<std::recursive_mutex> lock(mutex_);
154   queue_.push(state);
155
156   GLib::IdleAdd(g_main_context_default(), [](gpointer user_data) {
157         auto* impl = static_cast<AppCoreTaskBase::Impl*>(user_data);
158         UiState state;
159         {
160           std::lock_guard<std::recursive_mutex> lock(impl->GetMutex());
161           state = impl->queue_.front();
162           impl->queue_.pop();
163         }
164         impl->parent_->OnUiEvent(state);
165         return G_SOURCE_REMOVE;
166       }, this);
167 }
168
169 std::recursive_mutex& AppCoreTaskBase::Impl::GetMutex() const {
170   return mutex_;
171 }
172
173 AppCoreTaskBase::DeviceOrientationState
174 AppCoreTaskBase::Impl::ConvertRotationState(int value) {
175   AppCoreTaskBase::DeviceOrientationState state;
176
177   switch (value) {
178     case AppCoreBase::ROTATION_PORTRAIT_NORMAL:
179       state = AppCoreTaskBase::DEVICE_ORIENTATION_STATE_0;
180       break;
181     case AppCoreBase::ROTATION_PORTRAIT_REVERSE:
182       state = AppCoreTaskBase::DEVICE_ORIENTATION_STATE_180;
183       break;
184     case AppCoreBase::ROTATION_LANDSCAPE_NORMAL:
185       state = AppCoreTaskBase::DEVICE_ORIENTATION_STATE_270;
186       break;
187     case AppCoreBase::ROTATION_LANDSCAPE_REVERSE:
188       state = AppCoreTaskBase::DEVICE_ORIENTATION_STATE_90;
189       break;
190     default:
191       state = AppCoreTaskBase::DEVICE_ORIENTATION_STATE_UNKNOWN;
192       break;
193   }
194
195   return state;
196 }
197
198 AppCoreTaskBase::LowMemoryState AppCoreTaskBase::Impl::ConvertLowMemoryState(
199     int value) {
200   AppCoreTaskBase::LowMemoryState state;
201
202   switch (value) {
203     case VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL:
204       state = AppCoreTaskBase::LOW_MEMORY_STATE_NORMAL;
205       break;
206     case VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING:
207       state = AppCoreTaskBase::LOW_MEMORY_STATE_SOFT_WARNING;
208       break;
209     case VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING:
210       state = AppCoreTaskBase::LOW_MEMORY_STATE_HARD_WARNING;
211       break;
212     default:
213       state = AppCoreTaskBase::LOW_MEMORY_STATE_UNKNOWN;
214       break;
215   }
216
217   return state;
218 }
219
220 AppCoreTaskBase::LowBatteryState AppCoreTaskBase::Impl::ConvertLowBatteryState(
221     int value) {
222   AppCoreTaskBase::LowBatteryState state;
223
224   switch (value) {
225     case VCONFKEY_SYSMAN_BAT_POWER_OFF:
226       state = AppCoreTaskBase::LOW_BATTERY_STATE_POWER_OFF;
227       break;
228     case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW:
229       state = AppCoreTaskBase::LOW_BATTERY_STATE_CRITICAL_LOW;
230       break;
231     default:
232       state = AppCoreTaskBase::LOW_BATTERY_STATE_UNKNOWN;
233       break;
234   }
235
236   return state;
237 }
238
239 AppCoreTaskBase::AppCoreTaskBase() : impl_(new Impl(this)) {}
240
241 AppCoreTaskBase::~AppCoreTaskBase() = default;
242
243 int AppCoreTaskBase::OnReceive(aul_type type, tizen_base::Bundle b) {
244   return AppCoreBase::OnReceive(type, std::move(b));
245 }
246
247 int AppCoreTaskBase::OnCreate() {
248   return 0;
249 }
250
251 int AppCoreTaskBase::OnTerminate() {
252   return AppCoreBase::OnTerminate();
253 }
254
255 int AppCoreTaskBase::OnControl(tizen_base::Bundle b) {
256   return AppCoreBase::OnControl(std::move(b));
257 }
258
259 int AppCoreTaskBase::OnTrimMemory() {
260   return AppCoreBase::OnTrimMemory();
261 }
262
263 void AppCoreTaskBase::OnLoopInit(int argc, char** argv) {
264   impl_->LoopInit(argc, argv);
265 }
266
267 void AppCoreTaskBase::OnLoopRun() {
268   impl_->LoopRun();
269 }
270
271 void AppCoreTaskBase::OnLoopExit() {
272   impl_->LoopExit();
273 }
274
275 void AppCoreTaskBase::OnLoopFinish() {
276   impl_->LoopFinish();
277 }
278
279 void AppCoreTaskBase::OnLowMemory(LowMemoryState state) {}
280
281 void AppCoreTaskBase::OnLowBattery(LowBatteryState state) {}
282
283 void AppCoreTaskBase::OnLangChanged(const std::string& lang) {}
284
285 void AppCoreTaskBase::OnDeviceOrientationChanged(DeviceOrientationState state) {}
286
287 void AppCoreTaskBase::OnRegionChanged(const std::string& region) {}
288
289 void AppCoreTaskBase::Run(int argc, char** argv) {
290   impl_->SetSystemEvents();
291   AppCoreBase::Run(argc, argv);
292   impl_->UnsetSystemEvents();
293 }
294
295 void AppCoreTaskBase::OnUiEvent(UiState state) {}
296
297 void AppCoreTaskBase::Post(UiState state) {
298   impl_->Post(state);
299 }
300
301 }  // namespace tizen_cpp