tizen 2.3 release
[framework/system/deviced.git] / src / proc / proc-handler.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <stdio.h>
21 #include <stdbool.h>
22 #include <unistd.h>
23 #include <dirent.h>
24 #include <sys/types.h>
25 #include <device-node.h>
26 #include <sys/un.h>
27 #include <stdarg.h>
28 #include <errno.h>
29 #include <vconf.h>
30 #include <vconf-keys.h>
31 #include <fcntl.h>
32
33 #include "core/log.h"
34 #include "core/common.h"
35 #include "core/devices.h"
36 #include "core/device-notifier.h"
37 #include "display/enhance.h"
38 #include "proc-handler.h"
39 #include "core/edbus-handler.h"
40
41 #define TEMPERATURE_DBUS_INTERFACE      "org.tizen.trm.siop"
42 #define TEMPERATURE_DBUS_PATH           "/Org/Tizen/Trm/Siop"
43 #define TEMPERATURE_DBUS_SIGNAL         "ChangedTemperature"
44
45 #define LIMITED_PROCESS_OOMADJ 15
46
47 #define PROCESS_VIP             "process_vip"
48 #define PROCESS_PERMANENT       "process_permanent"
49 #define OOMADJ_SET                      "oomadj_set"
50
51 #define PREDEF_BACKGRD                  "backgrd"
52 #define PREDEF_FOREGRD                  "foregrd"
53 #define PREDEF_ACTIVE                   "active"
54 #define PREDEF_INACTIVE                 "inactive"
55 #define PROCESS_GROUP_SET               "process_group_set"
56
57 #define VCONFKEY_INTERNAL_PRIVATE_SIOP_DISABLE  "memory/private/sysman/siop_disable"
58
59 #define BUFF_MAX        255
60 #define SIOP_CTRL_LEVEL_MASK    0xFFFF
61 #define SIOP_CTRL_LEVEL(val)    ((val & SIOP_CTRL_LEVEL_MASK) << 16)
62 #define SIOP_CTRL_VALUE(s, r)   (s | (r << 4))
63 #define SIOP_VALUE(d, val)      ((d) * (val & 0xF))
64 #define REAR_VALUE(val) (val >> 4)
65
66 #define SIGNAL_SIOP_CHANGED     "ChangedSiop"
67 #define SIGNAL_REAR_CHANGED     "ChangedRear"
68 #define SIOP_LEVEL_GET          "GetSiopLevel"
69 #define REAR_LEVEL_GET          "GetRearLevel"
70 #define SIOP_LEVEL_SET          "SetSiopLevel"
71
72 #define SIGNAL_NAME_OOMADJ_SET  "OomadjSet"
73
74 enum SIOP_DOMAIN_TYPE {
75         SIOP_NEGATIVE = -1,
76         SIOP_POSITIVE = 1,
77 };
78
79 struct siop_data {
80         int siop;
81         int rear;
82 };
83
84 static int siop = 0;
85 static int mode = 0;
86 static int siop_domain = SIOP_POSITIVE;
87
88 enum siop_scenario {
89         MODE_NONE = 0,
90         MODE_LCD = 1,
91 };
92 #ifdef NOUSE
93 typedef struct _node {
94         pid_t pid;
95         struct _node *next;
96 } Node;
97
98 static Node *head = NULL;
99
100 static Node *find_node(pid_t pid)
101 {
102         Node *t = head;
103
104         while (t != NULL) {
105                 if (t->pid == pid)
106                         break;
107                 t = t->next;
108         }
109         return t;
110 }
111
112 static Node *add_node(pid_t pid)
113 {
114         Node *n;
115
116         n = (Node *) malloc(sizeof(Node));
117         if (n == NULL) {
118                 _E("Not enough memory, add cond. fail");
119                 return NULL;
120         }
121
122         n->pid = pid;
123         n->next = head;
124         head = n;
125
126         return n;
127 }
128
129 static int del_node(Node *n)
130 {
131         Node *t;
132         Node *prev;
133
134         if (n == NULL)
135                 return 0;
136
137         t = head;
138         prev = NULL;
139         while (t != NULL) {
140                 if (t == n) {
141                         if (prev != NULL)
142                                 prev->next = t->next;
143                         else
144                                 head = head->next;
145                         free(t);
146                         break;
147                 }
148                 prev = t;
149                 t = t->next;
150         }
151         return 0;
152 }
153 #endif
154
155 int cur_siop_level(void)
156 {
157         return  SIOP_VALUE(siop_domain, siop);
158 }
159
160 static void siop_level_action(int level)
161 {
162         int val = SIOP_CTRL_LEVEL(level);
163         static int old;
164         static int siop_level = 0;
165         static int rear_level = 0;
166         static int initialized = 0;
167         static int domain = 0;
168         char *arr[1];
169         char str_level[32];
170
171         if (initialized && siop == level && mode == old && domain == siop_domain)
172                 return;
173         initialized = 1;
174         siop = level;
175         domain = siop_domain;
176         if (siop_domain == SIOP_NEGATIVE)
177                 val = 0;
178         old = mode;
179         val |= old;
180
181         device_set_property(DEVICE_TYPE_POWER, PROP_POWER_SIOP_CONTROL, val);
182
183         val = SIOP_VALUE(siop_domain, level);
184         if (siop_level != val) {
185                 siop_level = val;
186                 snprintf(str_level, sizeof(str_level), "%d", siop_level);
187                 arr[0] = str_level;
188                 _I("broadcast siop %s", str_level);
189                 broadcast_edbus_signal(DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS,
190                         SIGNAL_SIOP_CHANGED, "i", arr);
191         }
192
193         val = REAR_VALUE(level);
194         if (rear_level != val) {
195                 rear_level = val;
196                 snprintf(str_level, sizeof(str_level), "%d", rear_level);
197                 arr[0] = str_level;
198                 _I("broadcast rear %s", str_level);
199                 broadcast_edbus_signal(DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS,
200                         SIGNAL_REAR_CHANGED, "i", arr);
201         }
202         _I("level is d:%d(0x%x) s:%d r:%d", siop_domain, siop, siop_level, rear_level);
203 }
204
205 static int siop_changed(int argc, char **argv)
206 {
207         int siop_level = 0;
208         int rear_level = 0;
209         int level;
210         int siop_disable;
211         int ret;
212
213         if (argc != 2 || argv[0] == NULL) {
214                 _E("fail to check value");
215                 return -1;
216         }
217
218         if (argv[0] == NULL)
219                 goto out;
220
221         level = atoi(argv[0]);
222         device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_ELVSS_CONTROL, level);
223         ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_SIOP_LEVEL, &level);
224         if (ret != 0)
225                 goto check_rear;
226
227         if (level <= SIOP_NEGATIVE)
228                 siop_domain = SIOP_NEGATIVE;
229         else
230                 siop_domain = SIOP_POSITIVE;
231         siop_level = siop_domain * level;
232
233 check_rear:
234         if (argv[1] == NULL)
235                 goto out;
236
237         level = atoi(argv[1]);
238         if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_REAR_LEVEL, &level) == 0)
239                 rear_level = level;
240
241 out:
242         level = SIOP_CTRL_VALUE(siop_level, rear_level);
243         siop_level_action(level);
244         return 0;
245 }
246
247 static int siop_mode_lcd(keynode_t *key_nodes, void *data)
248 {
249         int pm_state;
250         if (vconf_get_int(VCONFKEY_PM_STATE, &pm_state) != 0)
251                 _E("Fail to get vconf value for pm state\n");
252         if (pm_state == VCONFKEY_PM_STATE_LCDOFF)
253                 mode = MODE_LCD;
254         else
255                 mode = MODE_NONE;
256         siop_level_action(siop);
257         return 0;
258 }
259
260 static void memcg_move_group(int pid, int oom_score_adj)
261 {
262         char buf[100];
263         FILE *f;
264         int ret, size;
265         char exe_name[PATH_MAX];
266
267         if (get_cmdline_name(pid, exe_name, PATH_MAX) != 0) {
268                 _E("fail to get process name(%d)", pid);
269                 return;
270         }
271
272         _SD("memcg_move_group : %s, pid = %d", exe_name, pid);
273         if (oom_score_adj >= OOMADJ_BACKGRD_LOCKED)
274                 sprintf(buf, "/sys/fs/cgroup/memory/background/cgroup.procs");
275         else if (oom_score_adj >= OOMADJ_FOREGRD_LOCKED && oom_score_adj < OOMADJ_BACKGRD_LOCKED)
276                 sprintf(buf, "/sys/fs/cgroup/memory/foreground/cgroup.procs");
277         else
278                 return;
279
280         f = fopen(buf, "w");
281         if (f == NULL)
282                 return;
283         size = sprintf(buf, "%d", pid);
284         if (fwrite(buf, size, 1, f) != 1)
285                 _E("fwrite cgroup tasks : %d\n", pid);;
286         fclose(f);
287 }
288
289 int get_oom_score_adj(int pid, int *oom_score_adj)
290 {
291         char buf[PATH_MAX];
292         FILE *fp;
293
294         if (pid < 0)
295                 return -1;
296
297         fp = open_proc_oom_score_adj_file(pid, "r");
298         if (fp == NULL)
299                 return -1;
300         if (fgets(buf, PATH_MAX, fp) == NULL) {
301                 fclose(fp);
302                 return -1;
303         }
304
305         *oom_score_adj = atoi(buf);
306         fclose(fp);
307         return 0;
308 }
309
310 int set_oom_score_adj(pid_t pid, int new_oom_score_adj)
311 {
312         FILE *fp;
313         int old_oom_score_adj;
314         char exe_name[PATH_MAX];
315
316         if (get_cmdline_name(pid, exe_name, PATH_MAX) < 0)
317                 snprintf(exe_name, sizeof(exe_name), "Unknown (maybe dead)");
318
319         if (get_oom_score_adj(pid, &old_oom_score_adj) < 0)
320                 return -1;
321
322         _SI("Process %s, pid %d, old_oom_score_adj %d new_oom_score_adj %d",
323                 exe_name, pid, old_oom_score_adj, new_oom_score_adj);
324
325         if (new_oom_score_adj < OOMADJ_SU)
326                 new_oom_score_adj = OOMADJ_SU;
327
328         fp = open_proc_oom_score_adj_file(pid, "w");
329         if (fp == NULL)
330                 return -1;
331
332         fprintf(fp, "%d", new_oom_score_adj);
333         fclose(fp);
334
335         return 0;
336 }
337
338 int set_su_oom_score_adj(pid_t pid)
339 {
340         return set_oom_score_adj(pid, OOMADJ_SU);
341 }
342
343 int check_oom_score_adj(int oom_score_adj)
344 {
345         if (oom_score_adj != OOMADJ_FOREGRD_LOCKED && oom_score_adj != OOMADJ_FOREGRD_UNLOCKED)
346                 return 0;
347         return -1;
348 }
349
350 int set_oom_score_adj_action(int argc, char **argv)
351 {
352         FILE *fp;
353         int pid = -1;
354         int new_oom_score_adj = 0;
355
356         if (argc < 2)
357                 return -1;
358         if ((pid = atoi(argv[0])) < 0 || (new_oom_score_adj = atoi(argv[1])) <= -20)
359                 return -1;
360
361         _I("OOMADJ_SET : pid %d, new_oom_score_adj %d", pid, new_oom_score_adj);
362
363         fp = open_proc_oom_score_adj_file(pid, "w");
364         if (fp == NULL)
365                 return -1;
366         if (new_oom_score_adj < OOMADJ_SU)
367                 new_oom_score_adj = OOMADJ_SU;
368         fprintf(fp, "%d", new_oom_score_adj);
369         fclose(fp);
370
371         memcg_move_group(pid, new_oom_score_adj);
372         return 0;
373 }
374
375 int set_active_action(int argc, char **argv)
376 {
377         int pid = -1;
378         int ret = 0;
379         int oom_score_adj = 0;
380
381         if (argc < 1)
382                 return -1;
383         if ((pid = atoi(argv[0])) < 0)
384                 return -1;
385
386         if (get_oom_score_adj(pid, &oom_score_adj) < 0)
387                 return -1;
388
389         switch (oom_score_adj) {
390         case OOMADJ_FOREGRD_LOCKED:
391         case OOMADJ_BACKGRD_LOCKED:
392         case OOMADJ_SU:
393                 ret = 0;
394                 break;
395         case OOMADJ_FOREGRD_UNLOCKED:
396                 ret = set_oom_score_adj((pid_t) pid, OOMADJ_FOREGRD_LOCKED);
397                 break;
398         case OOMADJ_BACKGRD_UNLOCKED:
399                 ret = set_oom_score_adj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
400                 break;
401         case OOMADJ_INIT:
402                 ret = set_oom_score_adj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
403                 break;
404         default:
405                 if(oom_score_adj > OOMADJ_BACKGRD_UNLOCKED) {
406                         ret = set_oom_score_adj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
407                 } else {
408                         _E("Unknown oom_score_adj value (%d) !", oom_score_adj);
409                         ret = -1;
410                 }
411                 break;
412         }
413         set_enhance_pid(pid);
414         return ret;
415 }
416
417 int set_inactive_action(int argc, char **argv)
418 {
419         int pid = -1;
420         int ret = 0;
421         int oom_score_adj = 0;
422
423         if (argc < 1)
424                 return -1;
425         if ((pid = atoi(argv[0])) < 0)
426                 return -1;
427
428         if (get_oom_score_adj(pid, &oom_score_adj) < 0)
429                 return -1;
430
431         switch (oom_score_adj) {
432         case OOMADJ_FOREGRD_UNLOCKED:
433         case OOMADJ_BACKGRD_UNLOCKED:
434         case OOMADJ_SU:
435                 ret = 0;
436                 break;
437         case OOMADJ_FOREGRD_LOCKED:
438                 ret = set_oom_score_adj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
439                 break;
440         case OOMADJ_BACKGRD_LOCKED:
441                 ret = set_oom_score_adj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
442                 break;
443         case OOMADJ_INIT:
444                 ret = set_oom_score_adj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
445                 break;
446         default:
447                 if(oom_score_adj > OOMADJ_BACKGRD_UNLOCKED) {
448                         ret = 0;
449                 } else {
450                         _E("Unknown oom_score_adj value (%d) !", oom_score_adj);
451                         ret = -1;
452                 }
453                 break;
454
455         }
456         set_enhance_pid(pid);
457         return ret;
458 }
459
460 int set_process_action(int argc, char **argv)
461 {
462         int pid = -1;
463         int ret = 0;
464
465         if (argc < 1)
466                 return -1;
467         if ((pid = atoi(argv[0])) < 0)
468                 return -1;
469
470         set_enhance_pid(pid);
471         return ret;
472 }
473
474 int set_process_group_action(int argc, char **argv)
475 {
476         int pid = -1;
477         int ret = -1;
478
479         if (argc != 2)
480                 return -1;
481         if ((pid = atoi(argv[0])) < 0)
482                 return -1;
483
484         if (strncmp(argv[1], PROCESS_VIP, strlen(PROCESS_VIP)) == 0)
485                 ret = device_set_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_MP_VIP, pid);
486         else if (strncmp(argv[1], PROCESS_PERMANENT, strlen(PROCESS_PERMANENT)) == 0)
487                 ret = device_set_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_MP_PNP, pid);
488
489         if (ret == 0)
490                 _I("%s : pid %d", argv[1], pid);
491         else
492                 _E("fail to set %s : pid %d",argv[1], pid);
493         return 0;
494 }
495
496 void check_siop_disable_process(int pid, char *default_name)
497 {
498         int oom_score_adj;
499         char exe_name[PATH_MAX];
500         if (pid <= 0)
501                 return;
502
503         if (get_oom_score_adj(pid, &oom_score_adj) < 0) {
504                 _E("fail to get adj value of pid: %d (%d)", pid);
505                 return;
506         }
507
508         if (get_cmdline_name(pid, exe_name, PATH_MAX) != 0) {
509                 _E("fail to check cmdline: %d (%s)", pid, default_name);
510                 return;
511         }
512
513         if (strncmp(exe_name, default_name, strlen(default_name)) != 0) {
514                 return;
515         }
516
517         switch (oom_score_adj) {
518         case OOMADJ_FOREGRD_LOCKED:
519         case OOMADJ_FOREGRD_UNLOCKED:
520                 siop_level_action(0);
521                 vconf_set_int(VCONFKEY_INTERNAL_PRIVATE_SIOP_DISABLE, 1);
522                 return;
523         case OOMADJ_BACKGRD_LOCKED:
524         case OOMADJ_BACKGRD_UNLOCKED:
525         case OOMADJ_SU:
526                 vconf_set_int(VCONFKEY_INTERNAL_PRIVATE_SIOP_DISABLE, 0);
527         }
528         return;
529 }
530
531 static DBusMessage *dbus_proc_handler(E_DBus_Object *obj, DBusMessage *msg)
532 {
533         DBusError err;
534         DBusMessageIter iter;
535         DBusMessage *reply;
536         pid_t pid;
537         int ret;
538         int argc;
539         char *type_str;
540         char *argv;
541
542         dbus_error_init(&err);
543
544         if (!dbus_message_get_args(msg, &err,
545                     DBUS_TYPE_STRING, &type_str,
546                     DBUS_TYPE_INT32, &argc,
547                     DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
548                 _E("there is no message");
549                 ret = -EINVAL;
550                 goto out;
551         }
552
553         if (argc < 0) {
554                 _E("message is invalid!");
555                 ret = -EINVAL;
556                 goto out;
557         }
558
559         pid = get_edbus_sender_pid(msg);
560         if (kill(pid, 0) == -1) {
561                 _E("%d process does not exist, dbus ignored!", pid);
562                 ret = -ESRCH;
563                 goto out;
564         }
565
566         if (strncmp(type_str, PREDEF_FOREGRD, strlen(PREDEF_FOREGRD)) == 0)
567                 ret = set_process_action(argc, (char **)&argv);
568         else if (strncmp(type_str, PREDEF_BACKGRD, strlen(PREDEF_BACKGRD)) == 0)
569                 ret = set_process_action(argc, (char **)&argv);
570         else if (strncmp(type_str, PREDEF_ACTIVE, strlen(PREDEF_ACTIVE)) == 0)
571                 ret = set_active_action(argc, (char **)&argv);
572         else if (strncmp(type_str, PREDEF_INACTIVE, strlen(PREDEF_INACTIVE)) == 0)
573                 ret = set_inactive_action(argc, (char **)&argv);
574 out:
575         reply = dbus_message_new_method_return(msg);
576         dbus_message_iter_init_append(reply, &iter);
577         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
578
579         return reply;
580 }
581
582 static DBusMessage *dbus_oom_handler(E_DBus_Object *obj, DBusMessage *msg)
583 {
584         DBusError err;
585         DBusMessageIter iter;
586         DBusMessage *reply;
587         pid_t pid;
588         int ret;
589         int argc;
590         char *type_str;
591         char *argv[2];
592
593         dbus_error_init(&err);
594
595         if (!dbus_message_get_args(msg, &err,
596                     DBUS_TYPE_STRING, &type_str,
597                     DBUS_TYPE_INT32, &argc,
598                     DBUS_TYPE_STRING, &argv[0],
599                     DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
600                 _E("there is no message");
601                 ret = -EINVAL;
602                 goto out;
603         }
604
605         if (argc < 0) {
606                 _E("message is invalid!");
607                 ret = -EINVAL;
608                 goto out;
609         }
610
611         pid = get_edbus_sender_pid(msg);
612         if (kill(pid, 0) == -1) {
613                 _E("%d process does not exist, dbus ignored!", pid);
614                 ret = -ESRCH;
615                 goto out;
616         }
617
618         if (strncmp(type_str, OOMADJ_SET, strlen(OOMADJ_SET)) == 0)
619                 ret = set_oom_score_adj_action(argc, (char **)&argv);
620         else if (strncmp(type_str, PROCESS_GROUP_SET, strlen(PROCESS_GROUP_SET)) == 0)
621                 ret = set_process_group_action(argc, (char **)&argv);
622 out:
623         reply = dbus_message_new_method_return(msg);
624         dbus_message_iter_init_append(reply, &iter);
625         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
626
627         return reply;
628 }
629
630 static DBusMessage *dbus_get_siop_level(E_DBus_Object *obj, DBusMessage *msg)
631 {
632         DBusMessageIter iter;
633         DBusMessage *reply;
634         int level;
635
636         level = SIOP_VALUE(siop_domain, siop);
637         reply = dbus_message_new_method_return(msg);
638         dbus_message_iter_init_append(reply, &iter);
639         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &level);
640         return reply;
641 }
642
643 static DBusMessage *dbus_get_rear_level(E_DBus_Object *obj, DBusMessage *msg)
644 {
645         DBusMessageIter iter;
646         DBusMessage *reply;
647         int level;
648
649         level = REAR_VALUE(siop);
650         reply = dbus_message_new_method_return(msg);
651         dbus_message_iter_init_append(reply, &iter);
652         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &level);
653         return reply;
654 }
655
656 static DBusMessage *dbus_set_siop_level(E_DBus_Object *obj, DBusMessage *msg)
657 {
658         DBusError err;
659         DBusMessageIter iter;
660         DBusMessage *reply;
661         int ret;
662         char *argv[2];
663
664         dbus_error_init(&err);
665
666         if (!dbus_message_get_args(msg, &err,
667                     DBUS_TYPE_STRING, &argv[0],
668                     DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
669                 _E("there is no message");
670                 ret = -EINVAL;
671                 goto out;
672         }
673         ret = siop_changed(2, (char **)&argv);
674 out:
675         reply = dbus_message_new_method_return(msg);
676         dbus_message_iter_init_append(reply, &iter);
677         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
678
679         return reply;
680 }
681
682 static void dbus_proc_oomadj_set_signal_handler(void *data, DBusMessage *msg)
683
684 {
685         DBusError err;
686         pid_t pid;
687         int ret = -EINVAL;
688         int argc;
689         char *type_str;
690         char *argv;
691
692         dbus_error_init(&err);
693
694         if (!dbus_message_get_args(msg, &err,
695                     DBUS_TYPE_STRING, &type_str,
696                     DBUS_TYPE_INT32, &argc,
697                     DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
698                 _E("there is no message");
699                 return;
700         }
701
702         if (argc < 0) {
703                 _E("message is invalid!");
704                 return;
705         }
706
707         pid = get_edbus_sender_pid(msg);
708         if (kill(pid, 0) == -1) {
709                 _E("%d process does not exist, dbus ignored!", pid);
710                 return;
711         }
712
713         if (strncmp(type_str, PREDEF_FOREGRD, strlen(PREDEF_FOREGRD)) == 0)
714                 ret = set_process_action(argc, (char **)&argv);
715         else if (strncmp(type_str, PREDEF_BACKGRD, strlen(PREDEF_BACKGRD)) == 0)
716                 ret = set_process_action(argc, (char **)&argv);
717         else if (strncmp(type_str, PREDEF_ACTIVE, strlen(PREDEF_ACTIVE)) == 0)
718                 ret = set_active_action(argc, (char **)&argv);
719         else if (strncmp(type_str, PREDEF_INACTIVE, strlen(PREDEF_INACTIVE)) == 0)
720                 ret = set_inactive_action(argc, (char **)&argv);
721
722         if (ret < 0)
723                 _E("set_process_action error!");
724 }
725
726 static const struct edbus_method edbus_methods[] = {
727         { PREDEF_FOREGRD, "sis", "i", dbus_proc_handler },
728         { PREDEF_BACKGRD, "sis", "i", dbus_proc_handler },
729         { PREDEF_ACTIVE, "sis", "i", dbus_proc_handler },
730         { PREDEF_INACTIVE, "sis", "i", dbus_proc_handler },
731         { OOMADJ_SET, "siss", "i", dbus_oom_handler },
732         { PROCESS_GROUP_SET, "siss", "i", dbus_oom_handler },
733         { SIOP_LEVEL_GET, NULL, "i", dbus_get_siop_level },
734         { REAR_LEVEL_GET, NULL, "i", dbus_get_rear_level },
735         { SIOP_LEVEL_SET, "ss", "i", dbus_set_siop_level },
736 };
737
738 static int proc_booting_done(void *data)
739 {
740         static int done = 0;
741
742         if (data == NULL)
743                 goto out;
744         done = (int)data;
745         if (vconf_notify_key_changed(VCONFKEY_PM_STATE, (void *)siop_mode_lcd, NULL) < 0)
746                 _E("Vconf notify key chaneged failed: KEY(%s)", VCONFKEY_PM_STATE);
747         siop_mode_lcd(NULL, NULL);
748 out:
749         return done;
750 }
751
752 static int process_execute(void *data)
753 {
754         struct siop_data* key_data = (struct siop_data *)data;
755         int siop_level = 0;
756         int rear_level = 0;
757         int level;
758         int siop_disable;
759         int ret;
760         int booting_done;
761
762         booting_done = proc_booting_done(NULL);
763         if (!booting_done)
764                 return 0;
765
766         if (key_data == NULL)
767                 goto out;
768
769         level = key_data->siop;
770         device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_ELVSS_CONTROL, level);
771         ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_SIOP_LEVEL, &level);
772         if (ret != 0)
773                 goto check_rear;
774
775         if (level <= SIOP_NEGATIVE)
776                 siop_domain = SIOP_NEGATIVE;
777         else
778                 siop_domain = SIOP_POSITIVE;
779         siop_level = siop_domain * level;
780
781 check_rear:
782         level = key_data->rear;
783         if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_REAR_LEVEL, &level) == 0)
784                 rear_level = level;
785
786 out:
787         level = SIOP_CTRL_VALUE(siop_level, rear_level);
788         siop_level_action(level);
789         return 0;
790 }
791
792 static void temp_change_signal_handler(void *data, DBusMessage *msg)
793 {
794         DBusError err;
795         int level = 0;
796
797         if (dbus_message_is_signal(msg, TEMPERATURE_DBUS_INTERFACE, TEMPERATURE_DBUS_SIGNAL) == 0) {
798                 _E("there is no cool down signal");
799                 return;
800         }
801
802         dbus_error_init(&err);
803
804         if (dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &level, DBUS_TYPE_INVALID) == 0) {
805                 _E("there is no message");
806                 return;
807         }
808         _D("%d", level);
809         device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_ELVSS_CONTROL, level);
810 }
811
812 static void process_init(void *data)
813 {
814         int ret;
815
816         register_edbus_signal_handler(DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS,
817                         SIGNAL_NAME_OOMADJ_SET,
818                     dbus_proc_oomadj_set_signal_handler);
819         register_edbus_signal_handler(TEMPERATURE_DBUS_PATH, TEMPERATURE_DBUS_INTERFACE,
820                         TEMPERATURE_DBUS_SIGNAL,
821                     temp_change_signal_handler);
822
823         ret = register_edbus_method(DEVICED_PATH_PROCESS, edbus_methods, ARRAY_SIZE(edbus_methods));
824         if (ret < 0)
825                 _E("fail to init edbus method(%d)", ret);
826
827         register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, proc_booting_done);
828 }
829
830 static const struct device_ops process_device_ops = {
831         .priority = DEVICE_PRIORITY_NORMAL,
832         .name     = PROC_OPS_NAME,
833         .init     = process_init,
834         .execute  = process_execute,
835 };
836
837 DEVICE_OPS_REGISTER(&process_device_ops)