2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include "app-core-multi-window-cpp/app_core_multi_window_base.hh"
23 #include "common/ecore_handler.hh"
24 #include "common/log_private.hh"
28 class AppCoreMultiWindowBase::Context::Impl {
30 Impl(std::string context_id, std::string inst_id, AppCoreMultiWindowBase* app)
31 : id_(inst_id), context_id_(context_id), app_(app) {}
34 friend class AppCoreMultiWindowBase::Context;
37 std::string context_id_;
39 AppCoreMultiWindowBase* app_;
42 class AppCoreMultiWindowBase::Impl {
44 friend class AppCoreMultiWindowBase;
45 std::shared_ptr<EcoreHandler> handler_;
46 std::map<std::string, std::shared_ptr<Context::IFactory>> factory_map_;
47 std::list<std::shared_ptr<Context>> contexts_;
48 std::unique_ptr<EcoreHandler::ITrim> trim_;
51 AppCoreMultiWindowBase::Context::Context(std::string context_id,
52 std::string inst_id, AppCoreMultiWindowBase* app)
53 : impl_(std::make_unique<Impl>(
54 std::move(context_id), std::move(inst_id), app)) {
57 AppCoreMultiWindowBase::Context::~Context() = default;
59 void AppCoreMultiWindowBase::Context::Exit() {
64 void AppCoreMultiWindowBase::Context::Drop() {
68 void AppCoreMultiWindowBase::Context::Pause() {
73 impl_->paused_ = true;
76 void AppCoreMultiWindowBase::Context::Resume() {
81 impl_->paused_ = false;
84 bool AppCoreMultiWindowBase::Context::IsResumed() {
85 return !impl_->paused_;
88 const std::string& AppCoreMultiWindowBase::Context::GetInstId() const {
92 const std::string& AppCoreMultiWindowBase::Context::GetContextId() const {
93 return impl_->context_id_;
96 int AppCoreMultiWindowBase::Context::GetWindowId() const {
100 void AppCoreMultiWindowBase::Context::WindowBind(Ecore_Wl2_Window* wl_win) {
101 if (wl_win == nullptr) {
102 _E("Invalid parameter");
106 impl_->wid_ = ecore_wl2_window_id_get(wl_win);
109 void AppCoreMultiWindowBase::Context::WindowUnbind() {
113 AppCoreMultiWindowBase* AppCoreMultiWindowBase::Context::GetApp() {
117 AppCoreMultiWindowBase::AppCoreMultiWindowBase() :
118 impl_(std::make_unique<Impl>()) {}
120 AppCoreMultiWindowBase::~AppCoreMultiWindowBase() = default;
122 const std::list<std::shared_ptr<AppCoreMultiWindowBase::Context>>&
123 AppCoreMultiWindowBase::GetContexts() {
124 return impl_->contexts_;
127 int AppCoreMultiWindowBase::GetContextCnt() const {
128 return impl_->contexts_.size();
131 void AppCoreMultiWindowBase::ExitContext(
132 std::shared_ptr<AppCoreMultiWindowBase::Context> context) {
134 impl_->contexts_.remove(context);
137 std::shared_ptr<AppCoreMultiWindowBase::Context>
138 AppCoreMultiWindowBase::CreateContext(const std::string& context_id,
139 const std::string& inst_id) {
140 auto i = impl_->factory_map_.find(context_id);
141 if (i == impl_->factory_map_.end())
142 throw std::runtime_error("failed to find factory");
144 std::shared_ptr<Context> c = (*i).second->Create(inst_id, this);
148 std::shared_ptr<AppCoreMultiWindowBase::Context>
149 AppCoreMultiWindowBase::RunContext(
150 std::shared_ptr<AppCoreMultiWindowBase::Context> cxt) {
151 impl_->contexts_.push_back(cxt);
154 } catch (const std::runtime_error&) {
156 impl_->contexts_.remove(cxt);
163 std::shared_ptr<AppCoreMultiWindowBase::Context>
164 AppCoreMultiWindowBase::RunContext(const std::string& context_id,
165 const std::string& inst_id) {
166 auto c = CreateContext(context_id, inst_id);
167 return RunContext(c);
170 std::shared_ptr<AppCoreMultiWindowBase::Context>
171 AppCoreMultiWindowBase::FindById(const std::string& inst_id) {
172 for (auto& i : impl_->contexts_) {
173 if (i->GetInstId() == inst_id) {
181 std::shared_ptr<AppCoreMultiWindowBase::Context>
182 AppCoreMultiWindowBase::FindByWindowId(int win_id) {
183 for (auto& i : impl_->contexts_) {
184 if (i->GetWindowId() == win_id) {
192 void AppCoreMultiWindowBase::Run(int argc, char** argv) {
193 class Trimmer : public EcoreHandler::ITrim {
196 return base_->IsResumed();
200 base_->OnTrimMemory();
203 explicit Trimmer(AppCoreMultiWindowBase* base) : base_(base) {}
206 AppCoreMultiWindowBase* base_;
209 impl_->trim_ = std::unique_ptr<EcoreHandler::ITrim>(new Trimmer(this));
210 impl_->handler_ = std::make_shared<EcoreHandler>(this, impl_->trim_.get());
211 impl_->handler_->Init();
213 AppCoreBase::Run(argc, argv);
216 void AppCoreMultiWindowBase::Dispose() {
217 for (auto& i : impl_->contexts_) {
220 impl_->contexts_.clear();
221 impl_->factory_map_.clear();
223 AppCoreBase::Dispose();
224 if (impl_->handler_.get() != nullptr) {
225 impl_->handler_->UnsetEvents();
226 impl_->handler_->Fini();
230 int AppCoreMultiWindowBase::OnCreate() {
231 impl_->handler_->SetEvents();
232 AppCoreBase::OnCreate();
236 bool AppCoreMultiWindowBase::IsResumed() {
237 for (auto& i : impl_->contexts_) {
245 void AppCoreMultiWindowBase::OnShow(int type, void* event) {
248 void AppCoreMultiWindowBase::OnHide(int type, void* event) {
249 Ecore_Wl2_Event_Window_Hide* ev =
250 static_cast<Ecore_Wl2_Event_Window_Hide*>(event);
251 auto cxt = FindByWindowId(ev->win);
252 if (cxt.get() == nullptr)
258 void AppCoreMultiWindowBase::OnLower(int type, void* event) {
261 void AppCoreMultiWindowBase::OnVisibility(int type, void* event) {
262 auto* ev = static_cast<Ecore_Wl2_Event_Window_Visibility_Change*>(event);
263 auto cxt = FindByWindowId(ev->win);
264 if (cxt.get() == nullptr)
267 if (ev->fully_obscured)
268 cxt->Context::Pause();
270 cxt->Context::Resume();
273 void AppCoreMultiWindowBase::OnPreVisibility(int type, void* event) {
274 auto* ev = static_cast<Ecore_Wl2_Event_Window_Pre_Visibility_Change*>(event);
275 auto cxt = FindByWindowId(ev->win);
276 if (cxt.get() == nullptr)
279 if (ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED)
280 cxt->Context::Resume();
283 void AppCoreMultiWindowBase::OnAuxMessage(int type, void* event) {
284 auto* ev = static_cast<Ecore_Wl2_Event_Aux_Message*>(event);
285 if (ev->key && !strcmp(ev->key, "dpms_wm")) {
286 if (ev->val && !strcmp(ev->val, "on")) {
287 _D("Display state: on");
288 AppCoreBase::SetDisplayState(AppCoreBase::DISPLAY_STATE_ON);
289 } else if (ev->val && !strcmp(ev->val, "off")) {
290 _D("Display state: off");
291 AppCoreBase::SetDisplayState(AppCoreBase::DISPLAY_STATE_OFF);
293 _E("Unknown state: %s", ev->val);
298 void AppCoreMultiWindowBase::AddContextFactory(
299 std::shared_ptr<AppCoreMultiWindowBase::Context::IFactory> factory,
300 const std::string& context_id) {
301 impl_->factory_map_[context_id] = std::move(factory);
304 std::shared_ptr<AppCoreMultiWindowBase::Context::IFactory>
305 AppCoreMultiWindowBase::GetContextFactory(const std::string& context_id) {
306 return impl_->factory_map_[context_id];
309 } // namespace tizen_cpp