[gnome-usage] system-monitor: Add support for grouping system processes to backend



commit dca0b9741014074d9e84312367287000e170efac
Author: Petr Štětka <pstetka redhat com>
Date:   Thu May 31 13:56:12 2018 +0200

    system-monitor: Add support for grouping system processes to backend

 src/app-item.vala       | 99 ++++++++++++++++++++++++++-----------------------
 src/process.vala        |  4 +-
 src/system-monitor.vala | 73 +++++++++++++++++++++++++++++-------
 3 files changed, 113 insertions(+), 63 deletions(-)
---
diff --git a/src/app-item.vala b/src/app-item.vala
index 12a8662..244218f 100644
--- a/src/app-item.vala
+++ b/src/app-item.vala
@@ -10,20 +10,42 @@ namespace Usage
         public uint64 mem_usage { get; private set; }
         public Fdo.AccountsUser? user { get; private set; default = null; }
 
-        private static GLib.List<AppInfo>? apps_info;
-        private AppInfo app_info = null;
+        private static HashTable<string, AppInfo>? apps_info;
+        private AppInfo? app_info = null;
+
+        public static void init() {
+            apps_info = new HashTable<string, AppInfo>(str_hash, str_equal);
+            var _apps_info = AppInfo.get_all();
+
+            foreach (AppInfo info in _apps_info) {
+                string cmd = info.get_commandline();
+                sanity_cmd(ref cmd);
+
+                if(cmd != null)
+                    apps_info.insert(cmd, info);
+            }
+        }
+
+        public static bool have_app_info(string cmdline) {
+            return apps_info.get(cmdline) != null ? true : false;
+        }
 
         public AppItem(Process process) {
-            display_name = find_display_name(process.cmdline, process.cmdline_parameter);
+            app_info = apps_info.get(process.cmdline);
             representative_cmdline = process.cmdline;
             representative_uid = process.uid;
-            processes = new HashTable<Pid?, Process>(int_hash, int_equal);
+            display_name = find_display_name();
             processes.insert(process.pid, process);
+            load_user_account.begin();
+        }
 
-            if(apps_info == null)
-                apps_info = AppInfo.get_all();
+        public AppItem.system() {
+            display_name = _("System");
+            representative_cmdline = "system";
+        }
 
-            load_user_account.begin();
+        construct {
+            processes = new HashTable<Pid?, Process>(int_hash, int_equal);
         }
 
         public bool contains_process(Pid pid) {
@@ -80,48 +102,11 @@ namespace Usage
             processes.replace(process.pid, process);
         }
 
-        private string find_display_name(string cmdline, string cmdline_parameter) {
-            foreach (AppInfo info in apps_info)
-            {
-                string commandline = info.get_commandline();
-                if(commandline != null)
-                {
-                    for (int i = 0; i < commandline.length; i++)
-                    {
-                        if(commandline[i] == ' ' && commandline[i] == '%')
-                            commandline = commandline.substring(0, i);
-                    }
-
-                    commandline = Path.get_basename(commandline);
-                    string process_full_cmd = cmdline + " " + cmdline_parameter;
-                    if(commandline == process_full_cmd)
-                        app_info = info;
-                    else if(commandline.contains("google-" + cmdline + "-")) //Fix for Google Chrome naming
-                        app_info = info;
-
-                    if(app_info == null)
-                    {
-                        commandline = info.get_commandline();
-                        for (int i = 0; i < commandline.length; i++)
-                        {
-                            if(commandline[i] == ' ')
-                                commandline = commandline.substring(0, i);
-                        }
-
-                        if(info.get_commandline().has_prefix(commandline + " " + commandline + "://")) //Fix 
for Steam naming
-                            commandline = info.get_commandline();
-
-                        commandline = Path.get_basename(commandline);
-                        if(commandline == cmdline)
-                            app_info = info;
-                    }
-                }
-            }
-
+        private string find_display_name() {
             if(app_info != null)
                 return app_info.get_display_name();
             else
-                return cmdline;
+                return representative_cmdline;
         }
 
         private async void load_user_account() {
@@ -137,5 +122,27 @@ namespace Usage
                 warning ("Unable to obtain user account: %s", e.message);
             }
         }
