2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #define IDLE_PRIORITY (G_PRIORITY_HIGH_IDLE + 30)
25 struct switch_data_s {
27 GHashTable *callback_hash;
30 struct switch_callback_s {
31 switch_state_changed_cb callback;
35 struct switch_pass_data_s {
40 static struct switch_data_s *g_switch;
41 static pthread_mutex_t g_switch_mutex;
43 static int __free_switch_handle(struct switch_data_s *sw)
45 if (sw->callback_hash) {
46 g_hash_table_destroy(sw->callback_hash);
47 g_hash_table_unref(sw->callback_hash);
54 int switch_initialize(void)
57 _D("The switch is already initialized!");
61 g_switch = malloc(sizeof(struct switch_data_s));
62 retv_if(!g_switch, -1);
64 g_switch->callback_hash =
65 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
67 pthread_mutex_init(&g_switch_mutex, NULL);
68 g_switch->state = SWITCH_STATE_OFF;
70 /* TODO : initialize real switch here */
75 int switch_finalize(void)
78 pthread_mutex_destroy(&g_switch_mutex);
79 __free_switch_handle(g_switch);
86 static void __cb_item_foreach(gpointer key, gpointer value, gpointer user_data)
88 char *item_name = key;
89 struct switch_callback_s *cb_item = value;
90 struct switch_pass_data_s *pass_item = user_data;
97 if (pass_item->pass_key &&
98 (0 == g_strcmp0(item_name, pass_item->pass_key))) {
99 // _D("pass item - %s", item_name);
103 _D("callback called for [%s]", item_name);
104 cb_item->callback(pass_item->state, cb_item->cb_data);
107 static gboolean __call_cb_idle(gpointer data)
109 struct switch_pass_data_s *pass_item = data;
111 g_hash_table_foreach(g_switch->callback_hash, __cb_item_foreach, pass_item);
112 g_free(pass_item->pass_key);
115 return G_SOURCE_REMOVE;
118 int switch_state_set(switch_state_e state, const char *pass_key)
121 retv_if(!g_switch, -1);
123 pthread_mutex_lock(&g_switch_mutex);
124 old_state = g_switch->state;
125 pthread_mutex_unlock(&g_switch_mutex);
127 if (old_state != state) {
128 pthread_mutex_lock(&g_switch_mutex);
129 g_switch->state = state;
130 pthread_mutex_unlock(&g_switch_mutex);
132 if (g_hash_table_size(g_switch->callback_hash) > 0) {
133 struct switch_pass_data_s *pass_item = NULL;
135 pass_item = g_new(struct switch_pass_data_s, 1);
136 pass_item->pass_key = g_strdup(pass_key);
137 pass_item->state = state;
138 g_idle_add_full(IDLE_PRIORITY,
139 __call_cb_idle, pass_item, NULL);
145 int switch_state_get(switch_state_e *state)
147 retv_if(!g_switch, -1);
150 pthread_mutex_lock(&g_switch_mutex);
151 *state = g_switch->state;
152 pthread_mutex_unlock(&g_switch_mutex);
154 // _D("get state : %d", *state);
159 int switch_state_changed_cb_set(
160 const char *callback_key, switch_state_changed_cb callback, void *cb_data)
162 retv_if(!g_switch, -1);
163 retv_if(!g_switch->callback_hash, -1);
164 retv_if(!callback_key, -1);
167 struct switch_callback_s *cb_item = NULL;
168 cb_item = g_try_new(struct switch_callback_s, 1);
169 retv_if(!cb_item, -1);
171 cb_item->callback = callback;
172 cb_item->cb_data = cb_data;
174 g_hash_table_insert(g_switch->callback_hash,
175 g_strdup(callback_key), cb_item);
177 g_hash_table_remove(g_switch->callback_hash, callback_key);