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