Add some sample methods 30/272730/9
authorMateusz Majewski <m.majewski2@samsung.com>
Wed, 23 Mar 2022 07:34:20 +0000 (08:34 +0100)
committerMateusz Majewski <m.majewski2@samsung.com>
Tue, 29 Mar 2022 16:16:05 +0000 (18:16 +0200)
Change-Id: I86f5872692d058a8299417e1369718b266314374

sessiond/src/main.cpp

index 9fd1aa02758839f15ec13b80302cd360da86d1c1..47192f18d99d1b5f2a314a1a8e8ac93fc3372c83 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE. */
 
+#include <algorithm>
 #include <iostream>
 #include <memory>
 
 #include <gio/gio.h>
 
 struct introspection_data {
-       introspection_data(const std::string_view &xml)
+       introspection_data(std::string_view xml)
        {
                inner = g_dbus_node_info_new_for_xml(xml.data(), nullptr);
-               if (inner == nullptr) {
-                       throw std::system_error(std::error_code(), "Couldn't parse introspection data"); // TODO
-               }
+               if (inner == nullptr)
+                       throw std::system_error(std::error_code(), "Couldn't parse introspection data");
        }
 
        ~introspection_data()
@@ -48,7 +48,7 @@ struct introspection_data {
 };
 
 struct owner_id {
-       owner_id(const std::string_view &name, GBusAcquiredCallback on_connect, GBusNameLostCallback on_error,
+       owner_id(std::string_view name, GBusAcquiredCallback on_connect, GBusNameLostCallback on_error,
                 gpointer user_data)
        {
                inner = g_bus_own_name(G_BUS_TYPE_SYSTEM, name.data(), G_BUS_NAME_OWNER_FLAGS_NONE, on_connect,
@@ -100,25 +100,65 @@ struct sessiond_context {
        {
                guint registration_id = g_dbus_connection_register_object(
                    connection, bus_object.data(), data.inner->interfaces[0], &table, nullptr, nullptr, nullptr);
-               if (registration_id <= 0) {
-                       throw std::system_error(std::error_code(), "Couldn't register ID"); // TODO
-               }
+               if (registration_id <= 0)
+                       throw std::system_error(std::error_code(), "Couldn't register ID");
        }
 
        void on_name_lost(GDBusConnection *connection)
        {
-               throw std::system_error(std::error_code(), "Name lost"); // TODO
+               throw std::system_error(std::error_code(), "Name lost");
+       }
+
+       void on_add_user(GDBusMethodInvocation *invocation, GVariant *parameters)
+       {
+               if (!g_variant_is_of_type(parameters, g_variant_type_new("(ii)")))
+                       throw std::system_error(std::error_code(), "Invalid parameters type");
+
+               int session_uid;
+               int subsession_id;
+               g_variant_get(parameters, "(ii)", &session_uid, &subsession_id);
+
+               if (session_uid <= 0) {
+                       g_dbus_method_invocation_return_dbus_error(invocation, "org.freedesktop.DBus.Error.InvalidArgs", "Negative UID passed");
+                       return;
+               }
+
+               g_dbus_method_invocation_return_value(invocation, nullptr);
+       }
+
+       void on_remove_user(GDBusMethodInvocation *invocation, GVariant *parameters)
+       {
+               if (!g_variant_is_of_type(parameters, g_variant_type_new("(ii)")))
+                       throw std::system_error(std::error_code(), "Invalid parameters type");
+
+               int session_uid;
+               int subsession_id;
+               g_variant_get(parameters, "(ii)", &session_uid, &subsession_id);
+
+               if (session_uid <= 0) {
+                       g_dbus_method_invocation_return_dbus_error(invocation, "org.freedesktop.DBus.Error.InvalidArgs", "Negative UID passed");
+                       return;
+               }
+
+               g_dbus_method_invocation_return_value(invocation, nullptr);
        }
 
-       void on_method_call(const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation)
+       void on_switch_user(GDBusMethodInvocation *invocation, GVariant *parameters)
        {
-               std::string_view name = method_name;
+               if (!g_variant_is_of_type(parameters, g_variant_type_new("(iii)")))
+                       throw std::system_error(std::error_code(), "Invalid parameters type");
+
+               int session_uid;
+               int prev_subsession_id;
+               int next_subsession_id;
+               g_variant_get(parameters, "(iii)", &session_uid, &prev_subsession_id, &next_subsession_id);
 
-               if (name == "Run") {
-                       g_dbus_method_invocation_return_value(invocation, nullptr);
-               } else {
-                       throw std::system_error(std::error_code(), "Unknown method"); // TODO
+               if (session_uid <= 0) {
+                       g_dbus_method_invocation_return_dbus_error(invocation, "org.freedesktop.DBus.Error.InvalidArgs", "Negative UID passed");
+                       return;
                }
+
+               g_dbus_method_invocation_return_value(invocation, nullptr);
        }
 
        static void glib_bus_connected(GDBusConnection *connection, const gchar *name, gpointer user_data)
@@ -135,8 +175,21 @@ struct sessiond_context {
                                     const gchar *interface_name, const gchar *method_name, GVariant *parameters,
                                     GDBusMethodInvocation *invocation, gpointer user_data)
        {
-               auto self = static_cast<sessiond_context *>(user_data);
-               self->on_method_call(method_name, parameters, invocation);
+               // TODO: Also dispatch on interface_name (not needed at the moment)
+               try {
+                       auto self = static_cast<sessiond_context *>(user_data);
+                       auto to_call = std::find_if(methods.begin(), methods.end(), [&](auto pair) {
+                               return pair.first == method_name;
+                       });
+                       if (to_call == methods.end())
+                               throw std::system_error(std::error_code(), std::string("Unknown method ") + method_name + " called");
+                       std::cout << "Handling " << method_name << " call from " << sender << std::endl;
+                       (self->*(to_call->second))(invocation, parameters);
+               } catch (const std::exception &ex) {
+                       std::cerr << "Exception " << ex.what() << "\n" <<
+                               "while handling " << method_name << " call from " << sender << "\n";
+                       // Swallow the exception; the show must go on
+               }
        }
 
        constexpr static GDBusInterfaceVTable table = {
@@ -145,13 +198,35 @@ struct sessiond_context {
 
        constexpr static std::string_view xml =
                "<node name=\"/org/tizen/sessiond\">"
-                       "<interface name=\"org.tizen.sessiond.HelloWorld\">"
-                               "<method name=\"Run\"> </method>"
+                       "<interface name=\"org.tizen.sessiond.subsession.Manager\">"
+                               "<method name=\"AddUser\">"
+                                       "<arg name=\"session_uid\"        type=\"i\" direction=\"in\"/>"
+                                       "<arg name=\"subsession_id\"      type=\"i\" direction=\"in\"/>"
+                               "</method>"
+                               "<method name=\"RemoveUser\">"
+                                       "<arg name=\"session_uid\"        type=\"i\" direction=\"in\"/>"
+                                       "<arg name=\"subsession_id\"      type=\"i\" direction=\"in\"/>"
+                               "</method>"
+                               "<method name=\"SwitchUser\">"
+                                       "<arg name=\"session_uid\"        type=\"i\" direction=\"in\"/>"
+                                       "<arg name=\"prev_subsession_id\" type=\"i\" direction=\"in\"/>"
+                                       "<arg name=\"next_subsession_id\" type=\"i\" direction=\"in\"/>"
+                               "</method>"
                        "</interface>"
                "</node>";
        constexpr static std::string_view bus_name = "org.tizen.sessiond";
        constexpr static std::string_view bus_object = "/org/tizen/sessiond";
 
+       constexpr static std::array<
+                       std::pair<
+                               std::string_view,
+                               void (sessiond_context::*)(GDBusMethodInvocation *, GVariant *)
+                       >, 3> methods = {
+               std::make_pair("AddUser",    &sessiond_context::on_add_user),
+               std::make_pair("RemoveUser", &sessiond_context::on_remove_user),
+               std::make_pair("SwitchUser", &sessiond_context::on_switch_user),
+       };
+
        introspection_data data;
        owner_id id;
        main_loop loop;