+
+        private static void sanity_cmd(ref string? commandline) {
+            if(commandline != null) {
+                //flatpak
+                if(commandline.contains("flatpak run")) {
+                    var index = commandline.index_of("--command=") + 10;
+                    commandline = commandline.substring(index);
+                }
+
+                try {
+                    var rgx = new Regex("[^a-zA-Z0-9._-]");
+
+                    commandline = Path.get_basename(commandline.split(" ")[0]);
+                    commandline = rgx.replace(commandline, commandline.length, 0, "");
+                } catch (RegexError e) {
+                    warning ("Unable to obtain process command: %s", e.message);
+                }
+
+                if(commandline.contains("google-chrome-stable")) //Workaround for google-chrome
+                    commandline = "chrome";
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/src/process.vala b/src/process.vala
index a31bc2c..0f89c8f 100644
--- a/src/process.vala
+++ b/src/process.vala
@@ -24,7 +24,6 @@ namespace Usage
     {
         public Pid pid { get; private set; }
         public string cmdline { get; private set; }
-        public string cmdline_parameter { get; private set; } //Isn't parameters as "-p" etc, but parameter 
for running app, for ex. "--writer' with libreoffice, or "privacy" with gnome-control-center
         public uint uid { get; private set; }
 
         public double cpu_load { get; set; default = 0; }
@@ -38,11 +37,10 @@ namespace Usage
         public bool mark_as_updated { get; set; default = true; }
         public ProcessStatus status { get; private set; default = ProcessStatus.SLEEPING; }
 
-        public Process(Pid pid, string cmdline, string cmdline_parameter)
+        public Process(Pid pid, string cmdline)
         {
             this.pid = pid;
             this.cmdline = cmdline;
-            this.cmdline_parameter = cmdline_parameter;
             this.uid = _get_uid();
         }
 
diff --git a/src/system-monitor.vala b/src/system-monitor.vala
index 871e6bf..30f9d37 100644
--- a/src/system-monitor.vala
+++ b/src/system-monitor.vala
@@ -22,13 +22,14 @@ namespace Usage
 {
     public class SystemMonitor : Object
     {
-        public signal void cpu_processes_ready();
+        public bool process_list_ready { get; private set; default = false; }
         public double cpu_load { get; private set; }
         public double[] x_cpu_load { get; private set; }
         public uint64 ram_usage { get; private set; }
         public uint64 ram_total { get; private set; }
         public uint64 swap_usage { get; private set; }
         public uint64 swap_total { get; private set; }
+        public bool group_system_apps { get; set; default = true; }
 
         private CpuMonitor cpu_monitor;
         private MemoryMonitor memory_monitor;
@@ -58,6 +59,7 @@ namespace Usage
         public SystemMonitor()
         {
             GTop.init();
+            AppItem.init();
 
             cpu_monitor = new CpuMonitor();
             memory_monitor = new MemoryMonitor();
@@ -65,11 +67,29 @@ namespace Usage
             app_table = new HashTable<string, AppItem>(str_hash, str_equal);
             var settings = Settings.get_default();
 
-            update_data();
+            init();
+            this.notify["group-system-apps"].connect ((sender, property) => {
+                init();
+            });
+
             Timeout.add(settings.data_update_interval, update_data);
+        }
+
+        private void init()
+        {
+            var settings = Settings.get_default();
+            app_table.remove_all();
+            process_list_ready = false;
+
+            if(group_system_apps) {
+                var system = new AppItem.system();
+                app_table.insert("system" , system);
+            }
+
+            update_data();
             Timeout.add(settings.data_update_interval, () =>
             {
-                cpu_processes_ready();
+                process_list_ready = true;
                 return false;
             });
         }
@@ -94,23 +114,26 @@ namespace Usage
 
             for(uint i = 0; i < proclist.number; i++)
             {
-                string cmdline_parameter;
-                string cmdline = get_full_process_cmd(pids[i], out cmdline_parameter);
+                string cmd = get_full_process_cmd(pids[i]);
+                string app_id = cmd;
+
+                if(group_system_apps && is_system_app(cmd))
+                    app_id = "system";
 
-                if (!(cmdline in app_table))
+                if (!(app_id in app_table))
                 {
-                    var process = new Process(pids[i], cmdline, cmdline_parameter);
+                    var process = new Process(pids[i], cmd);
                     update_process(ref process);
                     var app = new AppItem(process);
-                    app_table.insert (cmdline, (owned) app);
+                    app_table.insert (app_id, (owned) app);
                 }
                 else
                 {
-                    AppItem app = app_table[cmdline];
+                    AppItem app = app_table[app_id];
 
                     if (!app.contains_process(pids[i]))
                     {
-                        var process = new Process(pids[i], cmdline, cmdline_parameter);
+                        var process = new Process(pids[i], cmd);
                         update_process(ref process);
                         app.insert_process(process);
                     }
@@ -136,14 +159,31 @@ namespace Usage
             process.update_status();
         }
 
-        private string get_full_process_cmd (Pid pid, out string cmd_parameter)
+        private string? sanity_cmd(string commandline)
+        {
+            string? cmd = null;
+
+            if(commandline != null)
+            {
+                try {
+                    var rgx = new Regex("[^a-zA-Z0-9._-]");
+                    cmd = Path.get_basename(commandline.split(" ")[0]);
+                    cmd = rgx.replace(commandline, commandline.length, 0, "");
+                } catch (RegexError e) {
+                    warning ("Unable to obtain process command: %s", e.message);
+                }
+            }
+            return cmd;
+        }
+
+        private string get_full_process_cmd (Pid pid)
         {
             GTop.ProcArgs proc_args;
             GTop.ProcState proc_state;
             string[] args = GTop.get_proc_argv (out proc_args, pid, 0);
             GTop.get_proc_state (out proc_state, pid);
             string cmd = (string) proc_state.cmd;
-            cmd_parameter = "";
+            string cmd_parameter = "";
 
             var secure_arguments = new string[2];
 
@@ -178,11 +218,16 @@ namespace Usage
                     else
                         cmd_parameter = secure_arguments[0];
 
-                    return name;
+                    return sanity_cmd(name);
                 }
             }
 
-            return cmd;
+            return sanity_cmd(cmd);
+        }
+
+        private bool is_system_app(string cmdline)
+        {
+            return !AppItem.have_app_info(cmdline);
         }
     }
 }


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