summaryrefslogtreecommitdiff
diff options
authorAndrea Azzarone <azzaronea@gmail.com>2016-11-02 16:38:47 +0000
committerAndrea Azzarone <azzaronea@gmail.com>2016-11-02 16:38:47 +0000
commit35cee0064f194ea29f349b41ac47d1868a4c224b (patch)
tree9ea3081be9b080e25b659442c77b6d6d30aa898e
parenta9418611d57dc618390f9d85632d3ac1803bf78c (diff)
Retrieve the session id using dbus if env variable XDG_SESSION_ID is not available.
(bzr r4194.4.1)
-rw-r--r--UnityCore/GnomeSessionManager.cpp75
-rw-r--r--UnityCore/GnomeSessionManagerImpl.h2
-rw-r--r--UnityCore/Variant.cpp30
-rw-r--r--UnityCore/Variant.h1
-rw-r--r--tests/test_gnome_session_manager.cpp9
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");