Plugin can now also push events 02/321602/4
authorMichal Bloch <m.bloch@samsung.com>
Tue, 25 Mar 2025 19:55:29 +0000 (20:55 +0100)
committerMichal Bloch <m.bloch@samsung.com>
Mon, 31 Mar 2025 13:54:27 +0000 (15:54 +0200)
Change-Id: I920283dd08647ac8abce95de25315484f1e7ba43

src/service/CMakeLists.txt
src/service/src/plugin_push.cpp [new file with mode: 0644]

index 62eaf8bc6c329a0d98feecc543fc0db66f9faa38..8eb9cff28c4bead442a35878b83b0dfa26de0de3 100644 (file)
@@ -12,6 +12,7 @@ set(
        src/fs_helpers.cpp
        src/os_ops.cpp
        src/plugin.cpp
+       src/plugin_push.cpp
        src/dir_backend_regular_dir.cpp
        src/dir_backend_fixed_size.cpp
        src/tuple_g_variant_helpers.hpp
diff --git a/src/service/src/plugin_push.cpp b/src/service/src/plugin_push.cpp
new file mode 100644 (file)
index 0000000..f981deb
--- /dev/null
@@ -0,0 +1,132 @@
+/* MIT License
+ *
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE. */
+
+#include "fs_helpers.hpp"
+#include "main_context.hpp"
+#include "plugin.hpp"
+
+#undef LOG_TAG
+#define LOG_TAG "SESSIOND"
+#include <dlog.h>
+
+#include <system/syscommon-internal-sessiond.h>
+
+#ifndef EXPORT
+       #define EXPORT __attribute__((visibility("default")))
+#endif
+
+extern "C"
+{
+       /* In addition to listening, plugin can also push events. The interface is
+        * a bit poorly designed due to time constraints and should probably have
+        * "proper" errors from exceptions etc at some point.
+        *
+        * Some caveats:
+        *
+        *  - the plugin receives OnSubsessionX from its own events.
+        *
+        *  - if you call sessiond_internal_x_subsession from within
+        *    OnSubsessionX, there will be an inversion in how D-Bus
+        *    notifications to other processes are ordered
+        *
+        *  - sessiond assumes single-threading and doing anything in
+        *    a separate thread is a race condition. */
+
+       EXPORT int sessiond_internal_add_subsession(int uid, const char *subsession)
+       {
+               LOGD("Called sessiond_internal_add_subsession(%d, %s)", uid, subsession);
+               if (!check_uid_valid(uid) || !check_subsession_id_valid(subsession)) {
+                       LOGE("Invalid arguments to sessiond_internal_add_subsession(%d, %s)", uid, subsession);
+                       return -EINVAL;
+               }
+
+               try {
+                       g_sessiond_context->do_add_user(uid, subsession, DirBackendAddRegularDir {});
+               } catch (const std::exception &ex) {
+                       LOGE("Error in sessiond_internal_add_subsession(%d, %s): %s", uid, subsession, ex.what());
+                       return -EIO;
+               }
+               return 0;
+       }
+
+       EXPORT int sessiond_internal_add_subsession_fixed_size(int uid, const char *subsession, unsigned size_kB)
+       {
+               LOGD("Called sessiond_internal_add_subsession_fixed_size(%d, %s, %u kB)", uid, subsession, size_kB);
+               if (!check_uid_valid(uid) || !check_subsession_id_valid(subsession) || !check_subsession_size_limit_valid(size_kB)) {
+                       LOGE("Invalid arguments to sessiond_internal_add_subsession_fixed_size(%d, %s, %u kB)", uid, subsession, size_kB);
+                       return -EINVAL;
+               }
+
+               try {
+                       g_sessiond_context->do_add_user(uid, subsession, DirBackendAddFixedSize {size_kB});
+               } catch (const std::exception &ex) {
+                       LOGE("Error in sessiond_internal_add_subsession_fixed_size(%d, %s, %u kB): %s", uid, subsession, size_kB, ex.what());
+                       return -EIO;
+               }
+               return 0;
+       }
+
+       EXPORT int sessiond_internal_remove_subsession(int uid, const char *subsession)
+       {
+               LOGD("Called sessiond_internal_remove_subsession(%d, %s)", uid, subsession);
+               if (!check_uid_valid(uid) || !check_subsession_id_valid(subsession)) {
+                       LOGE("Invalid arguments: sessiond_internal_add_subsession(%d, %s)", uid, subsession);
+                       return -EINVAL;
+               }
+               if (g_sessiond_context->is_subsession_currently_active(uid, subsession)) {
+                       LOGW("Cannot remove uid %d's currently active subsession %s", uid, subsession);
+                       return -EBUSY;
+               }
+
+               try {
+                       g_sessiond_context->do_remove_user(uid, subsession);
+               } catch (const std::exception &ex) {
+                       LOGE("Error in sessiond_internal_remove_subsession(%d, %s): %s", uid, subsession, ex.what());
+                       return -EIO;
+               }
+               return 0;
+       }
+
+       EXPORT int sessiond_internal_switch_subsession(int uid, const char *subsession)
+       {
+               LOGD("Called sessiond_internal_switch_subsession(%d, %s)", uid, subsession);
+
+               const bool isEmptySubsession = !strcmp(subsession, "");
+               if (!check_uid_valid(uid) || !(isEmptySubsession || check_subsession_id_valid(subsession))) {
+                       LOGE("Invalid arguments: sessiond_internal_switch_subsession(%d, %s)", uid, subsession);
+                       return -EINVAL;
+               }
+
+               if (!isEmptySubsession && !subsession_exists(uid, subsession)) {
+                       LOGW("Cannot switch to nonexistent subsession %s (uid %d)", uid, subsession);
+                       return -EEXIST;
+               }
+
+               try {
+                       g_sessiond_context->do_switch_user(uid, subsession);
+               } catch (const std::exception &ex) {
+                       LOGE("Error in sessiond_internal_switch_subsession(%d, %s): %s", uid, subsession, ex.what());
+                       return -EIO;
+               }
+               return 0;
+       }
+};