e_keyrouter: apply thread synchronization for key grab variables 33/297733/1
authorJihoon Kim <jihoon48.kim@samsung.com>
Mon, 21 Aug 2023 11:20:26 +0000 (20:20 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Wed, 23 Aug 2023 09:47:18 +0000 (18:47 +0900)
key grab variables such as HardKeys[key].excl_ptr, or_excl_ptr, top_ptr can be updated
wherever _e_keyrouter_send_key_events_press() is executed in input thread.

Change-Id: I725acedbda32d6cc16d84dd86ccd228ff44daf8b
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
src/bin/e_keyrouter.c
src/bin/e_keyrouter_events.c
src/bin/e_keyrouter_list.c
src/bin/e_keyrouter_private.h
src/bin/e_keyrouter_wl.c

index ae5925d..3e541a6 100644 (file)
@@ -134,6 +134,8 @@ _e_keyrouter_info_print(void *data, const char *log_path)
 
    fprintf(log_fl, "\n===== Keyrouter Information =====\n");
    fprintf(log_fl, "    ----- Grabbable Keys -----\n");
+
+   g_mutex_lock(&krt->grab_key_mutex);
    for (i = 8; i <= krt->max_tizen_hwkeys; i++)
      {
         if (!krt->HardKeys[i].keycode) continue;
@@ -145,6 +147,7 @@ _e_keyrouter_info_print(void *data, const char *log_path)
         free(keyname);
         keyname = NULL;
      }
+   g_mutex_unlock(&krt->grab_key_mutex);
    fprintf(log_fl, "    ----- End -----\n\n");
 
    fclose(log_fl);
@@ -206,6 +209,8 @@ _e_keyrouter_keygrab_print(void *data, const char *log_path)
    fprintf(log_fl, "    ----- End -----\n\n");
 
    fprintf(log_fl, "    ----- Grabbed keys Info -----\n\n");
+
+   g_mutex_lock(&krt->grab_key_mutex);
    for (i = 8; i <= krt->max_tizen_hwkeys; i++)
      {
         if (!krt->HardKeys[i].keycode) continue;
@@ -265,6 +270,7 @@ _e_keyrouter_keygrab_print(void *data, const char *log_path)
 
         fprintf(log_fl, "\n");
      }
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    fprintf(log_fl, "    ----- End -----\n\n");
 
@@ -422,6 +428,8 @@ _e_keyrouter_query_tizen_key_table(void)
    krt->HardKeys = E_NEW(E_Keyrouter_Grabbed_Key, kconf->max_keycode + 1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(krt->HardKeys, EINA_FALSE);
 
+   g_mutex_lock(&krt->grab_key_mutex);
+
    krt->numTizenHWKeys = kconf->num_keycode;
    krt->max_tizen_hwkeys = kconf->max_keycode;
 
@@ -457,6 +465,8 @@ _e_keyrouter_query_tizen_key_table(void)
           }
      }
 
+   g_mutex_unlock(&krt->grab_key_mutex);
+
    if (e_comp_wl_input_keymap_cache_file_use_get() == EINA_FALSE)
      {
         KLINF("Server create a new cache file: %s", e_comp_wl_input_keymap_path_get(names));
@@ -490,15 +500,19 @@ e_keyrouter_longkey_add(int keycode, double time)
    EINA_SAFETY_ON_NULL_RETURN_VAL(krt, EINA_FALSE);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(keycode <= krt->max_tizen_hwkeys, EINA_FALSE);
 
+   g_mutex_lock(&krt->grab_key_mutex);
    if (krt->HardKeys[keycode].longkey.enabled == EINA_TRUE)
      {
         KLWRN("The %d keycode'long press is already enabled by time: %lf\n", keycode, krt->HardKeys[keycode].longkey.time);
+        g_mutex_unlock(&krt->grab_key_mutex);
         return EINA_FALSE;
      }
 
    krt->HardKeys[keycode].longkey.enabled = EINA_TRUE;
    krt->HardKeys[keycode].longkey.time = time;
 
+   g_mutex_unlock(&krt->grab_key_mutex);
+
    KLINF("To enable %d key's longkey function. (time: %lf)\n", keycode, time);
 
    return EINA_TRUE;
@@ -511,9 +525,10 @@ e_keyrouter_longkey_del(int keycode)
              How control this behavior?
              Cancel current long press or not
     */
-
+   g_mutex_lock(&krt->grab_key_mutex);
    krt->HardKeys[keycode].longkey.enabled = EINA_FALSE;
    krt->HardKeys[keycode].longkey.time = 0.0;
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    KLINF("To disable %d key's longkey function.\n", keycode);
 }
