From 1821adaa196168935f3afe9f3853f88866d1ff6c Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 29 Jan 2024 10:56:15 +0900 Subject: [PATCH] Separate rotation implementation from app-core-cpp The AppCoreRotation class is added to separate the implmenetation related to using sensor library from the app-core-cpp. The AppCoreUiBase and the AppCoreMultiWindowBase use the AppCoreRotation. Change-Id: I0e59ed6c4411b7fb3477c268a8a51a3d59a19c42 Signed-off-by: Hwankyu Jhun --- CMakeLists.txt | 1 + packaging/app-core.spec | 5 + tizen-cpp/CMakeLists.txt | 1 + tizen-cpp/app-core-cpp/CMakeLists.txt | 1 - tizen-cpp/app-core-cpp/app_core_base.cc | 171 +-------------------- tizen-cpp/app-core-cpp/app_core_base.hh | 1 + tizen-cpp/app-core-multi-window-cpp/CMakeLists.txt | 1 + .../app_core_multi_window_base.cc | 52 ++++++- .../app_core_multi_window_base.hh | 4 +- tizen-cpp/app-core-rotation-cpp/CMakeLists.txt | 33 ++++ .../app-core-rotation-cpp.pc.in | 14 ++ .../app-core-rotation-cpp/app_core_rotation.cc | 131 ++++++++++++++++ .../app-core-rotation-cpp/app_core_rotation.hh | 61 ++++++++ tizen-cpp/app-core-ui-cpp/CMakeLists.txt | 1 + tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc | 41 ++++- tizen-cpp/app-core-ui-cpp/app_core_ui_base.hh | 2 + unittests/CMakeLists.txt | 3 + unittests/app_core_base_test.cc | 139 ++--------------- 18 files changed, 368 insertions(+), 294 deletions(-) create mode 100644 tizen-cpp/app-core-rotation-cpp/CMakeLists.txt create mode 100644 tizen-cpp/app-core-rotation-cpp/app-core-rotation-cpp.pc.in create mode 100644 tizen-cpp/app-core-rotation-cpp/app_core_rotation.cc create mode 100644 tizen-cpp/app-core-rotation-cpp/app_core_rotation.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index 36b2ac0..c52b31b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ SET(TARGET_APP_CORE_CPP "app-core-cpp") SET(TARGET_APP_CORE_UI_CPP "app-core-ui-cpp") SET(TARGET_APP_CORE_EFL_CPP "app-core-efl-cpp") SET(TARGET_APP_CORE_MULTI_WINDOW_CPP "app-core-multi-window-cpp") +SET(TARGET_APP_CORE_ROTATION_CPP "app-core-rotation-cpp") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs -pie" ) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") diff --git a/packaging/app-core.spec b/packaging/app-core.spec index 7a5e715..6524eac 100644 --- a/packaging/app-core.spec +++ b/packaging/app-core.spec @@ -261,6 +261,7 @@ install -m 0644 %{name}.zip %{buildroot}%{_datadir}/gcov/ %{_libdir}/libappcore-common.so.* %{_libdir}/libapp-core-cpp.so.* +%{_libdir}/libapp-core-rotation-cpp.so.* %license LICENSE %files common-devel @@ -281,6 +282,10 @@ install -m 0644 %{name}.zip %{buildroot}%{_datadir}/gcov/ %{_libdir}/libapp-core-cpp.so %{_libdir}/pkgconfig/app-core-cpp.pc +%{_includedir}/appcore_cpp/app_core_rotation.hh +%{_libdir}/libapp-core-rotation-cpp.so +%{_libdir}/pkgconfig/app-core-rotation-cpp.pc + %files ui %manifest %{name}.manifest %{_libdir}/libappcore-ui.so.* diff --git a/tizen-cpp/CMakeLists.txt b/tizen-cpp/CMakeLists.txt index 0814703..569335c 100644 --- a/tizen-cpp/CMakeLists.txt +++ b/tizen-cpp/CMakeLists.txt @@ -2,3 +2,4 @@ ADD_SUBDIRECTORY(app-core-efl-cpp) ADD_SUBDIRECTORY(app-core-multi-window-cpp) ADD_SUBDIRECTORY(app-core-cpp) ADD_SUBDIRECTORY(app-core-ui-cpp) +ADD_SUBDIRECTORY(app-core-rotation-cpp) diff --git a/tizen-cpp/app-core-cpp/CMakeLists.txt b/tizen-cpp/app-core-cpp/CMakeLists.txt index 6f427fb..0534880 100644 --- a/tizen-cpp/app-core-cpp/CMakeLists.txt +++ b/tizen-cpp/app-core-cpp/CMakeLists.txt @@ -18,7 +18,6 @@ APPLY_PKG_CONFIG(${TARGET_APP_CORE_CPP} PUBLIC BUNDLE_DEPS DLOG_DEPS GIO_2_DEPS - SENSOR_DEPS TTRACE_DEPS VCONF_DEPS ) diff --git a/tizen-cpp/app-core-cpp/app_core_base.cc b/tizen-cpp/app-core-cpp/app_core_base.cc index 2e14d8a..021435e 100644 --- a/tizen-cpp/app-core-cpp/app_core_base.cc +++ b/tizen-cpp/app-core-cpp/app_core_base.cc @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -71,16 +70,7 @@ internal::SigtermHandler sigterm_handler; constexpr const char PATH_LOCALE[] = "locale"; constexpr int SQLITE_FLUSH_MAX = 1024 * 1024; -struct Rotation { - int conn; - int lock; - int ref; - tizen_cpp::AppCoreBase::RotationState rm; - int charger_status; - bool initialized; -}; - -Rotation __rotation; +AppCoreBase::RotationState __rotation_state = AppCoreBase::ROTATION_UNKNOWN; AppCoreBase::DisplayState __display_state = AppCoreBase::DISPLAY_STATE_UNKNOWN; } // namespace @@ -98,8 +88,6 @@ class AppCoreBase::Impl : public SuspendEvent::IEventListener { explicit Impl(AppCoreBase* parent) : parent_(parent) {} private: - void UnregisterRotationChangedEvent(); - void RegisterRotationChangedEvent(); std::string GetAppName(const char* appid); std::string GetLocaleResourceDir(); void UpdateLang(); @@ -134,15 +122,9 @@ class AppCoreBase::Impl : public SuspendEvent::IEventListener { static gboolean InvokeLangChangeCb(gpointer data); static void OnLowBatteryCb(keynode_t* key, void* data); static void OnTimeZoneChangedCb(keynode_t* key, void* data); - static void LockCb(keynode_t* node, void* user_data); - static void AutoRotationChangedCb(sensor_t sensor, unsigned int event_type, - sensor_data_t* data, void* user_data); static void LanguageChangeCb(keynode_t* key, void* data); static void RegionChangeCb(keynode_t* key, void* data); static void LowMemoryCb(keynode_t* key, void* data); - void InitRotation(); - void FiniRotation(); - RotationState GetRm(sensor_data_t data); void VerifyLanguage(); void SetDefaultEvents(); void UnsetDefaultEvents(); @@ -246,27 +228,6 @@ void AppCoreBase::Impl::OnFreezerSignal() { } } -AppCoreBase::RotationState AppCoreBase::Impl::GetRm(sensor_data_t data) { - if (data.value_count <= 0) { - _E("Failed to get sensor data"); - return ROTATION_UNKNOWN; - } - - int event = data.values[0]; - switch (event) { - case AUTO_ROTATION_DEGREE_0: - return ROTATION_PORTRAIT_NORMAL; - case AUTO_ROTATION_DEGREE_90: - return ROTATION_LANDSCAPE_NORMAL; - case AUTO_ROTATION_DEGREE_180: - return ROTATION_PORTRAIT_REVERSE; - case AUTO_ROTATION_DEGREE_270: - return ROTATION_LANDSCAPE_REVERSE; - default: - return ROTATION_UNKNOWN; - } -} - void AppCoreBase::Impl::InitSuspend() { suspend_event_.reset(new SuspendEvent(this)); } @@ -324,113 +285,6 @@ void AppCoreBase::Impl::LowMemoryCb(keynode_t* key, void* user_data) { malloc_trim(0); } -void AppCoreBase::Impl::LockCb(keynode_t* node, void* user_data) { - AppCoreBase::RotationState rm; - AppCoreBase* base = reinterpret_cast(user_data); - - __rotation.lock = !vconf_keynode_get_bool(node); - if (__rotation.lock) { - _D("Rotation locked"); - rm = ROTATION_PORTRAIT_NORMAL; - } else { - _D("Rotation unlocked"); - sensor_data_t data; - bool r = sensord_get_data(__rotation.conn, AUTO_ROTATION_SENSOR, &data); - if (!r) { - _E("Failed to get sensor data"); - return; - } - - rm = base->impl_->GetRm(data); - if (rm == ROTATION_UNKNOWN) { - _E("Unknown mode"); - return; - } - } - - if (__rotation.rm == rm) - return; - - _D("Rotation: %d -> %d", __rotation.rm, rm); - __rotation.rm = rm; - base->impl_->InvokeCallback(__rotation.rm, - IEvent::Type::DEVICE_ORIENTATION_CHANGED); -} - -void AppCoreBase::Impl::AutoRotationChangedCb(sensor_t sensor, - unsigned int event_type, sensor_data_t* data, void* user_data) { - if (data == nullptr) - return; - - if (__rotation.lock) - return; - - if (event_type != AUTO_ROTATION_CHANGE_STATE_EVENT) - return; - - AppCoreBase* base = reinterpret_cast(user_data); - AppCoreBase::RotationState rm = base->impl_->GetRm(*data); - if (rm == ROTATION_UNKNOWN) { - _E("Unknown mode"); - return; - } - - _D("Rotation: %d -> %d", __rotation.rm, rm); - __rotation.rm = rm; - base->impl_->InvokeCallback(__rotation.rm, - IEvent::Type::DEVICE_ORIENTATION_CHANGED); -} - -void AppCoreBase::Impl::InitRotation() { - if (__rotation.initialized) - return; - - sensor_t sensor = sensord_get_sensor(AUTO_ROTATION_SENSOR); - __rotation.conn = sensord_connect(sensor); - if (__rotation.conn < 0) { - _E("Failed to connect sensord"); - return; - } - - bool r = sensord_register_event(__rotation.conn, - AUTO_ROTATION_CHANGE_STATE_EVENT, SENSOR_INTERVAL_NORMAL, 0, - AutoRotationChangedCb, parent_); - if (!r) { - _E("Failed to register auto rotation change event"); - sensord_disconnect(__rotation.conn); - return; - } - - r = sensord_start(__rotation.conn, 0); - if (!r) { - _E("Failed to start sensord"); - sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT); - sensord_disconnect(__rotation.conn); - return; - } - - int lock = 0; - vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock); - vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, LockCb, - parent_); - - __rotation.lock = !lock; - __rotation.initialized = true; -} - -void AppCoreBase::Impl::FiniRotation() { - if (!__rotation.initialized) - return; - - vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, LockCb); - sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT); - sensord_stop(__rotation.conn); - sensord_disconnect(__rotation.conn); - - __rotation.lock = 0; - __rotation.initialized = false; -} - void AppCoreBase::Impl::VerifyLanguage() { const char* env_lang = getenv("LANG"); if (env_lang == nullptr) @@ -648,20 +502,6 @@ void AppCoreBase::Impl::OnTimeZoneChangedCb(keynode_t* key, void* data) { } } -void AppCoreBase::Impl::UnregisterRotationChangedEvent() { - if (!__rotation.ref) - return; - - __rotation.ref--; - if (__rotation.ref == 0) FiniRotation(); -} - -void AppCoreBase::Impl::RegisterRotationChangedEvent() { - if (__rotation.ref == 0) InitRotation(); - - __rotation.ref++; -} - int AppCoreBase::OnSetEvent(IEvent::Type event) { switch (event) { case IEvent::Type::LOW_BATTERY: @@ -669,7 +509,6 @@ int AppCoreBase::OnSetEvent(IEvent::Type event) { impl_->OnLowBatteryCb, this); break; case IEvent::Type::DEVICE_ORIENTATION_CHANGED: - impl_->RegisterRotationChangedEvent(); break; case IEvent::Type::SUSPENDED_STATE_CHANGE: break; @@ -687,7 +526,6 @@ int AppCoreBase::OnUnsetEvent(IEvent::Type event) { impl_->OnLowBatteryCb); break; case IEvent::Type::DEVICE_ORIENTATION_CHANGED: - impl_->UnregisterRotationChangedEvent(); break; case IEvent::Type::SUSPENDED_STATE_CHANGE: break; @@ -759,10 +597,11 @@ void AppCoreBase::FlushMemory() { } AppCoreBase::RotationState AppCoreBase::GetRotationState() { - if (!__rotation.ref) - throw std::runtime_error("invalid rotation state"); + return __rotation_state; +} - return __rotation.rm; +void AppCoreBase::SetRotationState(RotationState state) { + __rotation_state = state; } bool AppCoreBase::IsBgAllowed() { diff --git a/tizen-cpp/app-core-cpp/app_core_base.hh b/tizen-cpp/app-core-cpp/app_core_base.hh index 815c6ff..d8196a0 100644 --- a/tizen-cpp/app-core-cpp/app_core_base.hh +++ b/tizen-cpp/app-core-cpp/app_core_base.hh @@ -105,6 +105,7 @@ class EXPORT_API AppCoreBase : public IAppCore, public IMainLoop { static int EnableWatchdog(); static int DisableWatchdog(); static int KickWatchdog(); + static void SetRotationState(RotationState state); protected: void SetCoreDelegator(IAppCore* delegator); diff --git a/tizen-cpp/app-core-multi-window-cpp/CMakeLists.txt b/tizen-cpp/app-core-multi-window-cpp/CMakeLists.txt index 3cf26f2..65f0299 100644 --- a/tizen-cpp/app-core-multi-window-cpp/CMakeLists.txt +++ b/tizen-cpp/app-core-multi-window-cpp/CMakeLists.txt @@ -13,6 +13,7 @@ TARGET_INCLUDE_DIRECTORIES(${TARGET_APP_CORE_MULTI_WINDOW_CPP} PUBLIC TARGET_LINK_LIBRARIES(${TARGET_APP_CORE_MULTI_WINDOW_CPP} PUBLIC ${TARGET_APP_CORE_CPP} + ${TARGET_APP_CORE_ROTATION_CPP} "-L${LIB_INSTALL_DIR}/hal") SET_TARGET_PROPERTIES(${TARGET_APP_CORE_MULTI_WINDOW_CPP} diff --git a/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.cc b/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.cc index 86261da..f69eca0 100644 --- a/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.cc +++ b/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.cc @@ -14,12 +14,15 @@ * limitations under the License. */ +#include "app-core-multi-window-cpp/app_core_multi_window_base.hh" + #include #include #include #include +#include -#include "app-core-multi-window-cpp/app_core_multi_window_base.hh" +#include "app-core-rotation-cpp/app_core_rotation.hh" #include "common/ecore_handler.hh" #include "common/log_private.hh" @@ -39,13 +42,24 @@ class AppCoreMultiWindowBase::Context::Impl { AppCoreMultiWindowBase* app_; }; -class AppCoreMultiWindowBase::Impl { +class AppCoreMultiWindowBase::Impl : public AppCoreRotation::IEventListener { + public: + explicit Impl(AppCoreMultiWindowBase* parent) : parent_(parent) {} + + private: + void RotationInit(); + void RotationShutdown(); + void OnRotationChanged(int degree) override; + private: friend class AppCoreMultiWindowBase; + AppCoreMultiWindowBase* parent_; + std::shared_ptr handler_; std::map> factory_map_; std::list> contexts_; std::unique_ptr trim_; + std::unique_ptr rotation_; }; AppCoreMultiWindowBase::Context::Context(std::string context_id, @@ -115,7 +129,7 @@ AppCoreMultiWindowBase* AppCoreMultiWindowBase::Context::GetApp() { } AppCoreMultiWindowBase::AppCoreMultiWindowBase() : - impl_(std::make_unique()) {} + impl_(std::make_unique(this)) {} AppCoreMultiWindowBase::~AppCoreMultiWindowBase() = default; @@ -306,4 +320,36 @@ AppCoreMultiWindowBase::GetContextFactory(const std::string& context_id) { return impl_->factory_map_[context_id]; } +void AppCoreMultiWindowBase::Impl::RotationInit() { + if (!rotation_) rotation_.reset(new AppCoreRotation(this)); + + rotation_->Init(); +} + +void AppCoreMultiWindowBase::Impl::RotationShutdown() { + if (rotation_) rotation_->Dispose(); +} + +void AppCoreMultiWindowBase::Impl::OnRotationChanged(int degree) { + AppCoreBase::SetRotationState( + static_cast(degree)); + parent_->RaiseEvent(degree, IEvent::Type::DEVICE_ORIENTATION_CHANGED); +} + +int AppCoreMultiWindowBase::OnSetEvent(IEvent::Type event) { + AppCoreBase::OnSetEvent(event); + if (event == IEvent::Type::DEVICE_ORIENTATION_CHANGED) + impl_->RotationInit(); + + return 0; +} + +int AppCoreMultiWindowBase::OnUnsetEvent(IEvent::Type event) { + AppCoreBase::OnUnsetEvent(event); + if (event == IEvent::Type::DEVICE_ORIENTATION_CHANGED) + impl_->RotationShutdown(); + + return 0; +} + } // namespace tizen_cpp diff --git a/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.hh b/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.hh index d308f0b..8a502df 100644 --- a/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.hh +++ b/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.hh @@ -94,6 +94,8 @@ class EXPORT_API AppCoreMultiWindowBase : public AppCoreBase, public IWindow { std::shared_ptr GetContextFactory( const std::string& context_id); void Dispose() override; + int OnSetEvent(IEvent::Type event) override; + int OnUnsetEvent(IEvent::Type event) override; private: class Impl; @@ -102,4 +104,4 @@ class EXPORT_API AppCoreMultiWindowBase : public AppCoreBase, public IWindow { } // namespace tizen_cpp -#endif // TIZEN_CPP_APP_CORE_MULTI_WINDOW_CPP__APP_CORE_MULTI_WINDOW_BASE_HH_ +#endif // TIZEN_CPP_APP_CORE_MULTI_WINDOW_CPP_APP_CORE_MULTI_WINDOW_BASE_HH_ diff --git a/tizen-cpp/app-core-rotation-cpp/CMakeLists.txt b/tizen-cpp/app-core-rotation-cpp/CMakeLists.txt new file mode 100644 index 0000000..de705a7 --- /dev/null +++ b/tizen-cpp/app-core-rotation-cpp/CMakeLists.txt @@ -0,0 +1,33 @@ +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_CORE_ROTATION_CPP_SRCS) + +ADD_LIBRARY(${TARGET_APP_CORE_ROTATION_CPP} SHARED + ${APP_CORE_ROTATION_CPP_SRCS}) + +TARGET_INCLUDE_DIRECTORIES(${TARGET_APP_CORE_ROTATION_CPP} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../) + +TARGET_LINK_LIBRARIES(${TARGET_APP_CORE_ROTATION_CPP} PUBLIC + "-L${LIB_INSTALL_DIR}/hal") + +SET_TARGET_PROPERTIES(${TARGET_APP_CORE_ROTATION_CPP} + PROPERTIES SOVERSION ${MAJORVER}) +SET_TARGET_PROPERTIES(${TARGET_APP_CORE_ROTATION_CPP} + PROPERTIES VERSION ${FULLVER}) + +APPLY_PKG_CONFIG(${TARGET_APP_CORE_ROTATION_CPP} PUBLIC + DLOG_DEPS + SENSOR_DEPS + VCONF_DEPS +) + +CONFIGURE_FILE(${TARGET_APP_CORE_ROTATION_CPP}.pc.in + ${TARGET_APP_CORE_ROTATION_CPP}.pc @ONLY) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_APP_CORE_ROTATION_CPP}.pc + DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + +INSTALL(TARGETS ${TARGET_APP_CORE_ROTATION_CPP} DESTINATION ${LIB_INSTALL_DIR}) +INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include/appcore_cpp + FILES_MATCHING + PATTERN "*_private.hh" EXCLUDE + PATTERN "*.hh") diff --git a/tizen-cpp/app-core-rotation-cpp/app-core-rotation-cpp.pc.in b/tizen-cpp/app-core-rotation-cpp/app-core-rotation-cpp.pc.in new file mode 100644 index 0000000..48c7bd5 --- /dev/null +++ b/tizen-cpp/app-core-rotation-cpp/app-core-rotation-cpp.pc.in @@ -0,0 +1,14 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDEDIR@ + +Name: app-core-rotation-cpp +Description: Tizen application core library for rotation event +Version: @VERSION@ +Requires.private: dlog sensor vconf +Libs: -L${libdir} -lapp-core-rotation-cpp +Cflags: -I${includedir} -I${includedir}/appcore_cpp +cppflags: I${includedir} -I${includedir}/appcore_cpp diff --git a/tizen-cpp/app-core-rotation-cpp/app_core_rotation.cc b/tizen-cpp/app-core-rotation-cpp/app_core_rotation.cc new file mode 100644 index 0000000..c6b08ba --- /dev/null +++ b/tizen-cpp/app-core-rotation-cpp/app_core_rotation.cc @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2024 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 "app-core-rotation-cpp/app_core_rotation.hh" + +#include "common/log_private.hh" + +namespace tizen_cpp { + +AppCoreRotation::AppCoreRotation(IEventListener* listener) + : listener_(listener) {} + +AppCoreRotation::~AppCoreRotation() { Dispose(); } + +bool AppCoreRotation::Init() { + if (!disposed_) { + ref_++; + return true; + } + + sensor_t sensor = sensord_get_sensor(AUTO_ROTATION_SENSOR); + conn_ = sensord_connect(sensor); + if (conn_ < 0) { + _E("sensord_connect() is failed"); + return false; + } + + if (!sensord_register_event(conn_, AUTO_ROTATION_CHANGE_STATE_EVENT, + SENSOR_INTERVAL_NORMAL, 0, SensorEventCb, this)) { + _E("sensord_register_event() is failed"); + sensord_disconnect(conn_); + conn_ = 0; + return false; + } + + if (!sensord_start(conn_, 0)) { + _E("sensord_start() is failed"); + sensord_unregister_event(conn_, AUTO_ROTATION_CHANGE_STATE_EVENT); + sensord_disconnect(conn_); + conn_ = 0; + return false; + } + + int lock = 0; + vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock); + vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, VconfCb, + this); + + lock_ = !lock; + ref_++; + disposed_ = false; + return true; +} + +void AppCoreRotation::Dispose() { + if (disposed_) return; + + ref_--; + if (ref_ > 0) return; + + vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, VconfCb); + sensord_unregister_event(conn_, AUTO_ROTATION_CHANGE_STATE_EVENT); + sensord_stop(conn_); + sensord_disconnect(conn_); + conn_ = 0; + lock_ = 0; + disposed_ = true; +} + +bool AppCoreRotation::IsLocked() const { return lock_; } + +int AppCoreRotation::GetDegree() const { return degree_; } + +void AppCoreRotation::SensorEventCb(sensor_t sensor, unsigned int event_type, + sensor_data_t* data, void* user_data) { + if (event_type != AUTO_ROTATION_CHANGE_STATE_EVENT) return; + + auto self = static_cast(user_data); + if (self->IsLocked()) return; + + int degree = static_cast(data->values[0]); + if (degree == static_cast(AUTO_ROTATION_DEGREE_UNKNOWN)) return; + + if (self->degree_ == degree) return; + + _D("Rotation: %d -> %d", self->degree_, degree); + self->degree_ = degree; + self->listener_->OnRotationChanged(degree); +} + +void AppCoreRotation::VconfCb(keynode_t* node, void* user_data) { + int degree; + auto self = static_cast(user_data); + self->lock_ = !vconf_keynode_get_bool(node); + if (self->lock_) { + _D("Rotation locked"); + degree = 0; + } else { + _D("Rotation unlocked"); + sensor_data_t data; + if (!sensord_get_data(self->conn_, AUTO_ROTATION_CHANGE_STATE_EVENT, + &data)) { + _E("sensord_get_data() is failed"); + return; + } + + degree = static_cast(data.values[0]); + if (degree == static_cast(AUTO_ROTATION_DEGREE_UNKNOWN)) return; + } + + if (self->degree_ == degree) return; + + _D("Rotation: %d -> %d", self->degree_, degree); + self->degree_ = degree; + self->listener_->OnRotationChanged(degree); +} + +} // namespace tizen_cpp diff --git a/tizen-cpp/app-core-rotation-cpp/app_core_rotation.hh b/tizen-cpp/app-core-rotation-cpp/app_core_rotation.hh new file mode 100644 index 0000000..4798436 --- /dev/null +++ b/tizen-cpp/app-core-rotation-cpp/app_core_rotation.hh @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 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_CPP_APP_CORE_ROTATION_CPP_APP_CORE_ROTATION_HH_ +#define TIZEN_CPP_APP_CORE_ROTATION_CPP_APP_CORE_ROTATION_HH_ + +#include +#include + +#undef EXPORT_API +#define EXPORT_API __attribute__((visibility("default"))) + +namespace tizen_cpp { + +class EXPORT_API AppCoreRotation { + public: + class IEventListener { + public: + virtual ~IEventListener() = default; + virtual void OnRotationChanged(int degree) = 0; + }; + + explicit AppCoreRotation(IEventListener* listener); + ~AppCoreRotation(); + + bool Init(); + void Dispose(); + + bool IsLocked() const; + int GetDegree() const; + + private: + static void SensorEventCb(sensor_t sensor, unsigned int event_type, + sensor_data_t* data, void* user_data); + static void VconfCb(keynode_t* node, void* user_data); + + private: + bool disposed_ = true; + IEventListener* listener_; + int conn_ = 0; + int lock_ = 0; + uint32_t ref_ = 0; + int degree_ = 0; +}; + +} // namespace tizen_cpp + +#endif // TIZEN_CPP_APP_CORE_ROTATION_CPP_APP_CORE_ROTATION_HH_ diff --git a/tizen-cpp/app-core-ui-cpp/CMakeLists.txt b/tizen-cpp/app-core-ui-cpp/CMakeLists.txt index 6c52af8..2e5fa17 100644 --- a/tizen-cpp/app-core-ui-cpp/CMakeLists.txt +++ b/tizen-cpp/app-core-ui-cpp/CMakeLists.txt @@ -14,6 +14,7 @@ TARGET_INCLUDE_DIRECTORIES(${TARGET_APP_CORE_UI_CPP} PUBLIC TARGET_LINK_LIBRARIES(${TARGET_APP_CORE_UI_CPP} PUBLIC ${TARGET_APP_CORE_CPP} + ${TARGET_APP_CORE_ROTATION_CPP} "-L${LIB_INSTALL_DIR}/hal") SET_TARGET_PROPERTIES(${TARGET_APP_CORE_UI_CPP} diff --git a/tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc b/tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc index 2eeb488..beeef29 100644 --- a/tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc +++ b/tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc @@ -35,6 +35,7 @@ #include #include "app-core-cpp/app_core_base.hh" +#include "app-core-rotation-cpp/app_core_rotation.hh" #include "app-core-ui-cpp/api/app_core_ui_base.h" #include "app-core-ui-cpp/app_core_task_base.hh" #include "app-core-ui-cpp/app_core_ui_delegator_private.hh" @@ -54,7 +55,7 @@ constexpr const char K_HINT_RECENT_SCREEN_POSITION[] = "__K_HINT_RECENT_SCREEN_POSITION"; const int APPID_MAX = 256; -class AppCoreUiBase::Impl { +class AppCoreUiBase::Impl : public AppCoreRotation::IEventListener { public: Impl(AppCoreUiBase* parent, unsigned int hint) : parent_(parent), @@ -122,6 +123,9 @@ class AppCoreUiBase::Impl { Ecore_Wl2_Window* GetWindow() const; void Run(int argc, char** argv); void Exit(); + void RotationInit(); + void RotationShutdown(); + void OnRotationChanged(int degree) override; std::list> winnode_list_; unsigned int hint_; @@ -142,6 +146,7 @@ class AppCoreUiBase::Impl { Ecore_Wl2_Window* window_ = nullptr; std::unique_ptr wp_manager_; std::unique_ptr thread_; + std::unique_ptr rotation_; }; AppCoreUiBase::AppCoreUiBase(unsigned int hint) @@ -544,6 +549,22 @@ void AppCoreUiBase::Impl::Exit() { parent_->DoExit(); } +void AppCoreUiBase::Impl::RotationInit() { + if (!rotation_) rotation_.reset(new AppCoreRotation(this)); + + rotation_->Init(); +} + +void AppCoreUiBase::Impl::RotationShutdown() { + if (rotation_) rotation_->Dispose(); +} + +void AppCoreUiBase::Impl::OnRotationChanged(int degree) { + AppCoreBase::SetRotationState( + static_cast(degree)); + parent_->RaiseEvent(degree, IEvent::Type::DEVICE_ORIENTATION_CHANGED); +} + void AppCoreUiBase::Run(int argc, char** argv) { impl_->Run(argc, argv); } @@ -980,4 +1001,22 @@ int AppCoreUiBase::GetWindowPosition(int* x, int* y, int* w, int* h) { return 0; } +int AppCoreUiBase::OnSetEvent(IEvent::Type event) { + AppCoreBase::OnSetEvent(event); + + if (event == IEvent::Type::DEVICE_ORIENTATION_CHANGED) + impl_->RotationInit(); + + return 0; +} + +int AppCoreUiBase::OnUnsetEvent(IEvent::Type event) { + AppCoreBase::OnUnsetEvent(event); + + if (event == IEvent::Type::DEVICE_ORIENTATION_CHANGED) + impl_->RotationShutdown(); + + return 0; +} + } // namespace tizen_cpp diff --git a/tizen-cpp/app-core-ui-cpp/app_core_ui_base.hh b/tizen-cpp/app-core-ui-cpp/app_core_ui_base.hh index 0c4acac..a7f0ec3 100644 --- a/tizen-cpp/app-core-ui-cpp/app_core_ui_base.hh +++ b/tizen-cpp/app-core-ui-cpp/app_core_ui_base.hh @@ -74,6 +74,8 @@ class EXPORT_API AppCoreUiBase : public AppCoreBase, virtual std::unique_ptr CreateTask(); void Exit() override; int GetWindowPosition(int* x, int* y, int* w, int* h); + int OnSetEvent(IEvent::Type event) override; + int OnUnsetEvent(IEvent::Type event) override; protected: void SetCoreUiDelegator(IAppCoreUi* delegator); diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 2e79bc9..fa272bf 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -2,6 +2,8 @@ SET(TARGET_UNIT_TEST "app-core_unittests") AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-cpp LIB_APP_CORE_CPP_SRCS) +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-rotation-cpp + LIB_APP_CORE_ROTATION_CPP_SRCS) AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-ui-cpp LIB_APP_CORE_UI_CPP_SRCS) AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-ui-cpp/api @@ -19,6 +21,7 @@ ADD_EXECUTABLE(${TARGET_UNIT_TEST} ${MOCK_SRCS} ${TEST_SRCS} ${LIB_APP_CORE_CPP_SRCS} + ${LIB_APP_CORE_ROTATION_CPP_SRCS} ${LIB_APP_CORE_UI_CPP_SRCS} ${LIB_APP_CORE_UI_CPP_API_SRCS} ${LIB_APP_CORE_EFL_CPP_SRCS} diff --git a/unittests/app_core_base_test.cc b/unittests/app_core_base_test.cc index 08c749d..698daa3 100644 --- a/unittests/app_core_base_test.cc +++ b/unittests/app_core_base_test.cc @@ -14,21 +14,21 @@ * limitations under the License. */ -#include -#include -#include #include #include +#include +#include +#include -#include "mock/test_fixture.h" +#include + +#include "mock/app_core_base_mock.h" #include "mock/aul_mock.h" -#include "mock/sensor_mock.h" -#include "mock/vconf_mock.h" #include "mock/dbus_mock.h" #include "mock/dl_mock.h" -#include "mock/app_core_base_mock.h" - -#include +#include "mock/sensor_mock.h" +#include "mock/test_fixture.h" +#include "mock/vconf_mock.h" using ::testing::_; using ::testing::DoAll; @@ -104,7 +104,7 @@ class DummyArgs { class TestEvent : public AppCoreBase::EventBase { public: - TestEvent(Type type) : EventBase(type) {} + explicit TestEvent(Type type) : EventBase(type) {} void OnEvent(const std::string& val) override { SetVal(val); @@ -268,11 +268,12 @@ TEST_F(AppCoreBaseTest, AppCoreBase_AllowBG) { EXPECT_CALL(core, OnTerminate()) .Times(1); EXPECT_CALL(core, OnReceive(_, _)) - .WillOnce(Invoke([&core, &bg](aul_type type, tizen_base::Bundle b) -> int { - int ret = core.AppCoreBase::OnReceive(type, std::move(b)); - bg = core.IsBgAllowed(); - return ret; - })); + .WillOnce( + Invoke([&core, &bg](aul_type type, tizen_base::Bundle b) -> int { + int ret = core.AppCoreBase::OnReceive(type, std::move(b)); + bg = core.IsBgAllowed(); + return ret; + })); DummyArgs da(AUL_K_ALLOWED_BG, "ALLOWED_BG"); core.SetFeature(AppCoreBase::FEATURE_BACKGROUND_MANAGEMENT); @@ -315,112 +316,6 @@ TEST_F(AppCoreBaseTest, AppCoreBase_FlushMemory) { core.Run(da.GetArgc(), da.GetArgv()); } -TEST_F(AppCoreBaseTest, AppCoreBase_GetRotationState_N) { - bool result = false; - - try { - AppCoreBase::GetRotationState(); - } catch (const std::runtime_error& e) { - EXPECT_STREQ(e.what(), "invalid rotation state"); - result = true; - } - - EXPECT_TRUE(result); -} - -TEST_F(AppCoreBaseTest, AppCoreBase_GetRotationState) { - testing::NiceMock core; - AppCoreBase::RotationState rst = AppCoreBase::ROTATION_UNKNOWN; - - EXPECT_CALL(core, OnCreate()) - .WillOnce(Invoke([&core, &rst]() -> int { - core.AppCoreBase::OnCreate(); - rst = AppCoreBase::GetRotationState(); - g_idle_add_full(G_PRIORITY_LOW, [](gpointer data) -> gboolean { - auto* obj = static_cast*>(data); - obj->Exit(); - return G_SOURCE_REMOVE; - }, &core, nullptr); - return 0; - })); - EXPECT_CALL(core, OnTerminate()) - .Times(1); - EXPECT_CALL(GetMock(), sensord_register_event(_, _, _, _, _, _)) - .WillOnce(Invoke([](int handle, unsigned int event_type, - unsigned int interval, unsigned int max_batch_latency, - sensor_cb_t cb, void *user_data) -> bool { - sensor_t sensor = { 0, }; - sensor_data_t data = { 0, }; - data.value_count = 1; - data.values[0] = AUTO_ROTATION_DEGREE_0; - cb(sensor, AUTO_ROTATION_CHANGE_STATE_EVENT, &data, user_data); - return true; - })); - - DummyArgs da; - auto ev = std::shared_ptr( - new TestEvent(IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED)); - core.AddEvent(ev); - core.Run(da.GetArgc(), da.GetArgv()); - EXPECT_EQ(rst, AppCoreBase::ROTATION_PORTRAIT_NORMAL); - core.RemoveEvent(ev); -} - -TEST_F(AppCoreBaseTest, AppCoreBase_LockCb) { - testing::NiceMock core; - AppCoreBase::RotationState rst = AppCoreBase::ROTATION_UNKNOWN; - - EXPECT_CALL(core, OnCreate()) - .WillOnce(Invoke([&core, &rst]() -> int { - core.AppCoreBase::OnCreate(); - GetMock().ChangeBool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, true); - rst = AppCoreBase::GetRotationState(); - g_idle_add_full(G_PRIORITY_LOW, [](gpointer data) -> gboolean { - auto* obj = static_cast*>(data); - obj->Exit(); - return G_SOURCE_REMOVE; - }, &core, nullptr); - return 0; - })); - EXPECT_CALL(core, OnTerminate()) - .Times(1); - - DummyArgs da; - auto ev = std::shared_ptr( - new TestEvent(IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED)); - core.AddEvent(ev); - core.Run(da.GetArgc(), da.GetArgv()); - EXPECT_EQ(rst, AppCoreBase::ROTATION_PORTRAIT_NORMAL); - core.RemoveEvent(ev); -} - -TEST_F(AppCoreBaseTest, AppCoreBase_ChargerStatusChangedCb) { - testing::NiceMock core; - - EXPECT_CALL(core, OnCreate()) - .WillOnce(Invoke([&]() -> int { - core.AppCoreBase::OnCreate(); - GetMock().ChangeInt(VCONFKEY_SYSMAN_CHARGER_STATUS, 0); - GetMock().ChangeInt(VCONFKEY_SYSMAN_CHARGER_STATUS, 1); - g_idle_add_full(G_PRIORITY_LOW, [](gpointer data) -> gboolean { - auto* obj = static_cast*>(data); - obj->Exit(); - return G_SOURCE_REMOVE; - }, &core, nullptr); - return 0; - })); - EXPECT_CALL(core, OnTerminate()) - .Times(1); - - DummyArgs da; - auto ev = std::shared_ptr( - new TestEvent(IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED)); - core.SetFeature(AppCoreBase::FEATURE_CHARGER_STATUS); - core.AddEvent(ev); - core.Run(da.GetArgc(), da.GetArgv()); - core.RemoveEvent(ev); -} - TEST_F(AppCoreBaseTest, AppCoreBase_AddEvent_LanguageChanged) { testing::NiceMock core; @@ -785,4 +680,4 @@ TEST_F(AppCoreBaseTest, AppCoreBase_RotationState) { EXPECT_EQ(AppCoreBase::GetDisplayState(), AppCoreBase::DISPLAY_STATE_UNKNOWN); } -} // namespace tizen_cpp +} // namespace tizen_cpp -- 2.7.4