2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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.
29 #include "slave_life.h"
30 #include "slave_rpc.h"
31 #include "client_life.h"
33 #include "client_rpc.h"
38 #include "rpc_to_slave.h"
40 #include "ctx_wrapper.h"
44 Eina_List *event_list;
49 struct pended_ctx_info {
55 static inline void processing_ctx_event(const char *cluster, const char *category, const char *pkgname)
57 slave_rpc_request_update(pkgname, "", cluster, category);
58 if (util_free_space(IMAGE_PATH) > MINIMUM_SPACE) {
59 if (client_nr_of_subscriber(cluster, category) > 0) {
61 struct inst_info *inst;
63 timestamp = util_timestamp();
64 inst = instance_create(NULL, timestamp, pkgname, DEFAULT_CONTENT, cluster, category, DEFAULT_PERIOD, 0, 0);
66 ErrPrint("Failed to create an instance (%s / %s - %s)\n", cluster, category, pkgname);
68 DbgPrint("No subscribed clients. Ignore ctx event (%s / %s - %s)\n", cluster, category, pkgname);
71 ErrPrint("Not enough space\n");
74 DbgPrint("Context event is updated\n");
77 static inline int is_already_pended(const char *c_name, const char *s_name, const char *pkgname)
80 struct pended_ctx_info *info;
82 EINA_LIST_FOREACH(s_info.event_list, l, info) {
83 if (strcmp(pkgname, info->pkgname))
86 if (strcmp(s_name, info->category))
89 if (strcmp(c_name, info->cluster))
98 static inline void push_pended_item(const char *c_name, const char *s_name, const char *pkgname)
100 struct pended_ctx_info *pending_item;
102 if (eina_list_count(s_info.event_list) >= MAX_PENDED_CTX_EVENTS) {
103 ErrPrint("Reach to count of a maximum pended ctx events\n");
107 pending_item = malloc(sizeof(*pending_item));
109 ErrPrint("Heap: %s\n", strerror(errno));
113 pending_item->cluster = strdup(c_name);
114 if (!pending_item->cluster) {
115 ErrPrint("Heap: %s\n", strerror(errno));
116 DbgFree(pending_item);
120 pending_item->category = strdup(s_name);
121 if (!pending_item->category) {
122 ErrPrint("Heap: %s\n", strerror(errno));
123 DbgFree(pending_item->cluster);
124 DbgFree(pending_item);
128 pending_item->pkgname = strdup(pkgname);
129 if (!pending_item->pkgname) {
130 ErrPrint("Heap: %s\n", strerror(errno));
131 DbgFree(pending_item->cluster);
132 DbgFree(pending_item->category);
133 DbgFree(pending_item);
137 s_info.event_list = eina_list_append(s_info.event_list, pending_item);
138 ErrPrint("Context event is pended (%s/%s - %s)\n", c_name, s_name, pkgname);
141 static int ctx_changed_cb(struct context_item *item, void *user_data)
146 struct context_info *info;
147 struct category *category;
149 info = group_context_info_from_item(item);
151 ErrPrint("Context info is not valid (%p)\n", item);
155 category = group_category_from_context_info(info);
157 ErrPrint("Category info is not valid: %p\n", info);
161 c_name = group_cluster_name_by_category(category);
162 s_name = group_category_name(category);
163 pkgname = group_pkgname_from_context_info(info);
165 if (!c_name || !s_name || !pkgname) {
166 ErrPrint("Name is not valid (%s/%s/%s)\n", c_name, s_name, pkgname);
170 if (xmonitor_is_paused()) {
171 if (!is_already_pended(c_name, s_name, pkgname)) {
172 push_pended_item(c_name, s_name, pkgname);
174 DbgPrint("Already pended event : %s %s / %s\n", c_name, s_name, pkgname);
177 processing_ctx_event(c_name, s_name, pkgname);
183 static inline void enable_event_handler(struct context_info *info)
186 Eina_List *item_list;
187 struct context_item *item;
189 item_list = group_context_item_list(info);
190 EINA_LIST_FOREACH(item_list, l, item) {
193 handler = group_context_item_data(item, "callback");
195 ErrPrint("Already registered ctx callback\n");
199 handler = ctx_wrapper_register_callback(item, ctx_changed_cb, NULL);
200 if (group_context_item_add_data(item, "callback", handler) < 0)
201 ctx_wrapper_unregister_callback(handler);
205 static inline void register_callbacks(void)
207 Eina_List *cluster_list;
209 struct cluster *cluster;
211 Eina_List *category_list;
213 struct category *category;
215 Eina_List *info_list;
217 struct context_info *info;
219 cluster_list = group_cluster_list();
220 EINA_LIST_FOREACH(cluster_list, l1, cluster) {
221 category_list = group_category_list(cluster);
222 EINA_LIST_FOREACH(category_list, l2, category) {
223 info_list = group_context_info_list(category);
224 EINA_LIST_FOREACH(info_list, l3, info) {
225 enable_event_handler(info);
231 HAPI int ctx_enable_event_handler(struct context_info *info)
235 if (vconf_get_int(SYS_CLUSTER_KEY, &enabled) < 0)
239 DbgPrint("CTX in not enabled\n");
243 enable_event_handler(info);
247 HAPI int ctx_disable_event_handler(struct context_info *info)
250 Eina_List *item_list;
251 struct context_item *item;
253 item_list = group_context_item_list(info);
254 EINA_LIST_FOREACH(item_list, l, item) {
256 handler = group_context_item_del_data(item, "callback");
258 ctx_wrapper_unregister_callback(handler);
264 static inline void unregister_callbacks(void)
266 Eina_List *cluster_list;
268 struct cluster *cluster;
270 Eina_List *category_list;
272 struct category *category;
274 Eina_List *info_list;
276 struct context_info *info;
278 cluster_list = group_cluster_list();
279 EINA_LIST_FOREACH(cluster_list, l1, cluster) {
280 category_list = group_category_list(cluster);
281 EINA_LIST_FOREACH(category_list, l2, category) {
282 info_list = group_context_info_list(category);
283 EINA_LIST_FOREACH(info_list, l3, info) {
284 ctx_disable_event_handler(info);
290 static void ctx_vconf_cb(keynode_t *node, void *data)
295 /*!< Enable this for default option */
296 if (vconf_get_int(SYS_CLUSTER_KEY, &enabled) < 0)
299 enabled = vconf_keynode_get_int(node);
303 unregister_callbacks();
304 ctx_wrapper_disable();
308 ctx_wrapper_enable();
309 register_callbacks();
312 static int xmonitor_pause_cb(void *data)
314 DbgPrint("XMonitor Paused: do nothing\n");
318 static int xmonitor_resume_cb(void *data)
320 struct pended_ctx_info *item;
322 EINA_LIST_FREE(s_info.event_list, item) {
323 DbgPrint("Pended ctx event for %s - %s / %s\n", item->cluster, item->category, item->pkgname);
324 processing_ctx_event(item->cluster, item->category, item->pkgname);
326 DbgFree(item->cluster);
327 DbgFree(item->category);
328 DbgFree(item->pkgname);
335 HAPI int ctx_client_init(void)
339 xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_pause_cb, NULL);
340 xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resume_cb, NULL);
342 ret = vconf_notify_key_changed(SYS_CLUSTER_KEY, ctx_vconf_cb, NULL);
344 ErrPrint("Failed to register the system_cluster vconf\n");
346 ctx_vconf_cb(NULL, NULL);
350 HAPI int ctx_client_fini(void)
352 vconf_ignore_key_changed(SYS_CLUSTER_KEY, ctx_vconf_cb);
354 xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_pause_cb, NULL);
355 xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resume_cb, NULL);