tizen_2.0_build
[framework/system/system-server.git] / ss_device_change_handler.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.tizenopensource.org/license
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17
18 #include <stdlib.h>
19 #include <fcntl.h>
20 #include <dirent.h>
21 #include <errno.h>
22 #include <vconf.h>
23 #include <sysman.h>
24 #include <pmapi.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/mount.h>
28 #include <syspopup_caller.h>
29 #include <aul.h>
30 #include <bundle.h>
31 #include <dirent.h>
32
33 #include "ss_queue.h"
34 #include "ss_log.h"
35 #include "ss_device_handler.h"
36 #include "ss_device_plugin.h"
37 #include "ss_noti.h"
38 #include "include/ss_data.h"
39 #include "sys_device_noti/sys_device_noti.h"
40
41 #define BUFF_MAX                255
42 #define SYS_CLASS_INPUT         "/sys/class/input"
43
44 struct input_event {
45         long dummy[2];
46         unsigned short type;
47         unsigned short code;
48         int value;
49 };
50
51 enum snd_jack_types {
52         SND_JACK_HEADPHONE = 0x0001,
53         SND_JACK_MICROPHONE = 0x0002,
54         SND_JACK_HEADSET = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
55         SND_JACK_LINEOUT = 0x0004,
56         SND_JACK_MECHANICAL = 0x0008,   /* If detected separately */
57         SND_JACK_VIDEOOUT = 0x0010,
58         SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT,
59 };
60
61
62 static int input_device_number;
63
64 static void usb_chgdet_cb(struct ss_main_data *ad)
65 {
66         int val = -1;
67         char params[BUFF_MAX];
68         PRT_TRACE("jack - usb changed\n");
69         pm_change_state(LCD_NORMAL);
70         /* check charging now */
71         ss_lowbat_is_charge_in_now();
72         /* check current battery level */
73         ss_lowbat_monitor(NULL);
74         ss_action_entry_call_internal(PREDEF_USBCON, 0);
75
76         if (plugin_intf->OEM_sys_get_jack_usb_online(&val)==0) {
77                 if (val==1) {
78                         snprintf(params, sizeof(params), "%d", CB_NOTI_BATT_CHARGE);
79                         ss_launch_if_noexist("/usr/bin/sys_device_noti", params);
80                         PRT_TRACE("usb device notification");
81                 }
82         }
83 }
84
85 static void ta_chgdet_cb(struct ss_main_data *ad)
86 {
87         PRT_TRACE("jack - ta changed\n");
88         pm_change_state(LCD_NORMAL);
89         /* check charging now */
90         ss_lowbat_is_charge_in_now();
91         /* check current battery level */
92         ss_lowbat_monitor(NULL);
93
94         int val = -1;
95         int ret = -1;
96         int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
97         char params[BUFF_MAX];
98
99         if (plugin_intf->OEM_sys_get_jack_charger_online(&val) == 0) {
100                 vconf_set_int(VCONFKEY_SYSMAN_CHARGER_STATUS, val);
101                 if (val == 0) {
102                         pm_unlock_state(LCD_OFF, STAY_CUR_STATE);
103
104                         vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
105                         if(bat_state < VCONFKEY_SYSMAN_BAT_NORMAL) {
106                                 bundle *b = NULL;
107                                 b = bundle_create();
108                                 bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
109
110                                 ret = syspopup_launch("lowbat-syspopup", b);
111                                 if (ret < 0) {
112                                         PRT_TRACE_EM("popup lauch failed\n");
113                                 }
114                                 bundle_free(b);
115                         }
116                 } else {
117                         pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
118                         snprintf(params, sizeof(params), "%d", CB_NOTI_BATT_CHARGE);
119                         ss_launch_if_noexist("/usr/bin/sys_device_noti", params);
120                         PRT_TRACE("ta device notification");
121                 }
122         }
123         else
124                 PRT_TRACE_ERR("failed to get ta status\n");
125 }
126
127 static void earjack_chgdet_cb(struct ss_main_data *ad)
128 {
129         PRT_TRACE("jack - earjack changed\n");
130         ss_action_entry_call_internal(PREDEF_EARJACKCON, 0);
131 }
132
133 static void earkey_chgdet_cb(struct ss_main_data *ad)
134 {
135         int val;
136         PRT_TRACE("jack - earkey changed\n");
137
138         if (plugin_intf->OEM_sys_get_jack_earkey_online(&val) == 0)
139                 vconf_set_int(VCONFKEY_SYSMAN_EARJACKKEY, val);
140 }
141
142 static void tvout_chgdet_cb(struct ss_main_data *ad)
143 {
144         PRT_TRACE("jack - tvout changed\n");
145         pm_change_state(LCD_NORMAL);
146 }
147
148 static void hdmi_chgdet_cb(struct ss_main_data *ad)
149 {
150         PRT_TRACE("jack - hdmi changed\n");
151         int val;
152         pm_change_state(LCD_NORMAL);
153         if (plugin_intf->OEM_sys_get_jack_hdmi_online(&val) == 0)
154                 if(val == 1)
155                         pm_lock_state(LCD_NORMAL, GOTO_STATE_NOW, 0);
156                 else
157                         pm_unlock_state(LCD_NORMAL, PM_SLEEP_MARGIN);
158 }
159
160 static void keyboard_chgdet_cb(struct ss_main_data *ad)
161 {
162         int val = -1;
163         int ret = -1;
164         PRT_TRACE("jack - keyboard changed\n");
165
166         ret = plugin_intf->OEM_sys_get_jack_keyboard_online(&val);
167         if( ret == 0) {
168                 if(val != 1)
169                         val = 0;
170                 vconf_set_int(VCONFKEY_SYSMAN_SLIDING_KEYBOARD, val);
171         } else {
172                 vconf_set_int(VCONFKEY_SYSMAN_SLIDING_KEYBOARD, VCONFKEY_SYSMAN_SLIDING_KEYBOARD_NOT_SUPPORTED);
173         }
174 }
175
176 static int show_tickernoti(char* msg)
177 {
178         PRT_TRACE("show tickernoti : %s\n", msg);
179         int ret = -1;
180
181         bundle *b = NULL;
182
183         b = bundle_create();
184         if (!b) {
185                 PRT_TRACE_ERR("FAIL: bundle_create()\n");
186                 return -1;
187         }
188
189         ret = bundle_add(b, "0", "info");   /* "0" means tickernoti style */
190         if (ret != 0) {
191                 PRT_TRACE_ERR("FAIL: bundle_add()\n");
192                 if (0 != bundle_free(b))
193                         PRT_TRACE_ERR("FAIL: bundle_free()\n");
194                 return -1;
195         }
196
197         ret = bundle_add(b, "1", dgettext("system-server", msg)); /* "1" means popup text */
198         if (ret != 0) {
199                 PRT_TRACE_ERR("FAIL: bundle_add()\n");
200                 if (0 != bundle_free(b))
201                         PRT_TRACE_ERR("FAIL: bundle_free()\n");
202                 return -1;
203         }
204
205         ret = bundle_add(b, "2", "0");  /* "2" means orientation of tickernoti */
206         if (ret != 0) {
207                 PRT_TRACE_ERR("FAIL: bundle_add()\n");
208                 if (0 != bundle_free(b))
209                         PRT_TRACE_ERR("FAIL: bundle_free()\n");
210                 return -1;
211         }
212
213         ret = bundle_add(b, "3", "3");  /* "3" means timeout(second) of tickernoti */
214         if (ret != 0) {
215                 PRT_TRACE_ERR("FAIL: bundle_add()\n");
216                 if (0 != bundle_free(b))
217                         PRT_TRACE_ERR("FAIL: bundle_free()\n");
218                 return -1;
219         }
220
221         ret = syspopup_launch("tickernoti-syspopup", b);
222         if (ret != 0)
223                 PRT_TRACE_ERR("FAIL: syspopup_launch()\n");
224
225         if (0 != bundle_free(b))
226                 PRT_TRACE_ERR("FAIL: bundle_free()\n");
227
228         return 0;
229 }
230
231 // TO DO - multi language
232 static void keyboard_add_cb(struct ss_main_data *ad)
233 {
234         pm_change_state(LCD_NORMAL);
235         show_tickernoti("Keyboard connected");
236         input_device_number++;
237         PRT_TRACE("keyboard added (total input device : %d)",input_device_number);
238 }
239
240 static void keyboard_remove_cb(struct ss_main_data *ad)
241 {
242         pm_change_state(LCD_NORMAL);
243         show_tickernoti("Keyboard removed safely");
244         if (input_device_number > 0)
245                 input_device_number--;
246         PRT_TRACE("keyboard removed (total input device : %d)",input_device_number);
247 }
248
249 static void mouse_add_cb(struct ss_main_data *ad)
250 {
251         pm_change_state(LCD_NORMAL);
252         show_tickernoti("Mouse connected");
253         input_device_number++;
254         PRT_TRACE("mouse added (total input device : %d)",input_device_number);
255 }
256
257 static void mouse_remove_cb(struct ss_main_data *ad)
258 {
259         pm_change_state(LCD_NORMAL);
260         show_tickernoti("Mouse removed safely");
261         if (input_device_number > 0)
262                 input_device_number--;
263         PRT_TRACE("Mouse removed (total input device : %d)",input_device_number);
264 }
265
266 static void camera_add_cb(struct ss_main_data *ad)
267 {
268         int ret = -1;
269         pm_change_state(LCD_NORMAL);
270         show_tickernoti("Camera connected");
271
272         DIR *dp;
273         struct dirent *dir;
274         struct stat stat;
275         char buf[255] = "unknown_camera";
276
277         if ((dp = opendir("/tmp/camera")) == NULL) {
278                 PRT_TRACE_ERR("Can not open directory\n");
279                 return -1;
280         }
281         chdir("/tmp/camera");
282
283         while (dir = readdir(dp)) {
284                 memset(&stat, 0, sizeof(struct stat));
285                 lstat(dir->d_name, &stat);
286                 if (S_ISDIR(stat.st_mode) || S_ISLNK(stat.st_mode)) {
287                         if (strncmp(".", dir->d_name, 1) == 0
288                                         || strncmp("..", dir->d_name, 2) == 0)
289                                 continue;
290                         snprintf(buf, 255, "%s", dir->d_name);
291                 }
292         }
293         closedir(dp);
294
295         bundle *b = NULL;
296         b = bundle_create();
297         bundle_add(b, "_SYSPOPUP_CONTENT_", "camera_add");
298         bundle_add(b, "device_name", buf);
299
300         ret = syspopup_launch("usbotg-syspopup", b);
301         if (ret < 0) {
302                 PRT_TRACE_EM("popup lauch failed\n");
303         }
304         bundle_free(b);
305         PRT_TRACE("Camera cannected");
306 }
307
308 static void camera_remove_cb(struct ss_main_data *ad)
309 {
310         int ret = -1;
311         bundle *b = NULL;
312         b = bundle_create();
313         bundle_add(b, "_SYSPOPUP_CONTENT_", "camera_remove");
314
315         ret = syspopup_launch("usbotg-syspopup", b);
316         if (ret < 0) {
317                 PRT_TRACE_EM("popup lauch failed\n");
318         }
319         bundle_free(b);
320         PRT_TRACE("Camera removed");
321 }
322
323
324 static void unknown_usb_add_cb(struct ss_main_data *ad)
325 {
326         int ret = -1;
327         pm_change_state(LCD_NORMAL);
328         bundle *b = NULL;
329         b = bundle_create();
330         bundle_add(b, "_SYSPOPUP_CONTENT_", "unknown_add");
331
332         ret = syspopup_launch("usbotg-syspopup", b);
333         if (ret < 0) {
334                 PRT_TRACE_EM("popup lauch failed\n");
335         }
336         bundle_free(b);
337         PRT_TRACE("unknown usb device added");
338 }
339
340 static void unknown_usb_remove_cb(struct ss_main_data *ad)
341 {
342         int ret = -1;
343         pm_change_state(LCD_NORMAL);
344         bundle *b = NULL;
345         b = bundle_create();
346         bundle_add(b, "_SYSPOPUP_CONTENT_", "unknown_remove");
347
348         ret = syspopup_launch("usbotg-syspopup", b);
349         if (ret < 0) {
350                 PRT_TRACE_EM("popup lauch failed\n");
351         }
352         bundle_free(b);
353         PRT_TRACE("unknown usb device added");
354 }
355
356
357 static void mmc_chgdet_cb(void *data)
358 {
359         if (data == NULL) {
360                 PRT_TRACE("mmc removed");
361                 ss_mmc_removed();
362         } else {
363                 PRT_TRACE("mmc added");
364                 ss_mmc_inserted();
365         }
366 }
367
368 static void ums_unmount_cb(void *data)
369 {
370         umount(MOVINAND_MOUNT_POINT);
371 }
372
373 static void charge_cb(struct ss_main_data *ad)
374 {
375         int val = -1;
376         char params[BUFF_MAX];
377         static int bat_full_noti = 0;
378         ss_lowbat_monitor(NULL);
379         if (plugin_intf->OEM_sys_get_battery_health(&val) == 0) {
380                 if (val==BATTERY_OVERHEAT || val==BATTERY_COLD) {
381                         PRT_TRACE_ERR("Battery health status is not good (%d)", val);
382                         ss_action_entry_call_internal(PREDEF_LOWBAT, 1, CHARGE_ERROR_ACT);
383                         return;
384                 }
385         } else {
386                 PRT_TRACE_ERR("failed to get battery health status");
387         }
388         plugin_intf->OEM_sys_get_battery_charge_full(&val);
389         if (val==0) {
390                 if (bat_full_noti==1) {
391                         snprintf(params, sizeof(params), "%d %d", CB_NOTI_BATT_FULL, CB_NOTI_OFF);
392                         ss_launch_if_noexist("/usr/bin/sys_device_noti", params);
393                 }
394                 bat_full_noti = 0;
395         } else {
396                 if (val==1 && bat_full_noti==0) {
397                         bat_full_noti = 1;
398                         PRT_TRACE("battery full noti");
399                         snprintf(params, sizeof(params), "%d %d", CB_NOTI_BATT_FULL, CB_NOTI_ON);
400                         ss_launch_if_noexist("/usr/bin/sys_device_noti", params);
401                 }
402         }
403 }
404
405 static void __usb_storage_cb(keynode_t *key, void *data)
406 {
407         char *vconf_value;
408
409         if (data == NULL) {
410                 PRT_TRACE("USB Storage removed");
411                 vconf_value = vconf_get_str(VCONFKEY_INTERNAL_REMOVED_USB_STORAGE);
412                 ss_action_entry_call_internal(PREDEF_USB_STORAGE_REMOVE, 1, vconf_value);
413         } else {
414                 PRT_TRACE("USB Storage added");
415                 show_tickernoti("Mass storage enabled");
416                 vconf_value = vconf_get_str(VCONFKEY_INTERNAL_ADDED_USB_STORAGE);
417                 ss_action_entry_call_internal(PREDEF_USB_STORAGE_ADD, 1, vconf_value);
418         }
419 }
420
421 int ss_device_change_init(struct ss_main_data *ad)
422 {
423         /* for simple noti change cb */
424         ss_noti_add("device_usb_chgdet", (void *)usb_chgdet_cb, (void *)ad);
425         ss_noti_add("device_ta_chgdet", (void *)ta_chgdet_cb, (void *)ad);
426         ss_noti_add("device_earjack_chgdet", (void *)earjack_chgdet_cb, (void *)ad);
427         ss_noti_add("device_earkey_chgdet", (void *)earkey_chgdet_cb, (void *)ad);
428         ss_noti_add("device_tvout_chgdet", (void *)tvout_chgdet_cb, (void *)ad);
429         ss_noti_add("device_hdmi_chgdet", (void *)hdmi_chgdet_cb, (void *)ad);
430         ss_noti_add("device_keyboard_chgdet", (void *)keyboard_chgdet_cb, (void *)ad);
431         ss_noti_add("device_keyboard_add", (void *)keyboard_add_cb, (void *)ad);
432         ss_noti_add("device_keyboard_remove", (void *)keyboard_remove_cb, (void *)ad);
433         ss_noti_add("device_mouse_add", (void *)mouse_add_cb, (void *)ad);
434         ss_noti_add("device_mouse_remove", (void *)mouse_remove_cb, (void *)ad);
435         ss_noti_add("device_camera_add", (void *)camera_add_cb, (void *)ad);
436         ss_noti_add("device_camera_remove", (void *)camera_remove_cb, (void *)ad);
437         ss_noti_add("device_unknown_usb_add", (void *)unknown_usb_add_cb, (void *)ad);
438         ss_noti_add("device_unknown_usb_remove", (void *)unknown_usb_remove_cb, (void *)ad);
439         ss_noti_add("mmcblk_add", (void *)mmc_chgdet_cb, (void *)1);
440         ss_noti_add("mmcblk_remove", (void *)mmc_chgdet_cb, NULL);
441
442         ss_noti_add("unmount_ums", (void *)ums_unmount_cb, NULL);
443         ss_noti_add("device_charge_chgdet", (void *)charge_cb, (void *)ad);
444
445         if (vconf_notify_key_changed(VCONFKEY_INTERNAL_ADDED_USB_STORAGE, (void *)__usb_storage_cb, (void *)1) < 0) {
446                 PRT_TRACE_ERR("Vconf notify key chaneged failed: KEY(%s)", VCONFKEY_SYSMAN_ADDED_USB_STORAGE);
447         }
448
449         if (vconf_notify_key_changed(VCONFKEY_INTERNAL_REMOVED_USB_STORAGE, (void *)__usb_storage_cb, NULL) < 0) {
450                 PRT_TRACE_ERR("Vconf notify key chaneged failed: KEY(%s)", VCONFKEY_SYSMAN_REMOVED_USB_STORAGE);
451         }
452
453         /* set initial state for devices */
454         input_device_number = 0;
455         keyboard_chgdet_cb(NULL);
456         hdmi_chgdet_cb(NULL);
457
458         return 0;
459 }