@@ -533,12 +548,13 @@ e_keyrouter_composition_key_add(int *keys, int count)
         KLWRN("Currently only two key composition is allowed. (%d)\n", count);
         return EINA_FALSE;
      }
-
+   g_mutex_lock(&krt->grab_key_mutex);
    EINA_LIST_FOREACH(krt->HardKeys[keys[0]].composition_key_list, l, data)
      {
         if (*data == keys[1])
           {
              KLWRN("%d and %d key's key composition is already requested.\n", keys[0], keys[1]);
+             g_mutex_unlock(&krt->grab_key_mutex);
              return EINA_FALSE;
           }
      }
@@ -547,9 +563,11 @@ e_keyrouter_composition_key_add(int *keys, int count)
         if (*data == keys[0])
           {
              KLERR("%d and %d key's key composition is already requested. (list currupted)\n", keys[0], keys[1]);
+             g_mutex_unlock(&krt->grab_key_mutex);
              return EINA_FALSE;
           }
      }
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    data = E_NEW(int, 1);
    EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
@@ -560,8 +578,10 @@ e_keyrouter_composition_key_add(int *keys, int count)
    *data = keys[0];
    *data2 = keys[1];
 
+   g_mutex_lock(&krt->grab_key_mutex);
    krt->HardKeys[keys[0]].composition_key_list = eina_list_append(krt->HardKeys[keys[0]].composition_key_list, data2);
    krt->HardKeys[keys[1]].composition_key_list = eina_list_append(krt->HardKeys[keys[1]].composition_key_list, data);
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    KLINF("Add %d and %d key composition.\n", keys[0], keys[1]);
 
@@ -589,6 +609,7 @@ e_keyrouter_composition_key_del(int *keys, int count)
         return;
      }
 
+   g_mutex_lock(&krt->grab_key_mutex);
    EINA_LIST_FOREACH_SAFE(krt->HardKeys[keys[0]].composition_key_list, l, l_next, data)
      {
         if (*data == keys[1])
@@ -608,6 +629,7 @@ e_keyrouter_composition_key_del(int *keys, int count)
              break;
           }
      }
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    KLINF("Delete %d and %d key composition.\n", keys[0], keys[1]);
 }
@@ -670,6 +692,8 @@ e_keyrouter_init(void)
    if (e_input_thread_mode_get())
      g_mutex_init(&krt->event_handler_mutex);
 
+   g_mutex_init(&krt->grab_key_mutex);
+
    kconfig = E_NEW(E_Keyrouter_Config_Data, 1);
    EINA_SAFETY_ON_NULL_GOTO(kconfig, err);
 
@@ -733,6 +757,7 @@ e_keyrouter_shutdown(void)
 
    _e_keyrouter_deinit_handlers();
 
+   g_mutex_lock(&krt->grab_key_mutex);
    for (i = 0; i <= krt->max_tizen_hwkeys; i++)
      {
         if (krt->HardKeys[i].keyname)
@@ -741,6 +766,7 @@ e_keyrouter_shutdown(void)
           E_FREE(keycode_data);
      }
    E_FREE(krt->HardKeys);
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    EINA_LIST_FREE(krt->ignore_list, keycode_data)
      E_FREE(keycode_data);
index 892b332..40923a8 100644 (file)
@@ -13,8 +13,11 @@ static Eina_Bool _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int a
 static Eina_Bool
 _e_keyrouter_is_key_grabbed(int key)
 {
+   g_mutex_lock(&krt->grab_key_mutex);
+
    if (!krt->HardKeys[key].keycode)
      {
+        g_mutex_unlock(&krt->grab_key_mutex);
         return EINA_FALSE;
      }
    if (krt->HardKeys[key].excl_ptr ||
@@ -22,9 +25,12 @@ _e_keyrouter_is_key_grabbed(int key)
         krt->HardKeys[key].top_ptr ||
         krt->HardKeys[key].shared_ptr)
      {
+        g_mutex_unlock(&krt->grab_key_mutex);
         return EINA_TRUE;
      }
 
+   g_mutex_unlock(&krt->grab_key_mutex);
+
    return EINA_FALSE;
 }
 
