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 motion_data_s {
27 GHashTable *callback_hash;
30 struct motion_callback_s {
31 motion_state_changed_cb callback;
35 struct motion_pass_data_s {
40 static struct motion_data_s *g_motion;
41 static pthread_mutex_t g_motion_mutex;
43 static int __free_motion_handle(struct motion_data_s *handle)
45 if (handle->callback_hash) {
46 g_hash_table_destroy(handle->callback_hash);
47 g_hash_table_unref(handle->callback_hash);
54 int motion_initialize(void)
57 _D("The motion is already initialized!");
61 g_motion = malloc(sizeof(struct motion_data_s));
62 retv_if(!g_motion, -1);
64 g_motion->callback_hash =
65 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
67 pthread_mutex_init(&g_motion_mutex, NULL);
70 /* TODO : initialize real motion detector here */
75 int motion_finalize(void)
78 pthread_mutex_destroy(&g_motion_mutex);
79 __free_motion_handle(g_motion);
86 static void __cb_item_foreach(gpointer key, gpointer value, gpointer user_data)
88 char *item_name = key;
89 struct motion_callback_s *cb_item = value;
90 struct motion_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 motion_pass_data_s *pass_item = data;
111 g_hash_table_foreach(g_motion->callback_hash, __cb_item_foreach, pass_item);
112 g_free(pass_item->pass_key);
115 return G_SOURCE_REMOVE;
118 int motion_state_set(int state, const char *pass_key)
121 retv_if(!g_motion, -1);
123 // _D("set state : %d", state);
125 pthread_mutex_lock(&g_motion_mutex);
126 old_state = g_motion->state;
127 pthread_mutex_unlock(&g_motion_mutex);
129 if (old_state != state) {
130 /* TODO : handle real motion detector here */
131 pthread_mutex_lock(&g_motion_mutex);
132 g_motion->state = state;
133 pthread_mutex_unlock(&g_motion_mutex);
135 if (g_hash_table_size(g_motion->callback_hash) > 0) {
136 struct motion_pass_data_s *pass_item = NULL;
138 pass_item = g_new(struct motion_pass_data_s, 1);
139 pass_item->pass_key = g_strdup(pass_key);
140 pass_item->state = state;
141 g_idle_add_full(IDLE_PRIORITY,
142 __call_cb_idle, pass_item, NULL);
148 int motion_state_get(int *state)
150 retv_if(!g_motion, -1);
153 pthread_mutex_lock(&g_motion_mutex);
154 *state = g_motion->state;
155 pthread_mutex_unlock(&g_motion_mutex);
157 // _D("get state : %d", *state);
162 int motion_state_changed_cb_set(
163 const char *callback_key, motion_state_changed_cb callback, void *cb_data)
165 retv_if(!g_motion, -1);
166 retv_if(!g_motion->callback_hash, -1);
167 retv_if(!callback_key, -1);
170 struct motion_callback_s *cb_item = NULL;
171 cb_item = g_try_new(struct motion_callback_s, 1);
172 retv_if(!cb_item, -1);
174 cb_item->callback = callback;
175 cb_item->cb_data = cb_data;
177 g_hash_table_insert(g_motion->callback_hash,
178 g_strdup(callback_key), cb_item);
180 g_hash_table_remove(g_motion->callback_hash, callback_key);