diff options
| -rw-r--r-- | UnityCore/GnomeSessionManager.cpp | 75 | ||||
| -rw-r--r-- | UnityCore/GnomeSessionManagerImpl.h | 2 | ||||
| -rw-r--r-- | UnityCore/Variant.cpp | 30 | ||||
| -rw-r--r-- | UnityCore/Variant.h | 1 | ||||
| -rw-r--r-- | tests/test_gnome_session_manager.cpp | 9 |
5 files changed, 95 insertions, 22 deletions
diff --git a/UnityCore/GnomeSessionManager.cpp b/UnityCore/GnomeSessionManager.cpp index 5f87fed8f..9fb1eb98c 100644 --- a/UnityCore/GnomeSessionManager.cpp +++ b/UnityCore/GnomeSessionManager.cpp @@ -101,32 +101,37 @@ GnomeManager::Impl::Impl(GnomeManager* manager, bool test_mode) }); { - const char* session_id = test_mode_ ? "id0" : g_getenv("XDG_SESSION_ID"); + std::string session_id = test_mode_ ? "id0" : glib::gchar_to_string(g_getenv("XDG_SESSION_ID")); - login_proxy_ = std::make_shared<glib::DBusProxy>(test_mode_ ? testing::DBUS_NAME : "org.freedesktop.login1", - "/org/freedesktop/login1/session/" + glib::gchar_to_string(session_id), - "org.freedesktop.login1.Session", - test_mode_ ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES); + if (!session_id.empty()) + { + CallLogindMethod("GetSession", g_variant_new("(s)", session_id.c_str()), [this, session_id] (GVariant* variant, glib::Error const& err) { + std::string session_path; - login_proxy_->Connect("Lock", [this](GVariant*){ - manager_->PromptLockScreen(); - }); + if (!err && variant) + session_path = glib::Variant(variant).GetObjectPath(); - login_proxy_->Connect("Unlock", [this](GVariant*){ - manager_->unlock_requested.emit(); - }); + if (session_path.empty()) + session_path = "/org/freedesktop/login1/session/" + session_id; - login_proxy_->ConnectProperty("Active", [this] (GVariant* variant) { - bool active = glib::Variant(variant).GetBool(); - manager_->is_session_active.changed.emit(active); - if (active) - manager_->screensaver_requested.emit(false); - }); + SetupLogin1Proxy(session_path); + }); + } + else + { + auto proxy = std::make_shared<glib::DBusProxy>("org.freedesktop.login1", + "/org/freedesktop/login1/user/self", + "org.freedesktop.login1.User", + G_BUS_TYPE_SYSTEM); - manager_->is_session_active.SetGetterFunction([this] { - return login_proxy_->GetProperty("Active").GetBool(); - }); + proxy->GetProperty("Display", [this, proxy] (GVariant *variant) { + if (!variant || g_variant_n_children(variant) < 2) + return; + + glib::Variant tmp(g_variant_get_child_value(variant, 1), glib::StealRef()); + SetupLogin1Proxy(tmp.GetObjectPath()); + }); + } } { @@ -221,6 +226,34 @@ GnomeManager::Impl::~Impl() ClosedDialog(); } +void GnomeManager::Impl::SetupLogin1Proxy(std::string const& session_path) +{ + login_proxy_ = std::make_shared<glib::DBusProxy>(test_mode_ ? testing::DBUS_NAME : "org.freedesktop.login1", + session_path, + "org.freedesktop.login1.Session", + test_mode_ ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES); + + login_proxy_->Connect("Lock", [this](GVariant*){ + manager_->PromptLockScreen(); + }); + + login_proxy_->Connect("Unlock", [this](GVariant*){ + manager_->unlock_requested.emit(); + }); + + login_proxy_->ConnectProperty("Active", [this] (GVariant* variant) { + bool active = glib::Variant(variant).GetBool(); + manager_->is_session_active.changed.emit(active); + if (active) + manager_->screensaver_requested.emit(false); + }); + + manager_->is_session_active.SetGetterFunction([this] { + return login_proxy_->GetProperty("Active").GetBool(); + }); +} + bool GnomeManager::Impl::InteractiveMode() { bool schema_found = false; diff --git a/UnityCore/GnomeSessionManagerImpl.h b/UnityCore/GnomeSessionManagerImpl.h index 88b0dd5c0..f3904e7eb 100644 --- a/UnityCore/GnomeSessionManagerImpl.h +++ b/UnityCore/GnomeSessionManagerImpl.h @@ -46,6 +46,8 @@ struct GnomeManager::Impl Impl(GnomeManager* parent, bool test_mode = false); ~Impl(); + void SetupLogin1Proxy(std::string const& session_path); + void ConfirmLogout(); void ConfirmReboot(); void ConfirmShutdown(); diff --git a/UnityCore/Variant.cpp b/UnityCore/Variant.cpp index 9a74147a1..9de1d42e5 100644 --- a/UnityCore/Variant.cpp +++ b/UnityCore/Variant.cpp @@ -174,6 +174,36 @@ std::string Variant::GetString() const return result ? result : ""; } +std::string Variant::GetObjectPath() const +{ + const gchar *result = nullptr; + + if (!variant_) + return ""; + + if (g_variant_is_of_type(variant_, G_VARIANT_TYPE_OBJECT_PATH)) + { + // g_variant_get_string doesn't duplicate the string + result = g_variant_get_string(variant_, nullptr); + } + else if (g_variant_is_of_type(variant_, G_VARIANT_TYPE("(o)"))) + { + // As we're using the '&' prefix we don't need to free the string! + g_variant_get(variant_, "(&o)", &result); + } + else + { + auto const& variant = get_variant(variant_); + if (variant) + return variant.GetObjectPath(); + + LOG_ERROR(logger) << "You're trying to extract a 'o' from a variant which is of type '" + << g_variant_type_peek_string(g_variant_get_type(variant_)) << "'"; + } + + return result ? result : ""; +} + template <typename TYPE, typename GTYPE> TYPE get_numeric_value(GVariant *variant_, const char *type_str, const char *fallback_type_str) { diff --git a/UnityCore/Variant.h b/UnityCore/Variant.h index fca2b8e63..e313e8f18 100644 --- a/UnityCore/Variant.h +++ b/UnityCore/Variant.h @@ -68,6 +68,7 @@ public: ~Variant(); std::string GetString() const; + std::string GetObjectPath() const; unsigned char GetByte() const; int16_t GetInt16() const; uint16_t GetUInt16() const; diff --git a/tests/test_gnome_session_manager.cpp b/tests/test_gnome_session_manager.cpp index b78329884..b7e2c58a2 100644 --- a/tests/test_gnome_session_manager.cpp +++ b/tests/test_gnome_session_manager.cpp @@ -70,6 +70,9 @@ R"(<node> const std::string LOGIND_MANAGER = R"(<node> <interface name="org.freedesktop.login1.Manager"> + <method name="GetSession"> + <arg type="s" name="result" direction="out"/> + </method> <method name="CanSuspend"> <arg type="s" name="result" direction="out"/> </method> @@ -186,7 +189,11 @@ struct TestGnomeSessionManager : testing::Test logind_->AddObjects(introspection::LOGIND_MANAGER, LOGIND_MANAGER_PATH); logind_->AddObjects(introspection::LOGIND_SESSION, LOGIND_SESSION_PATH); logind_->GetObjects().front()->SetMethodsCallsHandler([&] (std::string const& method, GVariant*) -> GVariant* { - if (method == "CanSuspend") + if (method == "GetSession") + { + return g_variant_new("(o)", "id0"); + } + else if (method == "CanSuspend") { suspend_called = true; return g_variant_new("(s)", can_suspend_ ? "yes" : "no"); |