@@ -58,13 +64,22 @@ _e_keyrouter_event_routed_key_check(Ecore_Event_Key *ev, int type)
           }
      }
 
+
    if (krt->max_tizen_hwkeys < ev->keycode)
      {
         KLWRN("The key(%d) is too larger to process keyrouting: Invalid keycode", ev->keycode);
         return EINA_FALSE;
      }
 
-   if (!krt->HardKeys[ev->keycode].keycode) return EINA_FALSE;
+   g_mutex_lock(&krt->grab_key_mutex);
+
+   if (!krt->HardKeys[ev->keycode].keycode)
+     {
+        g_mutex_unlock(&krt->grab_key_mutex);
+        return EINA_FALSE;
+     }
+
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    return EINA_TRUE;
 }
@@ -168,6 +183,8 @@ _e_keyrouter_key_cancel(int keycode)
    E_FREE(keyname);
    EINA_SAFETY_ON_NULL_GOTO(key_release, failed);
 
+   g_mutex_lock(&krt->grab_key_mutex);
+
    EINA_LIST_FREE(krt->HardKeys[keycode].press_ptr, key_node_data)
      {
         _e_keyrouter_key_send(ECORE_EVENT_KEY_DOWN, key_cancel, NULL, key_node_data);
@@ -186,6 +203,8 @@ _e_keyrouter_key_cancel(int keycode)
      }
    krt->HardKeys[keycode].press_ptr = NULL;
 
+   g_mutex_unlock(&krt->grab_key_mutex);
+
    _e_keyrouter_key_free(key_cancel);
    _e_keyrouter_key_free(key_release);
 
@@ -528,6 +547,7 @@ _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev, E_Device *de
    E_Keyrouter_Event_Data *key_data = NULL;
 
    /* Deliver release  clean up pressed key list */
+   g_mutex_lock(&krt->grab_key_mutex);
    EINA_LIST_FREE(krt->HardKeys[ev->keycode].press_ptr, key_node_data)
      {
         if (key_node_data->focused == EINA_TRUE)
@@ -592,6 +612,7 @@ _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev, E_Device *de
         E_FREE(key_node_data);
      }
    krt->HardKeys[ev->keycode].press_ptr = NULL;
+   g_mutex_unlock(&krt->grab_key_mutex);
 }
 
 static void
@@ -618,6 +639,7 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
         return;
      }
 
+   g_mutex_lock(&krt->grab_key_mutex);
    EINA_LIST_FOREACH(krt->HardKeys[keycode].excl_ptr, l, key_node_data)
      {
         if (key_node_data)
@@ -633,6 +655,7 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
                       key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown");
              if(pname) E_FREE(pname);
              if(cmd) E_FREE(cmd);
+             g_mutex_unlock(&krt->grab_key_mutex);
              return;
           }
      }
@@ -652,12 +675,14 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
                      key_node_data->surface, key_node_data->wc, pid, pname ?: "Unknown");
              if(pname) E_FREE(pname);
              if(cmd) E_FREE(cmd);
-
+             g_mutex_unlock(&krt->grab_key_mutex);
              return;
           }
      }
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    // Top position grab must need a focus surface.
+   g_mutex_lock(&krt->grab_key_mutex);
    if (surface_focus)
      {
         EINA_LIST_FOREACH(krt->HardKeys[keycode].top_ptr, l, key_node_data)
@@ -678,6 +703,7 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
 
                        if(pname) E_FREE(pname);
                        if(cmd) E_FREE(cmd);
+                       g_mutex_unlock(&krt->grab_key_mutex);
                        return;
                     }
                   krt->isWindowStackChanged = EINA_FALSE;
@@ -697,6 +723,7 @@ _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev)
 
                        if(pname) E_FREE(pname);
                        if(cmd) E_FREE(cmd);
+                       g_mutex_unlock(&krt->grab_key_mutex);
                        return;
                     }
                   break;
@@ -744,6 +771,8 @@ need_shared:
                }
           }
      }
+
+   g_mutex_unlock(&krt->grab_key_mutex);
 }
 
 static Eina_Bool
@@ -824,7 +853,7 @@ _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx)
           }
 
         /* TODO: Check this client is located inside a display boundary */
