[UI Thread] Add a new API about notify key changed 88/273188/6
authorHwankyu Jhun <h.jhun@samsung.com>
Thu, 31 Mar 2022 07:34:13 +0000 (16:34 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Fri, 1 Apr 2022 00:33:08 +0000 (09:33 +0900)
The function is added for UI thread. When adding a callback function,
vconf tries to get the glib context using getenv() with "TIZEN_GLIB_CONTEXT".
If it returns nullptr, the callback function will be invoked in the global default loop.

Adds:
 - vconf_notify_key_changed_for_ui_thread()

Change-Id: I960b972af0ed2e0376c26c5610e58cf8c8f42ef8
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
vconf-compat/vconf.c
vconf-compat/vconf.h
vconf-compat/vconf.sym

index 2f7ca9c..091dc62 100644 (file)
@@ -602,10 +602,28 @@ static struct noti_cb *_vconf_find_noti_cb(struct noti *noti, vconf_callback_fn
        return NULL;
 }
 
+static GMainContext *_vconf_get_tizen_glib_context(void)
+{
+       static GMainContext *context;
+       static int initialized;
+       const char *env;
+
+       if (initialized)
+               return context;
+
+       env = getenv("TIZEN_GLIB_CONTEXT");
+       if (env)
+               context = (GMainContext *)strtoul(env, NULL, 10);
+
+       initialized = 1;
+       return context;
+}
 
-static int _vconf_add_noti(struct noti *noti, vconf_callback_fn cb, void *user_data)
+static int _vconf_add_noti(struct noti *noti, vconf_callback_fn cb, void *user_data,
+               bool use_tizen_context)
 {
        struct noti_cb *noticb;
+       GMainContext *context;
 
        if (!noti || !cb) {
                LOGE("Invalid parameter");
@@ -633,7 +651,12 @@ static int _vconf_add_noti(struct noti *noti, vconf_callback_fn cb, void *user_d
        noticb->user_data = user_data;
        noticb->active = true;
        noticb->in_cb = false;
-       noticb->thread_ctx = g_main_context_ref_thread_default();
+
+       if (use_tizen_context) {
+               context = _vconf_get_tizen_glib_context();
+               if (context)
+                       noticb->thread_ctx = g_main_context_ref(context);
+       }
 
        noti->noti_list = g_list_append(noti->noti_list, noticb);
 
@@ -641,7 +664,7 @@ static int _vconf_add_noti(struct noti *noti, vconf_callback_fn cb, void *user_d
 }
 
 static int _vconf_create_noti(const char *key, vconf_callback_fn cb,
-               void *user_data, struct noti **new_noti)
+               void *user_data, bool use_tizen_context, struct noti **new_noti)
 {
        int r;
        struct noti *noti;
@@ -659,7 +682,7 @@ static int _vconf_create_noti(const char *key, vconf_callback_fn cb,
                return ENOMEM;
        }
 
-       r = _vconf_add_noti(noti, cb, user_data);
+       r = _vconf_add_noti(noti, cb, user_data, use_tizen_context);
        if (r != 0) {
                free(noti->key);
                free(noti);
@@ -691,8 +714,8 @@ static void _vconf_restore_noti_cb(gpointer key, gpointer value, gpointer user_d
 }
 /* LCOV_EXCL_STOP */
 
-EXPORT int vconf_notify_key_changed(const char *key, vconf_callback_fn cb,
-               void *user_data)
+static int _vconf_notify_key_changed(const char *key, vconf_callback_fn cb,
+               void *user_data, bool use_tizen_context)
 {
        int r;
        struct noti *noti;
@@ -714,7 +737,7 @@ EXPORT int vconf_notify_key_changed(const char *key, vconf_callback_fn cb,
 
        noti = g_hash_table_lookup(noti_tbl, key);
        if (!noti) {
-               r = _vconf_create_noti(key, cb, user_data, &noti);
+               r = _vconf_create_noti(key, cb, user_data, use_tizen_context, &noti);
                if (r != 0) {
                        _vconf_con_close();
                        _vconf_mutex_unlock();
@@ -733,7 +756,7 @@ EXPORT int vconf_notify_key_changed(const char *key, vconf_callback_fn cb,
                        r = _vconf_con_open();
                }
        } else {
-               r = _vconf_add_noti(noti, cb, user_data);
+               r = _vconf_add_noti(noti, cb, user_data, use_tizen_context);
        }
 
        _vconf_con_close();
@@ -747,6 +770,18 @@ EXPORT int vconf_notify_key_changed(const char *key, vconf_callback_fn cb,
        return 0;
 }
 
+EXPORT int vconf_notify_key_changed(const char *key, vconf_callback_fn cb,
+               void *user_data)
+{
+       return _vconf_notify_key_changed(key, cb, user_data, false);
+}
+
+EXPORT int vconf_notify_key_changed_for_ui_thread(const char *key, vconf_callback_fn cb,
+               void *user_data)
+{
+       return _vconf_notify_key_changed(key, cb, user_data, true);
+}
+
 static int _vconf_unregister_noti(struct noti *noti)
 {
        int cnt;
index 89daa62..09086ce 100644 (file)
@@ -1194,6 +1194,28 @@ int vconf_ignore_key_changed(const char *in_key, vconf_callback_fn cb);
 int vconf_get_ext_errno(void);
 
 /**
+ * @brief Adds a change callback for the given key, which is called when the key is set or unset.
+ * @details The changed information (#keynode_t) of the key is delivered to #vconf_callback_fn,
+ *          or if the key is deleted, the @link #keynode_t keynode @endlink has #VCONF_TYPE_NONE as type.
+ *
+ * @details Multiple vconf_callback_fn functions may exist for one key.
+ *
+ * @details The callback is invoked in the tizen glib context of the glib main loop for ui thread.
+ *
+ * @param[in] in_key     The key
+ * @param[in] cb         The callback function
+ * @param[in] user_data  The callback data
+ *
+ * @return  @c 0 on success,
+ *          otherwise @c -1 on error
+ *
+ * @see vconf_notify_key_changed()
+ * @see vconf_ignore_key_changed()
+ */
+int vconf_notify_key_changed_for_ui_thread(const char *in_key, vconf_callback_fn cb,
+               void *user_data);
+
+/**
  * @}
  */
 
index 745cacf..d417e47 100644 (file)
@@ -33,6 +33,7 @@ VCONF_BUXTON_1.0 {
                vconf_unset_recursive;
                vconf_sync_key;
                vconf_keylist_lookup;
+               vconf_notify_key_changed_for_ui_thread;
        local:
                *;
 };