[gnome-usage/benzea/simple-systemd-appid-lookup: 8/9] app-item: Add application lookup based on cgroup information




commit 792f465ffaf1b6bef2b19b3f462bae6acc285a48
Author: Benjamin Berg <bberg redhat com>
Date:   Wed Jul 22 17:03:59 2020 +0200

    app-item: Add application lookup based on cgroup information
    
    This allows looking up the application ID from the systemd unit name
    (i.e. cgroup).
    
    See: #76

 src/app-item.vala | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)
---
diff --git a/src/app-item.vala b/src/app-item.vala
index d7816d3..0f9f01b 100644
--- a/src/app-item.vala
+++ b/src/app-item.vala
@@ -49,8 +49,83 @@ namespace Usage
             }
         }
 
+        public static string? appid_from_unit (string ?systemd_unit) {
+            string ?escaped_id = null;
+            string ?id = null;
+
+            if (systemd_unit == null)
+                return null;
+
+            /* This is gnome-launched-APPID.desktop-RAND.scope */
+            if (systemd_unit.has_prefix ("gnome-launched-")) {
+                int index = -1;
+
+                index = systemd_unit.index_of (".desktop-");
+                // This is just argv[0] name encoded, we could also decode it
+                // and look it up differently.
+                // There is no standardization though for such a scheme.
+                if (index == -1)
+                    return null;
+
+                return systemd_unit[15:index];
+            }
+
+            /* In other cases, assume compliance with spec, i.e. for
+             * .scope units we fetch the second to last dashed item,
+             * for .service units the last (as they use @ to separate
+             * any required) */
+            try {
+                string[] segments = systemd_unit.split ("-");
+
+                if (systemd_unit.has_suffix (".scope") && segments.length >= 2)
+                    escaped_id = segments[segments.length - 2];
+                else if (systemd_unit.has_suffix (".service") && segments.length >= 1) {
+                    string tmp = segments[segments.length - 1];
+                    /* Strip .service */
+                    tmp = tmp[0:tmp.length-8];
+                    /* Remove any @ element (if there) */
+                    escaped_id = tmp.split("@", 2)[0];
+                }
+            } catch (Error e) {
+                return null;
+            }
+
+            if (escaped_id == null)
+                return null;
+
+            /* Now, unescape any \xXX escapes, which should only be dashes
+             * from the reverse domain name. */
+            id = escaped_id.compress();
+            if (id == null)
+                return null;
+
+            return id;
+        }
+
         public static AppInfo? app_info_for_process (Process p) {
             AppInfo? info = null;
+            string ?cgroup = null;
+            Pid pid = p.pid;
+
+            cgroup = Process.read_cgroup(p.pid);
+            if (cgroup != null) {
+                /* Try to extract an application ID, this is a bit "magic".
+                 * See https://systemd.io/DESKTOP_ENVIRONMENTS/
+                 * and we also have some special cases for GNOME which is not
+                 * currently compliant to the specification. */
+                string ?systemd_unit = null;
+                string ?appid = null;
+                string[] components;
+
+                components = cgroup.split("/");
+                systemd_unit = components[components.length - 1];
+                appid = appid_from_unit (systemd_unit);
+                if (appid != null)
+                    info = appid_map[appid];
+
+                if (info != null)
+                    return info;
+            }
 
             if (p.cmdline != null)
                 info = apps_info[p.cmdline];


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]