tizen 2.3 release
[framework/system/deviced.git] / src / core / device-change-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 <stdbool.h>
21 #include <stdlib.h>
22 #include <fcntl.h>
23 #include <dirent.h>
24 #include <errno.h>
25 #include <vconf.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/mount.h>
29 #include <dirent.h>
30 #include <fnmatch.h>
31 #include "dd-deviced.h"
32 #include "log.h"
33 #include "device-notifier.h"
34 #include "device-handler.h"
35 #include "device-node.h"
36 #include "display/poll.h"
37 #include "devices.h"
38 #include "hall/hall-handler.h"
39 #include "udev.h"
40 #include "common.h"
41 #include "list.h"
42 #include "ode/ode.h"
43 #include "proc/proc-handler.h"
44 #include "edbus-handler.h"
45 #include "devices.h"
46 #include "power-supply.h"
47 #include "display/setting.h"
48 #include "display/core.h"
49 #include "usb/usb-client.h"
50
51 #define PREDEF_DEVICE_CHANGED           "device_changed"
52 #define PREDEF_POWER_CHANGED            POWER_SUBSYSTEM
53 #define PREDEF_UDEV_CONTROL             UDEV
54
55 #define TVOUT_X_BIN                     "/usr/bin/xberc"
56 #define TVOUT_FLAG                      0x00000001
57
58 #define MOVINAND_MOUNT_POINT            "/opt/media"
59 #define BUFF_MAX                255
60 #define SYS_CLASS_INPUT         "/sys/class/input"
61
62 #define USB_STATE_PLATFORM_PATH "/sys/devices/platform/jack/usb_online"
63 #define USB_STATE_SWITCH_PATH "/sys/devices/virtual/switch/usb_cable/state"
64
65 #define HDMI_NOT_SUPPORTED      (-1)
66 #ifdef ENABLE_EDBUS_USE
67 #include <E_DBus.h>
68 static E_DBus_Connection *conn;
69 #endif                          /* ENABLE_EDBUS_USE */
70
71 struct input_event {
72         long dummy[2];
73         unsigned short type;
74         unsigned short code;
75         int value;
76 };
77
78 enum snd_jack_types {
79         SND_JACK_HEADPHONE = 0x0001,
80         SND_JACK_MICROPHONE = 0x0002,
81         SND_JACK_HEADSET = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
82         SND_JACK_LINEOUT = 0x0004,
83         SND_JACK_MECHANICAL = 0x0008,   /* If detected separately */
84         SND_JACK_VIDEOOUT = 0x0010,
85         SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT,
86 };
87
88 #define CRADLE_APP_NAME         "com.samsung.desk-dock"
89 #define VIRTUAL_CONTROLLER_APP_NAME             "com.samsung.virtual-controller"
90
91 #define CHANGE_ACTION           "change"
92 #define ENV_FILTER              "CHGDET"
93 #define USB_NAME                "usb"
94 #define USB_NAME_LEN            3
95
96 #define CHARGER_NAME            "charger"
97 #define CHARGER_NAME_LEN        7
98
99 #define EARJACK_NAME            "earjack"
100 #define EARJACK_NAME_LEN        7
101
102 #define EARKEY_NAME             "earkey"
103 #define EARKEY_NAME_LEN 6
104
105 #define TVOUT_NAME              "tvout"
106 #define TVOUT_NAME_LEN          5
107
108 #define HDMI_NAME               "hdmi"
109 #define HDMI_NAME_LEN           4
110
111 #define HDCP_NAME               "hdcp"
112 #define HDCP_NAME_LEN           4
113
114 #define HDMI_AUDIO_NAME         "ch_hdmi_audio"
115 #define HDMI_AUDIO_LEN          13
116
117 #define CRADLE_NAME             "cradle"
118 #define CRADLE_NAME_LEN 6
119
120 #define KEYBOARD_NAME           "keyboard"
121 #define KEYBOARD_NAME_LEN       8
122
123 #define POWER_SUPPLY_NAME_LEN   12
124
125 #define CHARGE_NAME_LEN 17
126 #define BATTERY_NAME            "battery"
127 #define BATTERY_NAME_LEN        7
128 #define CHARGEFULL_NAME "Full"
129 #define CHARGEFULL_NAME_LEN     4
130 #define CHARGENOW_NAME          "Charging"
131 #define CHARGENOW_NAME_LEN      8
132 #define DISCHARGE_NAME          "Discharging"
133 #define DISCHARGE_NAME_LEN      11
134 #define NOTCHARGE_NAME          "Not charging"
135 #define NOTCHARGE_NAME_LEN      12
136 #define OVERHEAT_NAME           "Overheat"
137 #define OVERHEAT_NAME_LEN       8
138 #define TEMPCOLD_NAME           "Cold"
139 #define TEMPCOLD_NAME_LEN       4
140 #define OVERVOLT_NAME           "Over voltage"
141 #define OVERVOLT_NAME_LEN       12
142
143 #define SWITCH_DEVICE_USB       "usb_cable"
144
145 #define LAUNCH_APP      "launch-app"
146 #define DESK_DOCK       "desk-dock"
147
148 /* Ticker notification */
149 #define DOCK_CONNECTED    "dock-connected"
150 #define HDMI_CONNECTED    "hdmi-connected"
151 #define HDMI_DISCONNECTED "hdmi-disconnected"
152
153 #define METHOD_GET_HDMI         "GetHDMI"
154 #define METHOD_GET_HDCP         "GetHDCP"
155 #define METHOD_GET_HDMI_AUDIO   "GetHDMIAudio"
156 #define SIGNAL_HDMI_STATE       "ChangedHDMI"
157 #define SIGNAL_HDCP_STATE       "ChangedHDCP"
158 #define SIGNAL_HDMI_AUDIO_STATE "ChangedHDMIAudio"
159
160 #define METHOD_FACTORY_MODE             "factorymode"
161 #define VCONFKEY_SYSMAN_FACTORY_MODE    "memory/sysman/factory_mode"
162
163 #define HDCP_HDMI_VALUE(HDCP, HDMI)     ((HDCP << 1) | HDMI)
164
165 #define METHOD_GET_CRADLE       "GetCradle"
166 #define SIGNAL_CRADLE_STATE     "ChangedCradle"
167
168 struct ticker_data {
169         char *name;
170         int type;
171 };
172
173 struct popup_data {
174         char *name;
175         char *key;
176         char *value;
177 };
178
179 struct siop_data {
180         int siop;
181         int rear;
182 };
183
184 static int ss_flags = 0;
185
186 static int input_device_number;
187
188 /* Uevent */
189 static struct udev *udev = NULL;
190 /* Kernel Uevent */
191 static struct udev_monitor *mon = NULL;
192 static Ecore_Fd_Handler *ufdh = NULL;
193 static int ufd = -1;
194 /* Udev Uevent */
195 static struct udev_monitor *mon_udev = NULL;
196 static Ecore_Fd_Handler *ufdh_udev = NULL;
197 static int ufd_udev = -1;
198
199 static dd_list *opt_uevent_list = NULL;
200 static dd_list *opt_kernel_uevent_list = NULL;
201 static int hdmi_status = 0;
202
203 static int factory_mode = 0;
204
205 enum udev_subsystem_type {
206         UDEV_HALL_IC,
207         UDEV_INPUT,
208         UDEV_LCD_EVENT,
209         UDEV_PLATFORM,
210         UDEV_POWER,
211         UDEV_SWITCH,
212 };
213
214 static const struct udev_subsystem {
215         const enum udev_subsystem_type type;
216         const char *str;
217         const char *devtype;
218 } udev_subsystems[] = {
219         { UDEV_HALL_IC,          HALL_IC_SUBSYSTEM, NULL},
220         { UDEV_INPUT,            INPUT_SUBSYSTEM, NULL },
221         { UDEV_LCD_EVENT,        LCD_EVENT_SUBSYSTEM, NULL },
222         { UDEV_PLATFORM,         PLATFORM_SUBSYSTEM, NULL },
223         { UDEV_POWER,            POWER_SUBSYSTEM, NULL},
224         { UDEV_SWITCH,           SWITCH_SUBSYSTEM, NULL },
225 };
226
227 static struct extcon_device {
228         const enum extcon_type type;
229         const char *str;
230         int fd;
231         int count;
232 } extcon_devices[] = {
233         { EXTCON_TA, "/csa/factory/batt_cable_count", 0, 0},
234         { EXTCON_EARJACK, "/csa/factory/earjack_count", 0, 0},
235 };
236
237 extern int battery_power_off_act(void *data);
238 extern int battery_charge_err_act(void *data);
239
240 int extcon_set_count(int index)
241 {
242         int r;
243         int ret = 0;
244         char buf[BUFF_MAX];
245
246         extcon_devices[index].count++;
247
248         if (extcon_devices[index].fd < 0) {
249                 _E("cannot open file(%s)", extcon_devices[index].str);
250                 return -ENOENT;
251         }
252         lseek(extcon_devices[index].fd, 0, SEEK_SET);
253         _I("ext(%d) count %d", index, extcon_devices[index].count);
254         snprintf(buf, sizeof(buf), "%d", extcon_devices[index].count);
255
256         r = write(extcon_devices[index].fd, buf, strlen(buf));
257         if (r < 0)
258                 ret = -EIO;
259         return ret;
260 }
261
262 static int extcon_get_count(int index)
263 {
264         int fd;
265         int r;
266         int ret = 0;
267         char buf[BUFF_MAX];
268
269         fd = open(extcon_devices[index].str, O_RDWR);
270         if (fd < 0)
271                 return -ENOENT;
272
273         r = read(fd, buf, BUFF_MAX);
274         if ((r >= 0) && (r < BUFF_MAX))
275                 buf[r] = '\0';
276         else
277                 ret = -EIO;
278
279         if (ret != 0) {
280                 close(fd);
281                 return ret;
282         }
283         extcon_devices[index].fd = fd;
284         extcon_devices[index].count = atoi(buf);
285         _I("get extcon(%d:%x) count %d",
286                 index, extcon_devices[index].fd, extcon_devices[index].count);
287
288         return ret;
289 }
290
291 static int extcon_create_count(int index)
292 {
293         int fd;
294         int r;
295         int ret = 0;
296         char buf[BUFF_MAX];
297         fd = open(extcon_devices[index].str, O_RDWR | O_CREAT, 0644);
298         if (fd < 0) {
299                 _E("cannot open file(%s)", extcon_devices[index].str);
300                 return -ENOENT;
301         }
302         snprintf(buf, sizeof(buf), "%d", extcon_devices[index].count);
303         r = write(fd, buf, strlen(buf));
304         if (r < 0)
305                 ret = -EIO;
306
307         if (ret != 0) {
308                 close(fd);
309                 _E("cannot write file(%s)", extcon_devices[index].str);
310                 return ret;
311         }
312         extcon_devices[index].fd = fd;
313         _I("create extcon(%d:%x) %s",
314                 index, extcon_devices[index].fd, extcon_devices[index].str);
315         return ret;
316 }
317
318 static int extcon_count_init(void)
319 {
320         int i;
321         int ret = 0;
322         for (i = 0; i < ARRAY_SIZE(extcon_devices); i++) {
323                 if (extcon_get_count(i) >= 0)
324                         continue;
325                 ret = extcon_create_count(i);
326                 if (ret < 0)
327                         break;
328         }
329         return ret;
330 }
331
332 int get_usb_state_direct(void)
333 {
334         FILE *fp;
335         char str[2];
336         int state;
337         char *path;
338
339         if (access(USB_STATE_PLATFORM_PATH, F_OK) == 0)
340                 path = USB_STATE_PLATFORM_PATH;
341         else if (access(USB_STATE_SWITCH_PATH, F_OK) == 0)
342                 path = USB_STATE_SWITCH_PATH;
343         else {
344                 _E("Cannot get direct path");
345                 return -ENOENT;
346         }
347
348         fp = fopen(path, "r");
349         if (!fp) {
350                 _E("Cannot open jack node");
351                 return -ENOMEM;
352         }
353
354         if (!fgets(str, sizeof(str), fp)) {
355                 _E("cannot get string from jack node");
356                 fclose(fp);
357                 return -ENOMEM;
358         }
359
360         fclose(fp);
361
362         return atoi(str);
363 }
364
365 static void usb_chgdet_cb(void *data)
366 {
367         int val = -1;
368         int ret = 0;
369         char params[BUFF_MAX];
370
371         if (data == NULL)
372                 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &val);
373         else
374                 val = *(int *)data;
375         if (ret == 0) {
376                 if (val < 0)
377                         val = get_usb_state_direct();
378
379                 _I("jack - usb changed %d",val);
380                 check_lowbat_charge_device(val);
381                 if (val==1) {
382                         battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
383                         _D("usb device notification");
384                 }
385                 usb_state_changed(val);
386         } else {
387                 _E("fail to get usb_online status");
388         }
389 }
390
391 static void show_ticker_notification(char *text, int queue)
392 {
393         struct ticker_data t_data;
394         static const struct device_ops *ticker = NULL;
395
396         FIND_DEVICE_VOID(ticker, "ticker");
397         t_data.name = text;
398         t_data.type = queue;
399         if (ticker->init)
400                 ticker->init(&t_data);
401 }
402
403 static void launch_cradle(int val)
404 {
405         struct popup_data *params;
406         static const struct device_ops *apps = NULL;
407
408         FIND_DEVICE_VOID(apps, "apps");
409
410         params = malloc(sizeof(struct popup_data));
411         if (params == NULL) {
412                 _E("Malloc failed");
413                 return;
414         }
415         params->name = LAUNCH_APP;
416         params->key = DESK_DOCK;
417         _I("%s %s %x", params->name, params->key, params);
418         if (val == 0) {
419                 if (apps->exit)
420                         apps->exit((void *)params);
421         } else {
422                 show_ticker_notification(DOCK_CONNECTED, 0);
423                 if (apps->init)
424                         apps->init((void *)params);
425         }
426         free(params);
427
428 }
429
430 static int display_changed(void *data)
431 {
432         enum state_t state = (enum state_t)data;
433         int ret, cradle = 0;
434
435         if (battery.charge_now == CHARGER_ABNORMAL && battery.health == HEALTH_BAD) {
436                 pm_lock_internal(INTERNAL_LOCK_POPUP, LCD_DIM, STAY_CUR_STATE, 0);
437                 return 0;
438         }
439
440         if (state != S_NORMAL)
441                 return 0;
442
443         ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
444         if (ret >= 0 && cradle == DOCK_SOUND) {
445                 pm_lock_internal(getpid(), LCD_DIM, STAY_CUR_STATE, 0);
446                 _I("sound dock is connected! dim lock is on.");
447         }
448         if (hdmi_status) {
449                 pm_lock_internal(getpid(), LCD_DIM, STAY_CUR_STATE, 0);
450                 _I("hdmi is connected! dim lock is on.");
451         }
452         return 0;
453 }
454
455 static void cradle_send_broadcast(int status)
456 {
457         static int old = 0;
458         char *arr[1];
459         char str_status[32];
460
461         if (old == status)
462                 return;
463
464         _I("broadcast cradle status %d", status);
465         old = status;
466         snprintf(str_status, sizeof(str_status), "%d", status);
467         arr[0] = str_status;
468
469         broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
470                         SIGNAL_CRADLE_STATE, "i", arr);
471 }
472
473 static int cradle_cb(void *data)
474 {
475         static int old = 0;
476         int val = 0;
477         int ret = 0;
478
479         if (data == NULL)
480                 return old;
481
482         val = *(int *)data;
483
484         if (old == val)
485                 return old;
486
487         old = val;
488         cradle_send_broadcast(old);
489         return old;
490 }
491
492 static void cradle_chgdet_cb(void *data)
493 {
494         int val;
495         int ret = 0;
496
497         pm_change_internal(getpid(), LCD_NORMAL);
498
499         if (data)
500                 val = *(int *)data;
501         else {
502                 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_CRADLE_ONLINE, &val);
503                 if (ret != 0) {
504                         _E("failed to get status");
505                         return;
506                 }
507         }
508
509         _I("jack - cradle changed %d", val);
510         cradle_cb((void *)&val);
511         if (vconf_set_int(VCONFKEY_SYSMAN_CRADLE_STATUS, val) != 0) {
512                 _E("failed to set vconf status");
513                 return;
514         }
515
516         if (val == DOCK_SOUND)
517                 pm_lock_internal(getpid(), LCD_DIM, STAY_CUR_STATE, 0);
518         else if (val == DOCK_NONE)
519                 pm_unlock_internal(getpid(), LCD_DIM, PM_SLEEP_MARGIN);
520
521         launch_cradle(val);
522 }
523
524 void sync_cradle_status(void)
525 {
526         int val;
527         int status;
528         if ((device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_CRADLE_ONLINE, &val) != 0) ||
529             vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &status) != 0)
530                 return;
531         if ((val != 0 && status == 0) || (val == 0 && status != 0))
532                 cradle_chgdet_cb(NULL);
533 }
534
535 static void earkey_chgdet_cb(void *data)
536 {
537         int val;
538         int ret = 0;
539
540         if (data)
541                 val = *(int *)data;
542         else {
543                 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARKEY_ONLINE, &val);
544                 if (ret != 0) {
545                         _E("failed to get status");
546                         return;
547                 }
548         }
549         _I("jack - earkey changed %d", val);
550         vconf_set_int(VCONFKEY_SYSMAN_EARJACKKEY, val);
551 }
552
553 static void tvout_chgdet_cb(void *data)
554 {
555         _I("jack - tvout changed");
556         pm_change_internal(getpid(), LCD_NORMAL);
557 }
558
559 static void hdcp_hdmi_send_broadcast(int status)
560 {
561         static int old = 0;
562         char *arr[1];
563         char str_status[32];
564
565         if (old == status)
566                 return;
567
568         _I("broadcast hdmi status %d", status);
569         old = status;
570         snprintf(str_status, sizeof(str_status), "%d", status);
571         arr[0] = str_status;
572
573         broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
574                         SIGNAL_HDMI_STATE, "i", arr);
575 }
576
577 static int hdcp_hdmi_cb(void *data)
578 {
579         static int old = 0;
580         int val = 0;
581         int ret = 0;
582
583         if (data == NULL)
584                 return old;
585
586         val = *(int *)data;
587         val = HDCP_HDMI_VALUE(val, hdmi_status);
588
589         if (old == val)
590                 return old;
591
592         old = val;
593         hdcp_hdmi_send_broadcast(old);
594         return old;
595 }
596
597 static int hdmi_cec_execute(void *data)
598 {
599         static const struct device_ops *ops = NULL;
600
601         FIND_DEVICE_INT(ops, "hdmi-cec");
602
603         return ops->execute(data);
604 }
605
606 static void hdmi_chgdet_cb(void *data)
607 {
608         int val;
609         int ret = 0;
610
611         pm_change_internal(getpid(), LCD_NORMAL);
612         if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_HDMI_SUPPORT, &val) == 0) {
613                 if (val!=1) {
614                         _I("target is not support HDMI");
615                         vconf_set_int(VCONFKEY_SYSMAN_HDMI, HDMI_NOT_SUPPORTED);
616                         return;
617                 }
618         }
619
620         if (data)
621                 val = *(int *)data;
622         else {
623                 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_HDMI_ONLINE, &val);
624                 if (ret != 0) {
625                         _E("failed to get status");
626                         return;
627                 }
628         }
629
630         _I("jack - hdmi changed %d", val);
631         vconf_set_int(VCONFKEY_SYSMAN_HDMI, val);
632         hdmi_status = val;
633         device_notify(DEVICE_NOTIFIER_HDMI, (void *)val);
634
635         if(val == 1) {
636                 pm_lock_internal(INTERNAL_LOCK_HDMI, LCD_DIM, STAY_CUR_STATE, 0);
637                 show_ticker_notification(HDMI_CONNECTED, 0);
638         } else {
639                 show_ticker_notification(HDMI_DISCONNECTED, 0);
640                 pm_unlock_internal(INTERNAL_LOCK_HDMI, LCD_DIM, PM_SLEEP_MARGIN);
641         }
642         hdmi_cec_execute((void *)val);
643 }
644
645 static void hdcp_send_broadcast(int status)
646 {
647         static int old = 0;
648         char *arr[1];
649         char str_status[32];
650
651         if (old == status)
652                 return;
653
654         _D("broadcast hdcp status %d", status);
655         old = status;
656         snprintf(str_status, sizeof(str_status), "%d", status);
657         arr[0] = str_status;
658
659         broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
660                         SIGNAL_HDCP_STATE, "i", arr);
661 }
662
663 static int hdcp_chgdet_cb(void *data)
664 {
665         static int old = 0;
666         int val = 0;
667
668         if (data == NULL)
669                 return old;
670
671         val = *(int *)data;
672         if (old == val)
673                 return old;
674
675         old = val;
676         hdcp_send_broadcast(old);
677         return old;
678 }
679
680 static void hdmi_audio_send_broadcast(int status)
681 {
682         static int old = 0;
683         char *arr[1];
684         char str_status[32];
685
686         if (old == status)
687                 return;
688
689         _D("broadcast hdmi audio status %d", status);
690         old = status;
691         snprintf(str_status, sizeof(str_status), "%d", status);
692         arr[0] = str_status;
693
694         broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
695                         SIGNAL_HDMI_AUDIO_STATE, "i", arr);
696 }
697
698 static int hdmi_audio_chgdet_cb(void *data)
699 {
700         static int old = 0;
701         int val = 0;
702
703         if (data == NULL)
704                 return old;
705
706         val = *(int *)data;
707         if (old == val)
708                 return old;
709
710         old = val;
711         hdmi_audio_send_broadcast(old);
712         return old;
713 }
714
715 static void keyboard_chgdet_cb(void *data)
716 {
717         int val = -1;
718         int ret = 0;
719
720         if (data)
721                 val = *(int *)data;
722         else {
723                 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_KEYBOARD_ONLINE, &val);
724                 if (ret != 0) {
725                         _E("failed to get status");
726                         vconf_set_int(VCONFKEY_SYSMAN_SLIDING_KEYBOARD, VCONFKEY_SYSMAN_SLIDING_KEYBOARD_NOT_SUPPORTED);
727                         return;
728                 }
729         }
730         _I("jack - keyboard changed %d", val);
731         if(val != 1)
732                 val = 0;
733         vconf_set_int(VCONFKEY_SYSMAN_SLIDING_KEYBOARD, val);
734 }
735
736 static void ums_unmount_cb(void *data)
737 {
738         umount(MOVINAND_MOUNT_POINT);
739 }
740
741 #ifdef ENABLE_EDBUS_USE
742 static void cb_xxxxx_signaled(void *data, DBusMessage * msg)
743 {
744         char *args;
745         DBusError err;
746
747         dbus_error_init(&err);
748         if (dbus_message_get_args
749             (msg, &err, DBUS_TYPE_STRING, &args, DBUS_TYPE_INVALID)) {
750                 if (!strcmp(args, "action")) ;  /* action */
751         }
752
753         return;
754 }
755 #endif                          /* ENABLE_EDBUS_USE */
756
757 static void check_capacity_status(const char *env_value)
758 {
759         if (env_value == NULL)
760                 return;
761         battery.capacity = atoi(env_value);
762 }
763
764 static void check_charge_status(const char *env_value)
765 {
766         if (env_value == NULL)
767                 return;
768         if (strncmp(env_value, CHARGEFULL_NAME , CHARGEFULL_NAME_LEN) == 0) {
769                 battery.charge_full = CHARGING_FULL;
770                 battery.charge_now = CHARGER_DISCHARGING;
771         } else if (strncmp(env_value, CHARGENOW_NAME, CHARGENOW_NAME_LEN) == 0) {
772                 battery.charge_full = CHARGING_NOT_FULL;
773                 battery.charge_now = CHARGER_CHARGING;
774         } else if (strncmp(env_value, DISCHARGE_NAME, DISCHARGE_NAME_LEN) == 0) {
775                 battery.charge_full = CHARGING_NOT_FULL;
776                 battery.charge_now = CHARGER_DISCHARGING;
777         } else if (strncmp(env_value, NOTCHARGE_NAME, NOTCHARGE_NAME_LEN) == 0) {
778                 battery.charge_full = CHARGING_NOT_FULL;
779                 battery.charge_now = CHARGER_ABNORMAL;
780         } else {
781                 battery.charge_full = CHARGING_NOT_FULL;
782                 battery.charge_now = CHARGER_DISCHARGING;
783         }
784 }
785
786 static void check_health_status(const char *env_value)
787 {
788         if (env_value == NULL) {
789                 battery.health = HEALTH_GOOD;
790                 battery.temp = TEMP_LOW;
791                 battery.ovp = OVP_NORMAL;
792                 return;
793         }
794         if (strncmp(env_value, OVERHEAT_NAME, OVERHEAT_NAME_LEN) == 0) {
795                 battery.health = HEALTH_BAD;
796                 battery.temp = TEMP_HIGH;
797                 battery.ovp = OVP_NORMAL;
798         } else if (strncmp(env_value, TEMPCOLD_NAME, TEMPCOLD_NAME_LEN) == 0) {
799                 battery.health = HEALTH_BAD;
800                 battery.temp = TEMP_LOW;
801                 battery.ovp = OVP_NORMAL;
802         } else if (strncmp(env_value, OVERVOLT_NAME, OVERVOLT_NAME_LEN) == 0) {
803                 battery.health = HEALTH_GOOD;
804                 battery.temp = TEMP_LOW;
805                 battery.ovp = OVP_ABNORMAL;
806         } else {
807                 battery.health = HEALTH_GOOD;
808                 battery.temp = TEMP_LOW;
809                 battery.ovp = OVP_NORMAL;
810         }
811 }
812
813 static void check_online_status(const char *env_value)
814 {
815         if (env_value == NULL)
816                 return;
817         battery.online = atoi(env_value);
818 }
819
820 static void check_present_status(const char *env_value)
821 {
822         if (env_value == NULL) {
823                 battery.present = PRESENT_NORMAL;
824                 return;
825         }
826         battery.present = atoi(env_value);
827 }
828
829 static int earjack_execute(void *data)
830 {
831         static const struct device_ops *ops = NULL;
832
833         FIND_DEVICE_INT(ops, "earjack");
834
835         return ops->execute(data);
836 }
837
838 static int hall_ic_execute(void)
839 {
840         static const struct device_ops *ops = NULL;
841
842         FIND_DEVICE_INT(ops, HALL_IC_NAME);
843
844         return ops->execute(NULL);
845 }
846
847 static int siop_execute(const char *siop, const char *rear)
848 {
849         static const struct device_ops *ops = NULL;
850         struct siop_data params;
851
852         FIND_DEVICE_INT(ops, PROC_OPS_NAME);
853
854         if (!siop)
855                 params.siop = 0;
856         else
857                 params.siop = atoi(siop);
858         if (!rear)
859                 params.rear = 0;
860         else
861                 params.rear = atoi(rear);
862         return ops->execute((void *)&params);
863 }
864
865 static int changed_device(const char *name, const char *value)
866 {
867         int val = 0;
868         int *state = NULL;
869         int i;
870
871         if (!name)
872                 goto out;
873
874         if (value) {
875                 val = atoi(value);
876                 state = &val;
877         }
878
879         if (strncmp(name, USB_NAME, USB_NAME_LEN) == 0)
880                 usb_chgdet_cb((void *)state);
881         else if (strncmp(name, EARJACK_NAME, EARJACK_NAME_LEN) == 0)
882                 earjack_execute((void *)state);
883         else if (strncmp(name, EARKEY_NAME, EARKEY_NAME_LEN) == 0)
884                 earkey_chgdet_cb((void *)state);
885         else if (strncmp(name, TVOUT_NAME, TVOUT_NAME_LEN) == 0)
886                 tvout_chgdet_cb((void *)state);
887         else if (strncmp(name, HDMI_NAME, HDMI_NAME_LEN) == 0)
888                 hdmi_chgdet_cb((void *)state);
889         else if (strncmp(name, HDCP_NAME, HDCP_NAME_LEN) == 0) {
890                 hdcp_chgdet_cb((void *)state);
891                 hdcp_hdmi_cb((void *)state);
892         }
893         else if (strncmp(name, HDMI_AUDIO_NAME, HDMI_AUDIO_LEN) == 0)
894                 hdmi_audio_chgdet_cb((void *)state);
895         else if (strncmp(name, CRADLE_NAME, CRADLE_NAME_LEN) == 0)
896                 cradle_chgdet_cb((void *)state);
897         else if (strncmp(name, KEYBOARD_NAME, KEYBOARD_NAME_LEN) == 0)
898                 keyboard_chgdet_cb((void *)state);
899         else if (strncmp(name, POWER_SUBSYSTEM, POWER_SUPPLY_NAME_LEN) == 0)
900                 power_supply((void *)state);
901 out:
902         return 0;
903 }
904
905 static int booting_done(void *data)
906 {
907         static int done = 0;
908         int ret;
909         int val;
910
911         if (data == NULL)
912                 return done;
913         done = (int)data;
914         if (done == 0)
915                 return done;
916
917         _I("booting done");
918
919         power_supply_timer_stop();
920         power_supply_init(NULL);
921
922         /* set initial state for devices */
923         input_device_number = 0;
924         cradle_chgdet_cb(NULL);
925         keyboard_chgdet_cb(NULL);
926         hdmi_chgdet_cb(NULL);
927
928         ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &val);
929         if (ret == 0 && val != 0)
930                 launch_cradle(val);
931         return done;
932 }
933
934 static Eina_Bool uevent_kernel_control_cb(void *data, Ecore_Fd_Handler *fd_handler)
935 {
936         struct udev_device *dev = NULL;
937         struct udev_list_entry *list_entry = NULL;
938         const char *subsystem = NULL;
939         const char *env_name = NULL;
940         const char *env_value = NULL;
941         const char *devpath;
942         const char *devnode;
943         const char *action;
944         const char *siop_level;
945         const char *rear_level;
946         dd_list *l;
947         void *l_data;
948         struct uevent_handler *uh;
949         int ret = -1;
950         int i, len;
951
952         if ((dev = udev_monitor_receive_device(mon)) == NULL)
953                 return EINA_TRUE;
954
955         subsystem = udev_device_get_subsystem(dev);
956
957         for (i = 0; i < ARRAY_SIZE(udev_subsystems); i++) {
958                 len = strlen(udev_subsystems[i].str);
959                 if (!strncmp(subsystem, udev_subsystems[i].str, len))
960                         break;
961         }
962
963         if (i >= ARRAY_SIZE(udev_subsystems))
964                 goto out;
965
966         devpath = udev_device_get_devpath(dev);
967
968         switch (udev_subsystems[i].type) {
969         case UDEV_HALL_IC:
970                 if (!strncmp(devpath, HALL_IC_PATH, strlen(HALL_IC_PATH))) {
971                         hall_ic_execute();
972                         goto out;
973                 }
974                 break;
975         case UDEV_INPUT:
976                 /* check new input device */
977                 if (!fnmatch(INPUT_PATH, devpath, 0)) {
978                         action = udev_device_get_action(dev);
979                         devnode = udev_device_get_devnode(dev);
980                         if (!strcmp(action, UDEV_ADD))
981                                 device_notify(DEVICE_NOTIFIER_INPUT_ADD, (void *)devnode);
982                         else if (!strcmp(action, UDEV_REMOVE))
983                                 device_notify(DEVICE_NOTIFIER_INPUT_REMOVE, (void *)devnode);
984                         goto out;
985                 }
986                 break;
987         case UDEV_LCD_EVENT:
988                 /* check new esd device */
989                 if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
990                         action = udev_device_get_action(dev);
991                         if (!strcmp(action, UDEV_CHANGE))
992                                 device_notify(DEVICE_NOTIFIER_LCD_ESD, "ESD");
993                         goto out;
994                 }
995                 break;
996         case UDEV_SWITCH:
997                 env_name = udev_device_get_property_value(dev, "SWITCH_NAME");
998                 env_value = udev_device_get_property_value(dev, "SWITCH_STATE");
999                 changed_device(env_name, env_value);
1000                 break;
1001         case UDEV_PLATFORM:
1002                 if (!fnmatch(THERMISTOR_PATH, devpath, 0)) {
1003                         siop_level = udev_device_get_property_value(dev, "TEMPERATURE");
1004                         rear_level = udev_device_get_property_value(dev, "REAR_TEMPERATURE");
1005                         siop_execute(siop_level, rear_level);
1006                         goto out;
1007                 }
1008
1009                 env_value = udev_device_get_property_value(dev, ENV_FILTER);
1010                 if (!env_value)
1011                         break;
1012                 changed_device(env_value, NULL);
1013                 break;
1014         case UDEV_POWER:
1015                 udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(dev)) {
1016                         env_name = udev_list_entry_get_name(list_entry);
1017                         if (env_name == NULL)
1018                                 continue;
1019                         if (strncmp(env_name, CHARGE_NAME, CHARGE_NAME_LEN) == 0) {
1020                                 env_value = udev_list_entry_get_value(list_entry);
1021                                 if (env_value == NULL)
1022                                         continue;
1023                                 if (strncmp(env_value, BATTERY_NAME, BATTERY_NAME_LEN) == 0) {
1024                                         ret = 0;
1025                                         break;
1026                                 }
1027                         }
1028                 }
1029                 if (ret != 0)
1030                         goto out;
1031                 env_value = udev_device_get_property_value(dev, CHARGE_STATUS);
1032                 check_charge_status(env_value);
1033                 env_value = udev_device_get_property_value(dev, CHARGE_ONLINE);
1034                 check_online_status(env_value);
1035                 env_value = udev_device_get_property_value(dev, CHARGE_HEALTH);
1036                 check_health_status(env_value);
1037                 env_value = udev_device_get_property_value(dev, CHARGE_PRESENT);
1038                 check_present_status(env_value);
1039                 env_value = udev_device_get_property_value(dev, CAPACITY);
1040                 check_capacity_status(env_value);
1041                 ret = booting_done(NULL);
1042                 if (ret)
1043                         battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
1044                 if (env_value)
1045                         changed_device(subsystem, env_value);
1046                 else
1047                         changed_device(subsystem, NULL);
1048                 break;
1049         }
1050
1051 out:
1052         DD_LIST_FOREACH(opt_kernel_uevent_list, l, l_data) {
1053                 uh = (struct uevent_handler *)l_data;
1054                 if (strncmp(subsystem, uh->subsystem, strlen(uh->subsystem)))
1055                         continue;
1056                 uh->uevent_func(dev);
1057         }
1058
1059         udev_device_unref(dev);
1060         return EINA_TRUE;
1061 }
1062
1063 static Eina_Bool uevent_udev_control_cb(void *data, Ecore_Fd_Handler *fd_handler)
1064 {
1065         struct udev_device *dev = NULL;
1066         dd_list *l;
1067         void *l_data;
1068         struct uevent_handler *uh;
1069         const char *subsystem = NULL;
1070
1071         dev = udev_monitor_receive_device(mon_udev);
1072         if (!dev)
1073                 return EINA_TRUE;
1074
1075         subsystem = udev_device_get_subsystem(dev);
1076         if (!subsystem) {
1077                 _E("Failed to get subsystem from uevent");
1078                 goto out;
1079         }
1080
1081         DD_LIST_FOREACH(opt_uevent_list, l, l_data) {
1082                 uh = (struct uevent_handler *)l_data;
1083                 if (strncmp(subsystem, uh->subsystem, strlen(uh->subsystem)))
1084                         continue;
1085                 uh->uevent_func(dev);
1086         }
1087
1088 out:
1089         udev_device_unref(dev);
1090         return EINA_TRUE;
1091 }
1092
1093 static int uevent_kernel_control_stop(void)
1094 {
1095         struct udev_device *dev = NULL;
1096
1097         if (ufdh) {
1098                 ecore_main_fd_handler_del(ufdh);
1099                 ufdh = NULL;
1100         }
1101         if (ufd >= 0) {
1102                 close(ufd);
1103                 ufd = -1;
1104         }
1105         if (mon) {
1106                 dev = udev_monitor_receive_device(mon);
1107                 if (dev) {
1108                         udev_device_unref(dev);
1109                         dev = NULL;
1110                 }
1111                 udev_monitor_unref(mon);
1112                 mon = NULL;
1113         }
1114         if (udev && !mon_udev) {
1115                 udev_unref(udev);
1116                 udev = NULL;
1117         }
1118         return 0;
1119 }
1120
1121 static int uevent_udev_control_stop(void)
1122 {
1123         struct udev_device *dev = NULL;
1124
1125         if (ufdh_udev) {
1126                 ecore_main_fd_handler_del(ufdh_udev);
1127                 ufdh_udev = NULL;
1128         }
1129         if (ufd_udev >= 0) {
1130                 close(ufd_udev);
1131                 ufd_udev = -1;
1132         }
1133         if (mon_udev) {
1134                 dev = udev_monitor_receive_device(mon_udev);
1135                 if (dev) {
1136                         udev_device_unref(dev);
1137                         dev = NULL;
1138                 }
1139                 udev_monitor_unref(mon_udev);
1140                 mon_udev = NULL;
1141         }
1142         if (udev && !mon) {
1143                 udev_unref(udev);
1144                 udev = NULL;
1145         }
1146         return 0;
1147 }
1148
1149 static int uevent_kernel_control_start(void)
1150 {
1151         int i, ret;
1152
1153         if (udev && mon) {
1154                 _E("uevent control routine is alreay started");
1155                 return -EINVAL;
1156         }
1157
1158         if (!udev) {
1159                 udev = udev_new();
1160                 if (!udev) {
1161                         _E("error create udev");
1162                         return -EINVAL;
1163                 }
1164         }
1165
1166         mon = udev_monitor_new_from_netlink(udev, UDEV);
1167         if (mon == NULL) {
1168                 _E("error udev_monitor create");
1169                 goto stop;
1170         }
1171
1172         if (udev_monitor_set_receive_buffer_size(mon, UDEV_MONITOR_SIZE) != 0) {
1173                 _E("fail to set receive buffer size");
1174                 goto stop;
1175         }
1176
1177         for (i = 0; i < ARRAY_SIZE(udev_subsystems); i++) {
1178                 ret = udev_monitor_filter_add_match_subsystem_devtype(mon,
1179                             udev_subsystems[i].str, udev_subsystems[i].devtype);
1180                 if (ret < 0) {
1181                         _E("error apply subsystem filter");
1182                         goto stop;
1183                 }
1184         }
1185
1186         ret = udev_monitor_filter_update(mon);
1187         if (ret < 0)
1188                 _E("error udev_monitor_filter_update");
1189
1190         ufd = udev_monitor_get_fd(mon);
1191         if (ufd == -1) {
1192                 _E("error udev_monitor_get_fd");
1193                 goto stop;
1194         }
1195
1196         ufdh = ecore_main_fd_handler_add(ufd, ECORE_FD_READ,
1197                         uevent_kernel_control_cb, NULL, NULL, NULL);
1198         if (!ufdh) {
1199                 _E("error ecore_main_fd_handler_add");
1200                 goto stop;
1201         }
1202
1203         if (udev_monitor_enable_receiving(mon) < 0) {
1204                 _E("error unable to subscribe to udev events");
1205                 goto stop;
1206         }
1207
1208         return 0;
1209 stop:
1210         uevent_kernel_control_stop();
1211         return -EINVAL;
1212
1213 }
1214
1215 static int uevent_udev_control_start(void)
1216 {
1217         int i, ret;
1218
1219         if (udev && mon_udev) {
1220                 _E("uevent control routine is alreay started");
1221                 return 0;
1222         }
1223
1224         if (!udev) {
1225                 udev = udev_new();
1226                 if (!udev) {
1227                         _E("error create udev");
1228                         return -EINVAL;
1229                 }
1230         }
1231
1232         mon_udev = udev_monitor_new_from_netlink(udev, "udev");
1233         if (mon_udev == NULL) {
1234                 _E("error udev_monitor create");
1235                 goto stop;
1236         }
1237
1238         if (udev_monitor_set_receive_buffer_size(mon_udev, UDEV_MONITOR_SIZE_LARGE) != 0) {
1239                 _E("fail to set receive buffer size");
1240                 goto stop;
1241         }
1242
1243         ufd_udev = udev_monitor_get_fd(mon_udev);
1244         if (ufd_udev == -1) {
1245                 _E("error udev_monitor_get_fd");
1246                 goto stop;
1247         }
1248
1249         ufdh_udev = ecore_main_fd_handler_add(ufd_udev, ECORE_FD_READ,
1250                         uevent_udev_control_cb, NULL, NULL, NULL);
1251         if (!ufdh_udev) {
1252                 _E("error ecore_main_fd_handler_add");
1253                 goto stop;
1254         }
1255
1256         if (udev_monitor_enable_receiving(mon_udev) < 0) {
1257                 _E("error unable to subscribe to udev events");
1258                 goto stop;
1259         }
1260
1261         return 0;
1262 stop:
1263         uevent_udev_control_stop();
1264         return -EINVAL;
1265 }
1266
1267 int register_uevent_control(const struct uevent_handler *uh)
1268 {
1269         int ret;
1270
1271         if (!mon || !uh)
1272                 return -EINVAL;
1273
1274         ret = udev_monitor_filter_add_match_subsystem_devtype(mon_udev,
1275                         uh->subsystem, NULL);
1276         if (ret < 0) {
1277                 _E("FAIL: udev_monitor_filter_add_match_subsystem_devtype()");
1278                 return -ENOMEM;
1279         }
1280
1281         ret = udev_monitor_filter_update(mon_udev);
1282         if (ret < 0)
1283                 _E("error udev_monitor_filter_update");
1284
1285         DD_LIST_APPEND(opt_uevent_list, uh);
1286
1287         return 0;
1288 }
1289
1290 void unregister_uevent_control(const struct uevent_handler *uh)
1291 {
1292         dd_list *l;
1293         void *data;
1294         struct uevent_handler *handler;
1295
1296         DD_LIST_FOREACH(opt_uevent_list, l, data) {
1297                 handler = (struct uevent_handler *)data;
1298                 if (strncmp(handler->subsystem, uh->subsystem, strlen(uh->subsystem)))
1299                         continue;
1300                 if (handler->uevent_func != uh->uevent_func)
1301                         continue;
1302
1303                 DD_LIST_REMOVE(opt_uevent_list, handler);
1304                 break;
1305         }
1306 }
1307
1308 int register_kernel_uevent_control(const struct uevent_handler *uh)
1309 {
1310         int ret;
1311
1312         if (!mon || !uh)
1313                 return -EINVAL;
1314
1315         ret = udev_monitor_filter_add_match_subsystem_devtype(mon,
1316                         uh->subsystem, NULL);
1317         if (ret < 0) {
1318                 _E("FAIL: udev_monitor_filter_add_match_subsystem_devtype()");
1319                 return -ENOMEM;
1320         }
1321
1322         ret = udev_monitor_filter_update(mon);
1323         if (ret < 0)
1324                 _E("error udev_monitor_filter_update");
1325
1326         DD_LIST_APPEND(opt_kernel_uevent_list, uh);
1327
1328         return 0;
1329 }
1330
1331 void unregister_kernel_uevent_control(const struct uevent_handler *uh)
1332 {
1333         dd_list *l;
1334         void *data;
1335         struct uevent_handler *handler;
1336
1337         DD_LIST_FOREACH(opt_kernel_uevent_list, l, data) {
1338                 handler = (struct uevent_handler *)data;
1339                 if (strncmp(handler->subsystem, uh->subsystem, strlen(uh->subsystem)))
1340                         continue;
1341                 if (handler->uevent_func != uh->uevent_func)
1342                         continue;
1343
1344                 DD_LIST_REMOVE(opt_kernel_uevent_list, data);
1345                 break;
1346         }
1347 }
1348
1349 int uevent_udev_get_path(const char *subsystem, dd_list **list)
1350 {
1351         struct udev_enumerate *enumerate = NULL;
1352         struct udev_list_entry *devices, *dev_list_entry;
1353         int ret;
1354
1355         if (!udev) {
1356                 udev = udev_new();
1357                 if (!udev) {
1358                         _E("error create udev");
1359                         return -EIO;
1360                 }
1361         }
1362
1363         enumerate = udev_enumerate_new(udev);
1364         if (!enumerate)
1365                 return -EIO;
1366
1367         ret = udev_enumerate_add_match_subsystem(enumerate, subsystem);
1368         if (ret < 0)
1369                 return -EIO;
1370
1371         ret = udev_enumerate_scan_devices(enumerate);
1372         if (ret < 0)
1373                 return -EIO;
1374
1375         devices = udev_enumerate_get_list_entry(enumerate);
1376
1377         udev_list_entry_foreach(dev_list_entry, devices) {
1378                 const char *path;
1379                 path = udev_list_entry_get_name(dev_list_entry);
1380                 _D("subsystem : %s, path : %s", subsystem, path);
1381                 DD_LIST_APPEND(*list, (void*)path);
1382         }
1383
1384         return 0;
1385 }
1386
1387 static DBusMessage *dbus_cradle_handler(E_DBus_Object *obj, DBusMessage *msg)
1388 {
1389         DBusMessageIter iter;
1390         DBusMessage *reply;
1391         int ret;
1392
1393         ret = cradle_cb(NULL);
1394         _I("cradle %d", ret);
1395
1396         reply = dbus_message_new_method_return(msg);
1397         dbus_message_iter_init_append(reply, &iter);
1398         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1399         return reply;
1400 }
1401
1402 static DBusMessage *dbus_hdcp_hdmi_handler(E_DBus_Object *obj, DBusMessage *msg)
1403 {
1404         DBusMessageIter iter;
1405         DBusMessage *reply;
1406         int ret;
1407
1408         ret = hdcp_hdmi_cb(NULL);
1409         _I("hdmi %d", ret);
1410
1411         reply = dbus_message_new_method_return(msg);
1412         dbus_message_iter_init_append(reply, &iter);
1413         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1414         return reply;
1415 }
1416
1417 static DBusMessage *dbus_hdcp_handler(E_DBus_Object *obj, DBusMessage *msg)
1418 {
1419         DBusMessageIter iter;
1420         DBusMessage *reply;
1421         int ret;
1422
1423         ret = hdcp_chgdet_cb(NULL);
1424         _I("hdcp %d", ret);
1425
1426         reply = dbus_message_new_method_return(msg);
1427         dbus_message_iter_init_append(reply, &iter);
1428         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1429         return reply;
1430 }
1431
1432 static DBusMessage *dbus_hdmi_audio_handler(E_DBus_Object *obj, DBusMessage *msg)
1433 {
1434         DBusMessageIter iter;
1435         DBusMessage *reply;
1436         int ret;
1437
1438         ret = hdmi_audio_chgdet_cb(NULL);
1439         _I("hdmi audio %d", ret);
1440
1441         reply = dbus_message_new_method_return(msg);
1442         dbus_message_iter_init_append(reply, &iter);
1443         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1444         return reply;
1445 }
1446
1447 static DBusMessage *dbus_device_handler(E_DBus_Object *obj, DBusMessage *msg)
1448 {
1449         DBusError err;
1450         DBusMessageIter iter;
1451         DBusMessage *reply;
1452         pid_t pid;
1453         int ret;
1454         int argc;
1455         char *type_str;
1456         char *argv[2];
1457
1458         dbus_error_init(&err);
1459
1460         if (!dbus_message_get_args(msg, &err,
1461                     DBUS_TYPE_STRING, &type_str,
1462                     DBUS_TYPE_INT32, &argc,
1463                     DBUS_TYPE_STRING, &argv[0],
1464                     DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
1465                 _E("there is no message");
1466                 ret = -EINVAL;
1467                 goto out;
1468         }
1469
1470         if (argc < 0) {
1471                 _E("message is invalid!");
1472                 ret = -EINVAL;
1473                 goto out;
1474         }
1475
1476         pid = get_edbus_sender_pid(msg);
1477         if (kill(pid, 0) == -1) {
1478                 _E("%d process does not exist, dbus ignored!", pid);
1479                 ret = -ESRCH;
1480                 goto out;
1481         }
1482
1483         changed_device(argv[0], argv[1]);
1484
1485 out:
1486         reply = dbus_message_new_method_return(msg);
1487         dbus_message_iter_init_append(reply, &iter);
1488         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1489
1490         return reply;
1491 }
1492
1493 static DBusMessage *dbus_battery_handler(E_DBus_Object *obj, DBusMessage *msg)
1494 {
1495         DBusError err;
1496         DBusMessageIter iter;
1497         DBusMessage *reply;
1498         pid_t pid;
1499         int ret;
1500         int argc;
1501         char *type_str;
1502         char *argv[5];
1503
1504         dbus_error_init(&err);
1505
1506         if (!dbus_message_get_args(msg, &err,
1507                     DBUS_TYPE_STRING, &type_str,
1508                     DBUS_TYPE_INT32, &argc,
1509                     DBUS_TYPE_STRING, &argv[0],
1510                     DBUS_TYPE_STRING, &argv[1],
1511                     DBUS_TYPE_STRING, &argv[2],
1512                     DBUS_TYPE_STRING, &argv[3],
1513                     DBUS_TYPE_STRING, &argv[4], DBUS_TYPE_INVALID)) {
1514                 _E("there is no message");
1515                 ret = -EINVAL;
1516                 goto out;
1517         }
1518
1519         if (argc < 0) {
1520                 _E("message is invalid!");
1521                 ret = -EINVAL;
1522                 goto out;
1523         }
1524
1525         pid = get_edbus_sender_pid(msg);
1526         if (kill(pid, 0) == -1) {
1527                 _E("%d process does not exist, dbus ignored!", pid);
1528                 ret = -ESRCH;
1529                 goto out;
1530         }
1531         check_capacity_status(argv[0]);
1532         check_charge_status(argv[1]);
1533         check_health_status(argv[2]);
1534         check_online_status(argv[3]);
1535         check_present_status(argv[4]);
1536         _I("%d %d %d %d %d %d %d %d",
1537                 battery.capacity,
1538                 battery.charge_full,
1539                 battery.charge_now,
1540                 battery.health,
1541                 battery.online,
1542                 battery.ovp,
1543                 battery.present,
1544                 battery.temp);
1545         battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
1546         changed_device(POWER_SUBSYSTEM, argv[0]);
1547 out:
1548         reply = dbus_message_new_method_return(msg);
1549         dbus_message_iter_init_append(reply, &iter);
1550         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1551
1552         return reply;
1553 }
1554
1555 static DBusMessage *dbus_udev_handler(E_DBus_Object *obj, DBusMessage *msg)
1556 {
1557         DBusError err;
1558         DBusMessageIter iter;
1559         DBusMessage *reply;
1560         pid_t pid;
1561         int ret;
1562         int argc;
1563         char *type_str;
1564         char *argv;
1565
1566         dbus_error_init(&err);
1567
1568         if (!dbus_message_get_args(msg, &err,
1569                     DBUS_TYPE_STRING, &type_str,
1570                     DBUS_TYPE_INT32, &argc,
1571                     DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
1572                 _E("there is no message");
1573                 ret = -EINVAL;
1574                 goto out;
1575         }
1576
1577         if (argc < 0) {
1578                 _E("message is invalid!");
1579                 ret = -EINVAL;
1580                 goto out;
1581         }
1582
1583         pid = get_edbus_sender_pid(msg);
1584         if (kill(pid, 0) == -1) {
1585                 _E("%d process does not exist, dbus ignored!", pid);
1586                 ret = -ESRCH;
1587                 goto out;
1588         }
1589
1590         if (strncmp(argv, "start", strlen("start")) == 0) {
1591                 uevent_kernel_control_start();
1592                 uevent_udev_control_start();
1593         } else if (strncmp(argv, "stop", strlen("stop")) == 0) {
1594                 uevent_kernel_control_stop();
1595                 uevent_udev_control_stop();
1596         }
1597
1598 out:
1599         reply = dbus_message_new_method_return(msg);
1600         dbus_message_iter_init_append(reply, &iter);
1601         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1602
1603         return reply;
1604 }
1605
1606 int is_factory_mode(void)
1607 {
1608         return factory_mode;
1609 }
1610
1611 void internal_pm_change_state(unsigned int s_bits)
1612 {
1613         if (is_factory_mode() == 1)
1614                 _D("skip LCD control for factory mode");
1615         else
1616                 pm_change_internal(getpid(), s_bits);
1617 }
1618
1619 static int set_factory_mode(int status)
1620 {
1621         int ret = -1;
1622
1623         if (status == 1 || status == 0) {
1624                 factory_mode = status;
1625                 /* For USB-server to refer the value */
1626                 ret = vconf_set_int(VCONFKEY_SYSMAN_FACTORY_MODE, status);
1627                 if(ret != 0) {
1628                         _E("FAIL: vconf_set_int()");
1629                 }
1630         }
1631         return factory_mode;
1632 }
1633
1634 static DBusMessage *dbus_factory_mode(E_DBus_Object *obj, DBusMessage *msg)
1635 {
1636         DBusError err;
1637         DBusMessageIter iter;
1638         DBusMessage *reply;
1639         pid_t pid;
1640         int ret;
1641         int argc;
1642         char *type_str;
1643         char *argv;
1644
1645         dbus_error_init(&err);
1646
1647         if (!dbus_message_get_args(msg, &err,
1648                     DBUS_TYPE_STRING, &type_str,
1649                     DBUS_TYPE_INT32, &argc,
1650                     DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
1651                 _E("there is no message");
1652                 ret = -EINVAL;
1653                 goto out;
1654         }
1655
1656         if (argc < 0) {
1657                 _E("message is invalid!");
1658                 ret = -EINVAL;
1659                 goto out;
1660         }
1661
1662         pid = get_edbus_sender_pid(msg);
1663         if (kill(pid, 0) == -1) {
1664                 _E("%d process does not exist, dbus ignored!", pid);
1665                 ret = -ESRCH;
1666                 goto out;
1667         }
1668
1669         ret = set_factory_mode(atoi(argv));
1670 out:
1671         reply = dbus_message_new_method_return(msg);
1672         dbus_message_iter_init_append(reply, &iter);
1673         dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
1674
1675         return reply;
1676 }
1677
1678 static const struct edbus_method edbus_methods[] = {
1679         { PREDEF_DEVICE_CHANGED, "siss",    "i", dbus_device_handler },
1680         { PREDEF_POWER_CHANGED,  "sisssss", "i", dbus_battery_handler },
1681         { PREDEF_UDEV_CONTROL,   "sis","i", dbus_udev_handler },
1682         { METHOD_GET_HDCP,       NULL, "i", dbus_hdcp_handler },
1683         { METHOD_GET_HDMI_AUDIO, NULL, "i", dbus_hdmi_audio_handler },
1684         { METHOD_GET_HDMI,       NULL, "i", dbus_hdcp_hdmi_handler },
1685         { METHOD_GET_CRADLE,     NULL, "i", dbus_cradle_handler },
1686         { METHOD_FACTORY_MODE,   "sis","i", dbus_factory_mode },
1687 };
1688
1689 static int device_change_poweroff(void *data)
1690 {
1691         uevent_kernel_control_stop();
1692         uevent_udev_control_stop();
1693         return 0;
1694 }
1695
1696 static void device_change_init(void *data)
1697 {
1698         int ret;
1699
1700         power_supply_timer_start();
1701         if (extcon_count_init() != 0)
1702                 _E("fail to init extcon files");
1703         register_notifier(DEVICE_NOTIFIER_POWEROFF, device_change_poweroff);
1704         register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
1705         register_notifier(DEVICE_NOTIFIER_LCD, display_changed);
1706         ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
1707         if (ret < 0)
1708                 _E("fail to init edbus method(%d)", ret);
1709
1710         /* dbus noti change cb */
1711 #ifdef ENABLE_EDBUS_USE
1712         e_dbus_init();
1713         conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
1714         if (!conn)
1715                 _E("check system dbus running!\n");
1716
1717         e_dbus_signal_handler_add(conn, NULL, "/system/uevent/xxxxx",
1718                                   "system.uevent.xxxxx",
1719                                   "Change", cb_xxxxx_signaled, data);
1720 #endif                          /* ENABLE_EDBUS_USE */
1721         if (uevent_kernel_control_start() != 0) {
1722                 _E("fail uevent control init");
1723                 return;
1724         }
1725
1726         if (uevent_udev_control_start() != 0) {
1727                 _E("fail uevent control init");
1728                 return;
1729         }
1730 }
1731
1732 static void device_change_exit(void *data)
1733 {
1734         int i;
1735         unregister_notifier(DEVICE_NOTIFIER_POWEROFF, device_change_poweroff);
1736         unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
1737         unregister_notifier(DEVICE_NOTIFIER_LCD, display_changed);
1738         for (i = 0; i < ARRAY_SIZE(extcon_devices); i++) {
1739                 if (extcon_devices[i].fd <= 0)
1740                         continue;
1741                 close(extcon_devices[i].fd);
1742         }
1743
1744 }
1745
1746 static const struct device_ops change_device_ops = {
1747         .priority = DEVICE_PRIORITY_NORMAL,
1748         .name     = "device change",
1749         .init     = device_change_init,
1750         .exit     = device_change_exit,
1751 };
1752
1753 DEVICE_OPS_REGISTER(&change_device_ops)