4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "core/device-notifier.h"
22 static dd_list *storage_list;
23 static dd_list *device_list;
25 static int noti_id = 0;
41 /* Do not handle usb host uevents if host_uevent_enable is false
42 * host_uevent_enable is set to true when usb host connector is connected first*/
43 static bool host_uevent_enabled = false;
45 bool is_host_uevent_enabled(void)
47 return host_uevent_enabled;
50 int get_storage_list_length(void)
52 return DD_LIST_LENGTH(storage_list);
55 dd_list *get_storage_list(void)
60 dd_list *get_device_list(void)
65 void launch_ticker_notification(char *name)
67 struct ticker_data ticker;
68 const struct device_ops *ticker_ops;
71 _E("ticker noti name is NULL");
76 ticker.type = 0; /* WITHOUT_QUEUE */
78 ticker_ops = find_device("ticker");
80 if (ticker_ops && ticker_ops->init)
81 ticker_ops->init(&ticker);
83 _E("cannot find \"ticker\" ops");
86 void launch_host_syspopup(char *name, char *method,
87 char *key1, char *value1,
88 char *key2, char *value2)
90 struct popup_data params;
91 static const struct device_ops *apps = NULL;
97 apps = find_device("apps");
103 params.method = method;
105 params.value1 = value1;
107 params.value2 = value2;
113 static int get_number_of_mounted_storages(void)
117 struct usb_device *dev;
119 if (!storage_list || DD_LIST_LENGTH(storage_list) == 0)
123 DD_LIST_FOREACH(storage_list, l, dev) {
124 if (dev && dev->is_mounted)
131 void update_usbhost_state(void)
135 if (vconf_get_int(VCONFKEY_SYSMAN_USB_HOST_STATUS, &prev) != 0)
138 if (get_number_of_mounted_storages() == 0
139 && (!device_list || DD_LIST_LENGTH(device_list) == 0))
140 curr = VCONFKEY_SYSMAN_USB_HOST_DISCONNECTED;
142 curr = VCONFKEY_SYSMAN_USB_HOST_CONNECTED;
147 if (vconf_set_int(VCONFKEY_SYSMAN_USB_HOST_STATUS, curr) != 0)
148 _E("Failed to set vconf key");
151 bool check_same_mntpath(const char *mntpath)
154 struct usb_device *dev;
156 DD_LIST_FOREACH(storage_list, l, dev) {
157 if (!strncmp(dev->mntpath, mntpath, strlen(dev->mntpath)))
163 bool is_storage_mounted(const char *mntpath)
166 struct usb_device *dev;
168 DD_LIST_FOREACH(storage_list, l, dev) {
169 if (!strncmp(dev->mntpath, mntpath, strlen(dev->mntpath)))
173 return dev->is_mounted;
177 static int add_usb_host_device_to_list(int type,
184 struct usb_device *dev;
187 if (!name || type < 0)
190 if (type == USBHOST_STORAGE && !path)
193 dev = (struct usb_device *)malloc(sizeof(struct usb_device));
195 _E("Failed to assign memory");
200 dev->is_mounted = false;
202 snprintf(dev->name, sizeof(dev->name), "%s", name);
203 snprintf(dev->mntpath, sizeof(dev->mntpath), "%s", path);
206 snprintf(dev->model, sizeof(dev->model), "%s", model);
208 memset(dev->model, 0, sizeof(dev->model));
211 snprintf(dev->vendor, sizeof(dev->vendor), "%s", vendor);
213 memset(dev->vendor, 0, sizeof(dev->vendor));
216 snprintf(dev->fs, sizeof(dev->fs), "%s", fstype);
218 memset(dev->fs, 0, sizeof(dev->fs));
220 if (type == USBHOST_STORAGE) {
221 if (!check_same_mntpath(path))
222 DD_LIST_APPEND(storage_list, dev);
226 dev->noti_id = activate_device_notification(dev, DD_LIST_LENGTH(device_list));
227 DD_LIST_APPEND(device_list, dev);
228 if (send_device_added_info(dev) < 0)
229 _E("Failed to send device info");
235 int add_usb_storage_to_list(const char *name,
246 ret = get_mount_path(name, path, sizeof(path));
248 _E("Failed to get mount path");
252 ret = add_usb_host_device_to_list(USBHOST_STORAGE,
253 name, vendor, model, fstype, path);
255 update_usbhost_state();
260 int add_usb_device_to_list(int type,
267 ret = add_usb_host_device_to_list(type,
268 name, vendor, model, NULL, NULL);
270 update_usbhost_state();
275 int remove_usb_storage_from_list(const char *name)
278 struct usb_device *dev;
285 DD_LIST_FOREACH(storage_list, l, dev) {
286 if (strncmp(dev->name, name, strlen(name)))
296 DD_LIST_REMOVE(storage_list, dev);
299 update_usbhost_state();
304 int remove_usb_device_from_list(const char *name, int type)
307 struct usb_device *dev;
315 DD_LIST_FOREACH(device_list, l, dev) {
316 if (type == USBHOST_PRINTER) {
317 if (!strstr(name, dev->name))
320 if (strncmp(dev->name, name, strlen(name)))
331 if (send_device_removed_info(dev) < 0)
332 _E("Failed to send device info");
334 DD_LIST_REMOVE(device_list, dev);
337 len = DD_LIST_LENGTH(device_list);
341 dev = DD_LIST_NTH(device_list, 0); /* First element */
343 if (deactivate_device_notification(dev, len))
344 _E("Failed to remove notification");
346 update_usbhost_state();
351 static void subsystem_host_changed (struct udev_device *dev)
353 const char *state = NULL;
357 state = udev_device_get_property_value(dev, UDEV_PROP_KEY_STATE);
361 if (!strncmp(state, UDEV_PROP_VALUE_ADD, strlen(UDEV_PROP_VALUE_ADD))) {
362 _I("USB host connector is added");
364 if (!host_uevent_enabled)
365 host_uevent_enabled = true;
367 cradle = get_cradle_status();
369 launch_ticker_notification(TICKER_NAME_CONNECTOR_CONNECTED);
375 if (!strncmp(state, UDEV_PROP_VALUE_REMOVE, strlen(UDEV_PROP_VALUE_REMOVE))) {
376 _I("USB host connector is removed");
379 launch_ticker_notification(TICKER_NAME_CONNECTOR_DISCONNECTED);
388 const static struct uevent_handler uhs[] = {
389 { HOST_SUBSYSTEM , subsystem_host_changed , NULL },
392 static int usbhost_init_booting_done(void *data)
396 unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_init_booting_done);
398 for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
399 ret = register_uevent_control(&uhs[i]);
401 _E("FAIL: reg_uevent_control()");
404 if (register_unmount_signal_handler() < 0)
405 _E("Failed to register handler for unmount signal");
407 if (register_device_all_signal_handler() < 0)
408 _E("Failed to register handler for device info");
410 if (register_usbhost_dbus_methods() < 0)
411 _E("Failed to register dbus handler for usbhost");
416 static void usbhost_init(void *data)
418 register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_init_booting_done);
421 static void usbhost_exit(void *data)
425 for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
426 unregister_uevent_control(&uhs[i]);
430 static const struct device_ops usbhost_device_ops = {
431 .priority = DEVICE_PRIORITY_NORMAL,
433 .init = usbhost_init,
434 .exit = usbhost_exit,
437 DEVICE_OPS_REGISTER(&usbhost_device_ops)