proc-monitor: Check window validity using focus information 62/296562/5
authorUnsung Lee <unsung.lee@samsung.com>
Mon, 31 Jul 2023 08:11:20 +0000 (17:11 +0900)
committerUnsung Lee <unsung.lee@samsung.com>
Wed, 2 Aug 2023 04:45:49 +0000 (13:45 +0900)
Check whether focus information of app life cycle
and focus information of window stack is same to judge window stack validity.

Window information in window stack includes focus information
and appfw also notifies resourced when focus information of app is updated.
In this case, both information should be synchronized.

Change-Id: I7a9a0e5eb772ac93ec45d07bb393d8d42e832f41
Signed-off-by: Unsung Lee <unsung.lee@samsung.com>
src/process/proc-monitor.c

index 85275b5..40bd847 100644 (file)
@@ -77,66 +77,10 @@ static struct app_watchdog_info {
 
 #define INIT_PROCESS_PID 1
 
-static bool is_valid_window(const char *window_name, const char *app_state,
-               const struct proc_app_window_info *window)
+static bool is_valid_pid(pid_t pid)
 {
-       if (!window_name) {
-               _E("Window name cannot be NULL");
-               return false;
-       }
-
-       if (window->pid < INIT_PROCESS_PID) {
-               _E("window = %s, pid = %d", window_name, window->pid);
-               return false;
-       }
-
-       /* Focused app should be visible */
-       if (window->is_focused) {
-               if (window->visibility != 0 && window->visibility != 1) {
-                       _I("Focused app should be visible."
-                                       "window = %s, is_focused = %d, visibility = %d",
-                                       window_name, window->is_focused,
-                                       window->visibility);
-                       return false;
-               }
-       }
-
-       if (app_state == NULL)
-               return true;
-
-       if (!strncmp(app_state, "fg", 3)) {
-               /**
-                * Foreground app should be visible,
-                * but sometimes it does not guaranteed because of timing issue
-                */
-               if (window->visibility != 0 && window->visibility != 1) {
-                       _I("Fg app (window = %s) must be visible.",
-                                       window_name);
-                       return false;
-               }
-       } else if (!strncmp(app_state, "bg", 3)) {
-               /**
-                * Background app should not be focused,
-                * but sometimes it does not guaranteed because of timing issue
-                */
-               if (window->is_focused) {
-                       _I("Bg app (window = %s) must not be focused.",
-                                       window_name);
-                       return false;
-               }
-
-               /**
-                * Background app should not be visible,
-                * but sometimes it does not guaranteed because of timing issue
-                */
-               if (window->visibility == 0 || window->visibility == 1) {
-                       _I("Bg app (window = %s) must not be visible.",
-                                       window_name);
-                       return false;
-               }
-       } else {
-               _I("Unknown app state = %s, window = %s",
-                               app_state, window_name);
+       if (pid < INIT_PROCESS_PID) {
+               _E("(pid = %d) is wrong", pid);
                return false;
        }
 
@@ -230,21 +174,17 @@ static void free_window_stack(GVariantIter *iter, GVariant *reply,
                g_hash_table_remove_all(window_table);
 }
 
-static int dbus_update_window_stack(pid_t pid, const char *app_state)
+static int dbus_update_window_stack(pid_t pid, bool has_focus)
 {
        static GHashTable *window_table = NULL;
        struct proc_app_window_info window;
        GVariantIter *iter = NULL;
        GVariant *reply = NULL;
+       bool is_valid_window_stack = false;
        gchar *name;
        int z = 0;
        int ret;
 
-       if (!app_state) {
-               _E("It is impossible to parse pid or app status");
-               return RESOURCED_ERROR_INVALID_PARAMETER;
-       }
-
        ret = d_bus_call_method_sync_gvariant_with_reply(WINDOW_SYSTEM_BUS_NAME,
                        WINDOW_SYSTEM_OBJECT_PATH, WINDOW_SYSTEM_INTERFACE_NAME,
                        GET_VISIBLE_WINDOW_INFO_V2, NULL, &reply);
@@ -264,25 +204,49 @@ static int dbus_update_window_stack(pid_t pid, const char *app_state)
                g_assert(window_table);
        }
 
+       /**
+        * If window is valid, then update window stack
+        * without checking has_focus information
+        */
+       if (pid == 0)
+               is_valid_window_stack = true;
+
        while (g_variant_iter_loop(iter, "("VISIBLE_WINDOW_INFO_V2_VALUE_TYPE")",
                                &window.pid, &window.x, &window.y, &window.w, &window.h,
                                &window.is_transformed, &window.alpha, &window.opaque,
                                &window.visibility, &window.is_focused,
                                &window.is_mapped, &window.layer, &name)) {
-               bool is_same_pid;
-
                ++z;
                window.z = z;
 
-               is_same_pid = (pid == window.pid);
-               if (!is_valid_window(name, is_same_pid ? app_state : NULL, &window))
-                       goto error_to_parse_window_stack;
+               if (!name) {
+                       is_valid_window_stack = false;
+                       break;
+               }
+
+               if (!is_valid_pid(window.pid)) {
+                       is_valid_window_stack = false;
+                       break;
+               }
+
+               /**
+                * A process (same pid) can have more than one window,
+                * so Although current window's focus information is different
+                * from has_focus, it does not mean window stack is not valid.
+                * However, at least one window of corresponding process must have
+                * same focus information with has_focus.
+                */
+               if ((pid == window.pid) && (has_focus == window.is_focused))
+                       is_valid_window_stack = true;
 
                ret = insert_window_in_window_table(window_table, &window);
                if (ret < 0)
                        goto error_to_parse_window_stack;
        }
 
+       if (!is_valid_window_stack)
+               goto error_to_parse_window_stack;
+
        /**
         * Validity of all windows in window stack is checked,
         * so update proc_app_info structure of corresponding windows
@@ -1277,19 +1241,18 @@ EXPORT_TEST void proc_dbus_suspend_hint(GVariant *params)
 
 static void aul_app_lifecycle_state_changed_monitor_cb(const char *appid, pid_t pid,
                aul_app_lifecycle_state_e state, bool has_focus, void *user_data) {
-       char app_state[4];
-
        switch (state) {
+       case AUL_APP_LIFECYCLE_STATE_INITIALIZED:
+       case AUL_APP_LIFECYCLE_STATE_CREATED:
+       case AUL_APP_LIFECYCLE_STATE_DESTROYED:
+               return;
        case AUL_APP_LIFECYCLE_STATE_RESUMED:
-               strncpy(app_state, "fg", sizeof(app_state) - 1);
-               dbus_update_window_stack(pid, app_state);
-               break;
        case AUL_APP_LIFECYCLE_STATE_PAUSED:
-               strncpy(app_state, "bg", sizeof(app_state) -1);
-               dbus_update_window_stack(pid, app_state);
-               break;
-       default:
+               dbus_update_window_stack(pid, has_focus);
                return;
+       default:
+               _E("Unknown app life cycle state");
+               assert(0);
        }
 }