4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
28 #include <sys/types.h>
33 #include "appcore-agent.h"
41 #define LOG_TAG "APPCORE_AGENT"
45 # define EXPORT_API __attribute__ ((visibility("default")))
48 #define _warn_if(expr, fmt, arg...) do { \
54 #define _ret_if(expr) do { \
60 #define _retv_if(expr, val) do { \
66 #define _retm_if(expr, fmt, arg...) do { \
73 #define _retvm_if(expr, val, fmt, arg...) do { \
84 * Appcore internal system event
94 * agent internal state
114 static enum appcore_agent_event to_ae[SE_MAX] = {
115 APPCORE_AGENT_EVENT_UNKNOWN, /* SE_UNKNOWN */
116 APPCORE_AGENT_EVENT_LOW_MEMORY, /* SE_LOWMEM */
117 APPCORE_AGENT_EVENT_LOW_BATTERY, /* SE_LOWBAT */
121 enum cb_type { /* callback */
131 enum appcore_agent_event sys;
132 enum agent_event app;
136 int (*cb_pre) (void *);
138 int (*cb_post) (void *);
140 int (*vcb_pre) (void *, void *);
141 int (*vcb) (void *, void *);
142 int (*vcb_post) (void *, void *);
146 enum agent_state state;
148 struct agentcore_ops *ops;
151 static struct agent_priv priv;
155 void (*cb_app)(int, void *, bundle *);
159 * Appcore system event operation
162 int (*func) (void *);
166 struct agent_appcore {
169 const struct agent_ops *ops;
170 struct sys_op sops[SE_MAX];
173 static struct agent_appcore core;
177 extern int service_create_request(bundle *data, service_h *service);
178 static int __sys_lowmem_post(void *data, void *evt);
179 static int __sys_lowmem(void *data, void *evt);
180 static int __sys_lowbatt(void *data, void *evt);
183 static struct evt_ops evtops[] = {
186 .key.vkey = VCONFKEY_SYSMAN_LOW_MEMORY,
187 .vcb_post = __sys_lowmem_post,
192 .key.vkey = VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
193 .vcb = __sys_lowbatt,
197 static void __do_app(enum agent_event event, void *data, bundle * b)
200 struct agent_priv *svc = data;
201 service_h service = NULL;
203 _ret_if(svc == NULL);
205 if (event == AGE_TERMINATE) {
206 svc->state = AGS_DYING;
207 g_main_loop_quit(mainloop);
211 _ret_if(svc->ops == NULL);
213 if (service_create_event(b, &service) != 0)
220 if (svc->ops->service)
221 r = svc->ops->service(service, svc->ops->data);
222 svc->state = AGS_RUNNING;
225 if(svc->state == AGS_RUNNING) {
227 r = svc->ops->stop(svc->ops->data);
228 svc->state = AGS_STOPED;
235 service_destroy(service);
238 static struct agent_ops s_ops = {
243 static int __set_data(struct agent_priv *agent, struct agentcore_ops *ops)
257 static int __agent_request(void *data, bundle * k)
259 struct agent_appcore *ac = data;
260 _retv_if(ac == NULL || ac->ops == NULL, -1);
261 _retv_if(ac->ops->cb_app == NULL, 0);
263 ac->ops->cb_app(AGE_REQUEST, ac->ops->data, k);
268 static int __agent_terminate(void *data)
270 struct agent_appcore *ac = data;
272 _retv_if(ac == NULL || ac->ops == NULL, -1);
273 _retv_if(ac->ops->cb_app == NULL, 0);
275 ac->ops->cb_app(AGE_TERMINATE, ac->ops->data, NULL);
280 static int __sys_do_default(struct appcore *ac, enum sys_event event)
286 /*r = __def_lowbatt(ac);*/
297 static int __sys_do(struct agent_appcore *ac, enum sys_event event)
301 _retv_if(ac == NULL || event >= SE_MAX, -1);
303 op = &ac->sops[event];
305 if (op->func == NULL)
306 return __sys_do_default(ac, event);
308 return op->func(op->data);
311 static int __sys_lowmem_post(void *data, void *evt)
313 #if defined(MEMORY_FLUSH_ACTIVATE)
314 struct appcore *ac = data;
315 ac->ops->cb_app(AE_LOWMEM_POST, ac->ops->data, NULL);
322 static int __sys_lowmem(void *data, void *evt)
324 return __sys_do(data, SE_LOWMEM);
327 static int __sys_lowbatt(void *data, void *evt)
329 keynode_t *key = evt;
332 val = vconf_keynode_get_int(key);
334 /* VCONFKEY_SYSMAN_BAT_CRITICAL_LOW or VCONFKEY_SYSMAN_POWER_OFF */
335 if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW)
336 return __sys_do(data, SE_LOWBAT);
341 static void __vconf_do(struct evt_ops *eo, keynode_t * key, void *data)
346 eo->vcb_pre(data, key);
352 eo->vcb_post(data, key);
355 static void __vconf_cb(keynode_t *key, void *data)
360 name = vconf_keynode_get_name(key);
361 _ret_if(name == NULL);
363 SECURE_LOGD("[APP %d] vconf changed: %s", _pid, name);
365 for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) {
366 struct evt_ops *eo = &evtops[i];
370 if (!strcmp(name, eo->key.vkey))
371 __vconf_do(eo, key, data);
380 static int __add_vconf(struct agent_appcore *ac)
385 for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) {
386 struct evt_ops *eo = &evtops[i];
390 r = vconf_notify_key_changed(eo->key.vkey, __vconf_cb,
402 static int __del_vconf(void)
407 for (i = 0; i < sizeof(evtops) / sizeof(evtops[0]); i++) {
408 struct evt_ops *eo = &evtops[i];
412 r = vconf_ignore_key_changed(eo->key.vkey, __vconf_cb);
423 static int __aul_handler(aul_type type, bundle *b, void *data)
429 ret = __agent_request(data, b);
434 ret = __service_stop(data);
438 ret = __agent_terminate(data);
448 EXPORT_API int appcore_agent_set_event_callback(enum appcore_agent_event event,
449 int (*cb) (void *), void *data)
451 struct agent_appcore *ac = &core;
455 for (se = SE_UNKNOWN; se < SE_MAX; se++) {
456 if (event == to_ae[se])
460 if (se == SE_UNKNOWN || se >= SE_MAX) {
461 _ERR("Unregistered event");
474 EXPORT_API int appcore_agent_init(const struct agent_ops *ops,
475 int argc, char **argv)
479 if (core.state != 0) {
484 if (ops == NULL || ops->cb_app == NULL) {
489 r = __add_vconf(&core);
491 _ERR("Add vconf callback failed");
495 r = aul_launch_init(__aul_handler, &core);
500 r = aul_launch_argv_handler(argc, argv);
506 core.state = 1; /* TODO: use enum value */
515 static int __before_loop(struct agent_priv *agent, int argc, char **argv)
519 if (argc == NULL || argv == NULL) {
526 r = appcore_agent_init(&s_ops, argc, argv);
527 _retv_if(r == -1, -1);
529 if (agent->ops && agent->ops->create) {
530 r = agent->ops->create(agent->ops->data);
537 agent->state = AGS_CREATED;
542 static void __after_loop(struct agent_priv *agent)
544 priv.state = AGS_DYING;
545 if (agent->ops && agent->ops->terminate)
546 agent->ops->terminate(agent->ops->data);
550 EXPORT_API int appcore_agent_terminate()
552 g_main_loop_quit(mainloop);
557 EXPORT_API int appcore_agent_main(int argc, char **argv,
558 struct agentcore_ops *ops)
562 r = __set_data(&priv, ops);
563 _retv_if(r == -1, -1);
565 r = __before_loop(&priv, argc, argv);
567 //__unset_data(&priv);
571 mainloop = g_main_loop_new(NULL, FALSE);
573 g_main_loop_run(mainloop);
578 //__unset_data(&priv);