-
+        g_mutex_lock(&krt->grab_key_mutex);
         EINA_LIST_FOREACH_SAFE(krt->HardKeys[arr_idx].top_ptr, l, l_next, key_node_data)
           {
              if (key_node_data)
@@ -834,10 +863,12 @@ _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx)
                        krt->HardKeys[arr_idx].top_ptr = eina_list_promote_list(krt->HardKeys[arr_idx].top_ptr, l);
                        KLDBG("Move a client(e_client: %p, wl_surface: %p) to first index of list(key: %d)",
                                 ec_top, key_node_data->surface, arr_idx);
+                       g_mutex_unlock(&krt->grab_key_mutex);
                        return EINA_TRUE;
                     }
                }
           }
+        g_mutex_unlock(&krt->grab_key_mutex);
 
         if (ec_top == ec_focus)
           {
index bf99aa3..6e74f99 100644 (file)
@@ -19,8 +19,12 @@ e_keyrouter_set_keygrab_in_list(struct wl_resource *surface, struct wl_client *c
 
    if (mode == TIZEN_KEYROUTER_MODE_EXCLUSIVE)
      {
+        bool check_grabbed = false;
+        g_mutex_lock(&krt->grab_key_mutex);
+        check_grabbed = (krt->HardKeys[key].excl_ptr != NULL);
+        g_mutex_unlock(&krt->grab_key_mutex);
         EINA_SAFETY_ON_TRUE_RETURN_VAL
-          ((krt->HardKeys[key].excl_ptr != NULL),
+          (check_grabbed,
            TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY);
      }
 
@@ -48,9 +52,11 @@ _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_clien
    Eina_List *keylist_ptr = NULL, *l = NULL;
    E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
 
+   g_mutex_lock(&krt->grab_key_mutex);
    switch(mode)
      {
       case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
+         g_mutex_unlock(&krt->grab_key_mutex);
          return TIZEN_KEYROUTER_ERROR_NONE;
 
       case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE:
@@ -74,8 +80,10 @@ _e_keyrouter_find_duplicated_client(struct wl_resource *surface, struct wl_clien
          break;
       default:
          KLWRN("Unknown key(%d) and grab mode(%d)", key, mode);
+         g_mutex_unlock(&krt->grab_key_mutex);
          return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
      }
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    EINA_LIST_FOREACH(keylist_ptr, l, key_node_data)
      {
@@ -150,6 +158,8 @@ e_keyrouter_prepend_to_keylist(struct wl_resource *surface, struct wl_client *wc
    new_keyptr->focused = focused;
    new_keyptr->status = E_KRT_CSTAT_ALIVE;
 
+   g_mutex_lock(&krt->grab_key_mutex);
+
    switch(mode)
      {
       case TIZEN_KEYROUTER_MODE_EXCLUSIVE:
@@ -179,20 +189,22 @@ e_keyrouter_prepend_to_keylist(struct wl_resource *surface, struct wl_client *wc
       default:
          KLWRN("Unknown key(%d) and grab mode(%d)", key, mode);
          E_FREE(new_keyptr);
+         g_mutex_unlock(&krt->grab_key_mutex);
          return TIZEN_KEYROUTER_ERROR_INVALID_MODE;
      }
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    if (TIZEN_KEYROUTER_MODE_PRESSED != mode)
      {
         if (surface)
           {
              e_keyrouter_wl_add_surface_destroy_listener(surface);
-             /* TODO: if failed add surface_destory_listener, remove keygrabs */
+             /* TODO: if failed add surface_destroy_listener, remove keygrabs */
           }
         else if (wc)
           {
              e_keyrouter_wl_add_client_destroy_listener(wc);
-             /* TODO: if failed add client_destory_listener, remove keygrabs */
+             /* TODO: if failed add client_destroy_listener, remove keygrabs */
           }
      }
 
@@ -255,6 +267,8 @@ e_keyrouter_remove_client_from_list(struct wl_resource *surface, struct wl_clien
 
    EINA_SAFETY_ON_TRUE_RETURN(((!surface) && (!wc)));
 
+   g_mutex_lock(&krt->grab_key_mutex);
+
    for (i = 0; i <= krt->max_tizen_hwkeys; i++)
      {
         if (0 == krt->HardKeys[i].keycode) continue;
@@ -376,6 +390,8 @@ e_keyrouter_remove_client_from_list(struct wl_resource *surface, struct wl_clien
                }
           }
      }
+
+   g_mutex_unlock(&krt->grab_key_mutex);
 }
 
 int
@@ -432,6 +448,8 @@ _e_keyrouter_get_list(int mode, int key)
 {
    Eina_List **list = NULL;
 
+   g_mutex_lock(&krt->grab_key_mutex);
+
    switch (mode)
      {
         case TIZEN_KEYROUTER_MODE_EXCLUSIVE:             list = &krt->HardKeys[key].excl_ptr;    break;
@@ -442,6 +460,8 @@ _e_keyrouter_get_list(int mode, int key)
         default: break;
      }
 
+   g_mutex_unlock(&krt->grab_key_mutex);
+
    return list;
 }
 
@@ -477,13 +497,16 @@ e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface, i
         return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
      }
 
+   g_mutex_lock(&krt->grab_key_mutex);
    /* Check whether the key can be grabbed or not !
     * Only key listed in Tizen key layout file can be grabbed. */
    if (0 == krt->HardKeys[key].keycode)
      {
         KLWRN("Invalid key ! Disabled to set keygrab ! (keycode:%d)", key);
+        g_mutex_unlock(&krt->grab_key_mutex);
         return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
      }
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    /* Check whether the request key can be grabbed or not */
    res = e_keyrouter_set_keygrab_in_list(surface, client, key, mode);
@@ -494,11 +517,13 @@ e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface, i
 int
 e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface, int key)
 {
+   g_mutex_lock(&krt->grab_key_mutex);
 
    /* Check the given key range */
    if (krt->max_tizen_hwkeys < key)
      {
         KLWRN("Invalid range of key ! (keycode:%d) maximum value(%d)", key, krt->max_tizen_hwkeys);
+        g_mutex_unlock(&krt->grab_key_mutex);
         return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
      }
 
@@ -507,9 +532,12 @@ e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface,
    if (0 == krt->HardKeys[key].keycode)
      {
         KLWRN("Invalid key ! Disabled to unset keygrab! (keycode:%d)", key);
+        g_mutex_unlock(&krt->grab_key_mutex);
         return TIZEN_KEYROUTER_ERROR_INVALID_KEY;
      }
 
+   g_mutex_unlock(&krt->grab_key_mutex);
+
    /* Ungrab top position grabs first. This grab mode do not need privilege */
    if (!surface)
      e_keyrouter_find_and_remove_client_from_list(NULL, client, key, TIZEN_KEYROUTER_MODE_TOPMOST);
index 5f05374..a977711 100644 (file)
@@ -89,6 +89,7 @@ struct _E_Keyrouter
    E_Input_Event_Handler *_key_down_handler;
    E_Input_Event_Handler *_key_up_handler;
    GMutex event_handler_mutex;
+   GMutex grab_key_mutex;
 };
 
 struct _E_Keyrouter_Grab_Request {
index 3f14be1..def5d56 100644 (file)
@@ -146,6 +146,7 @@ e_keyrouter_keycancel_send(struct wl_client *client, struct wl_resource *surface
 
    EINA_SAFETY_ON_NULL_RETURN(wc);
 
+   g_mutex_lock(&krt->grab_key_mutex);
    EINA_LIST_FOREACH(krt->HardKeys[key].press_ptr, l, data)
      {
         if (surface)
@@ -170,6 +171,7 @@ e_keyrouter_keycancel_send(struct wl_client *client, struct wl_resource *surface
                }
           }
      }
+   g_mutex_unlock(&krt->grab_key_mutex);
 }
 
 static int
@@ -543,13 +545,19 @@ e_keyrouter_wl_util_do_privilege_check(struct wl_client *client, uint32_t mode,
    if (mode == TIZEN_KEYROUTER_MODE_TOPMOST)
      return EINA_TRUE;
 
+   g_mutex_lock(&krt->grab_key_mutex);
    if (krt->HardKeys[keycode].no_privcheck == EINA_TRUE &&
        mode == TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE)
-     return EINA_TRUE;
+     {
+        g_mutex_unlock(&krt->grab_key_mutex);
+        return EINA_TRUE;
+     }
+
+   g_mutex_unlock(&krt->grab_key_mutex);
 
    if (!client) return EINA_FALSE;
 
-   /* If initialize cynara is failed, allow keygrabs regardless of the previlege permition. */
+   /* If initialize cynara is failed, allow keygrabs regardless of the privilege permission. */
    if (krt->p_cynara == NULL)
      {
         if (retried == EINA_FALSE)