aboutsummaryrefslogtreecommitdiff
path: root/tests/backend-dbus/mock-login1-seat.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/backend-dbus/mock-login1-seat.cc')
-rw-r--r--tests/backend-dbus/mock-login1-seat.cc244
1 files changed, 244 insertions, 0 deletions
diff --git a/tests/backend-dbus/mock-login1-seat.cc b/tests/backend-dbus/mock-login1-seat.cc
new file mode 100644
index 0000000..49d7fb6
--- /dev/null
+++ b/tests/backend-dbus/mock-login1-seat.cc
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Authors:
+ * Charles Kerr <charles.kerr@canonical.com>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mock-login1-seat.h"
+
+#include "mock-object.h"
+#include "mock-user.h"
+
+namespace
+{
+ const char * BUS_NAME = "org.freedesktop.login1";
+
+ std::string next_unique_sid ()
+ {
+ static int id = 1;
+
+ char * tmp;
+ std::string ret;
+
+ tmp = g_strdup_printf ("/org/freedesktop/login1/seat/seat%d", id++);
+ ret = tmp;
+ g_free (tmp);
+ return ret;
+ }
+
+ static int next_session_tag = 1;
+}
+
+void
+MockLogin1Seat :: get_session_id_and_path_for_tag (int tag,
+ std::string & id,
+ std::string & path)
+{
+ if (tag)
+ {
+ char tmp[80];
+
+ g_snprintf (tmp, sizeof(tmp), "c%d", tag);
+ id = tmp;
+
+ g_snprintf (tmp, sizeof(tmp), "/org/freedesktop/login1/session/%s", id.c_str());
+ path = tmp;
+ }
+ else
+ {
+ id = "";
+ path = "";
+ }
+}
+
+
+/***
+****
+***/
+
+void
+MockLogin1Seat :: update_sessions_property ()
+{
+ GVariantBuilder b;
+
+ g_variant_builder_init (&b, G_VARIANT_TYPE("a(so)"));
+ for (const auto& it : my_sessions)
+ {
+ std::string id, path;
+ get_session_id_and_path_for_tag (it.first, id, path);
+ g_variant_builder_add (&b, "(so)", id.c_str(), path.c_str());
+ }
+
+ GVariant * v = g_variant_builder_end (&b);
+ g_object_set (my_skeleton, "sessions", v, NULL);
+}
+
+void
+MockLogin1Seat :: update_active_session_property ()
+{
+ std::string id;
+ std::string path;
+ get_session_id_and_path_for_tag (my_active_session, id, path);
+
+ GVariant * v = g_variant_new ("(so)", id.c_str(), path.c_str());
+ g_object_set (my_skeleton, "active-session", v, NULL);
+}
+
+void
+MockLogin1Seat :: update_can_multi_session_property ()
+{
+ g_object_set (my_skeleton, "can-multi-session", my_can_multi_session, NULL);
+}
+
+/***
+****
+***/
+
+/* lists this seat's sessions in the format of Login1Manager::ListSessions() */
+GVariant *
+MockLogin1Seat :: list_sessions ()
+{
+ GVariantBuilder b;
+ g_variant_builder_init (&b, G_VARIANT_TYPE("a(susso)"));
+ for (auto it : my_sessions)
+ {
+ std::string id, path;
+ get_session_id_and_path_for_tag (it.first, id, path);
+ g_variant_builder_add (&b, "(susso)",
+ id.c_str(),
+ uint32_t(it.second->uid()),
+ it.second->username(),
+ seat_id(),
+ path.c_str());
+ }
+
+ return g_variant_builder_end (&b);
+}
+
+/***
+****
+***/
+
+std::set<int>
+MockLogin1Seat :: sessions () const
+{
+ std::set<int> ret;
+
+ for (auto it : my_sessions)
+ ret.insert (it.first);
+
+ return ret;
+}
+
+int
+MockLogin1Seat :: add_session (MockUser * user)
+{
+ const int tag = next_session_tag++;
+
+ my_sessions[tag] = user;
+ update_sessions_property ();
+
+ return tag;
+}
+
+void
+MockLogin1Seat :: remove_session (int session_tag)
+{
+ my_sessions.erase (session_tag);
+ update_sessions_property ();
+}
+
+/***
+****
+***/
+
+std::string
+MockLogin1Seat :: user_state (unsigned int uid) const
+{
+ for (auto it : my_sessions)
+ if (it.second->uid() == uid)
+ return it.first == my_active_session ? "active" : "online";
+
+ return "offline"; // no matching session
+}
+
+void
+MockLogin1Seat :: activate_session (int session_tag)
+{
+ g_assert (my_sessions.count(session_tag) == 1);
+
+ if (my_active_session != session_tag)
+ {
+ std::string id, path;
+ my_active_session = session_tag;
+ get_session_id_and_path_for_tag (session_tag, id, path);
+ g_setenv ("XDG_SESSION_ID", id.c_str(), true);
+ update_active_session_property ();
+
+ }
+}
+
+void
+MockLogin1Seat :: switch_to_guest ()
+{
+ for (const auto& it : my_sessions)
+ {
+ if (it.second->is_guest())
+ {
+ activate_session (it.first);
+ return;
+ }
+ }
+
+ g_warn_if_reached ();
+}
+
+void
+MockLogin1Seat :: switch_to_user (const char * username)
+{
+ for (const auto& it : my_sessions)
+ {
+ if (!g_strcmp0 (username, it.second->username()))
+ {
+ activate_session (it.first);
+ return;
+ }
+ }
+
+ g_warn_if_reached ();
+}
+
+/***
+**** Life Cycle
+***/
+
+MockLogin1Seat :: MockLogin1Seat (GMainLoop * loop,
+ GDBusConnection * bus_connection,
+ bool can_activate_sessions):
+ MockObject (loop, bus_connection, BUS_NAME, next_unique_sid()),
+ my_skeleton (login1_seat_skeleton_new ()),
+ my_active_session (0),
+ my_can_multi_session (can_activate_sessions)
+
+{
+ set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton));
+ update_can_multi_session_property ();
+}
+
+MockLogin1Seat :: ~MockLogin1Seat ()
+{
+ g_clear_object (&my_skeleton);
+}