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 = NULL;
71 _E("ticker noti name is NULL");
76 ticker.type = 0; /* WITHOUT_QUEUE */
78 FIND_DEVICE_VOID(ticker_ops, "ticker");
79 if (ticker_ops && ticker_ops->init)
80 ticker_ops->init(&ticker);
82 _E("cannot find \"ticker\" ops");
85 void launch_host_syspopup(char *name, char *method,
86 char *key1, char *value1,
87 char *key2, char *value2)
89 struct popup_data params;
90 static const struct device_ops *apps = NULL;
95 FIND_DEVICE_VOID(apps, "apps");
97 params.method = method;
99 params.value1 = value1;
101 params.value2 = value2;
107 static int get_number_of_mounted_storages(void)
111 struct usb_device *dev;
113 if (!storage_list || DD_LIST_LENGTH(storage_list) == 0)
117 DD_LIST_FOREACH(storage_list, l, dev) {
118 if (dev && dev->is_mounted)
125 void update_usbhost_state(void)
129 if (vconf_get_int(VCONFKEY_SYSMAN_USB_HOST_STATUS, &prev) != 0)
132 if (get_number_of_mounted_storages() == 0
133 && (!device_list || DD_LIST_LENGTH(device_list) == 0))
134 curr = VCONFKEY_SYSMAN_USB_HOST_DISCONNECTED;
136 curr = VCONFKEY_SYSMAN_USB_HOST_CONNECTED;
141 if (vconf_set_int(VCONFKEY_SYSMAN_USB_HOST_STATUS, curr) != 0)
142 _E("Failed to set vconf key");
145 bool check_same_mntpath(const char *mntpath)
148 struct usb_device *dev;
150 DD_LIST_FOREACH(storage_list, l, dev) {
151 if (!strncmp(dev->mntpath, mntpath, strlen(dev->mntpath)))
157 bool is_storage_mounted(const char *mntpath)
160 struct usb_device *dev;
162 DD_LIST_FOREACH(storage_list, l, dev) {
163 if (!strncmp(dev->mntpath, mntpath, strlen(dev->mntpath)))
167 return dev->is_mounted;
171 static int add_usb_host_device_to_list(int type,
178 struct usb_device *dev;
181 if (!name || type < 0)
184 if (type == USBHOST_STORAGE && !path)
187 dev = (struct usb_device *)malloc(sizeof(struct usb_device));
189 _E("Failed to assign memory");
194 dev->is_mounted = false;
196 snprintf(dev->name, sizeof(dev->name), "%s", name);
197 snprintf(dev->mntpath, sizeof(dev->mntpath), "%s", path);
200 snprintf(dev->model, sizeof(dev->model), "%s", model);
202 memset(dev->model, 0, sizeof(dev->model));
205 snprintf(dev->vendor, sizeof(dev->vendor), "%s", vendor);
207 memset(dev->vendor, 0, sizeof(dev->vendor));
210 snprintf(dev->fs, sizeof(dev->fs), "%s", fstype);
212 memset(dev->fs, 0, sizeof(dev->fs));
214 if (type == USBHOST_STORAGE) {
215 if (!check_same_mntpath(path))
216 DD_LIST_APPEND(storage_list, dev);
220 dev->noti_id = activate_device_notification(dev, DD_LIST_LENGTH(device_list));
221 DD_LIST_APPEND(device_list, dev);
222 if (send_device_added_info(dev) < 0)
223 _E("Failed to send device info");
229 int add_usb_storage_to_list(const char *name,
240 ret = get_mount_path(name, path, sizeof(path));
242 _E("Failed to get mount path");
246 ret = add_usb_host_device_to_list(USBHOST_STORAGE,
247 name, vendor, model, fstype, path);
249 update_usbhost_state();
254 int add_usb_device_to_list(int type,
261 ret = add_usb_host_device_to_list(type,
262 name, vendor, model, NULL, NULL);
264 update_usbhost_state();
269 int remove_usb_storage_from_list(const char *name)
272 struct usb_device *dev;
279 DD_LIST_FOREACH(storage_list, l, dev) {
280 if (strncmp(dev->name, name, strlen(name)))
290 DD_LIST_REMOVE(storage_list, dev);
293 update_usbhost_state();
298 int remove_usb_device_from_list(const char *name, int type)
301 struct usb_device *dev;
309 DD_LIST_FOREACH(device_list, l, dev) {
310 if (type == USBHOST_PRINTER) {
311 if (!strstr(name, dev->name))
314 if (strncmp(dev->name, name, strlen(name)))
325 if (send_device_removed_info(dev) < 0)
326 _E("Failed to send device info");
328 DD_LIST_REMOVE(device_list, dev);
331 len = DD_LIST_LENGTH(device_list);
335 dev = DD_LIST_NTH(device_list, 0); /* First element */
337 if (deactivate_device_notification(dev, len))
338 _E("Failed to remove notification");
340 update_usbhost_state();
345 static void subsystem_host_changed (struct udev_device *dev)
347 const char *state = NULL;
351 state = udev_device_get_property_value(dev, UDEV_PROP_KEY_STATE);
355 if (!strncmp(state, UDEV_PROP_VALUE_ADD, strlen(UDEV_PROP_VALUE_ADD))) {
356 _I("USB host connector is added");
358 if (!host_uevent_enabled)
359 host_uevent_enabled = true;
361 cradle = get_cradle_status();
363 launch_ticker_notification(TICKER_NAME_CONNECTOR_CONNECTED);
369 if (!strncmp(state, UDEV_PROP_VALUE_REMOVE, strlen(UDEV_PROP_VALUE_REMOVE))) {
370 _I("USB host connector is removed");
373 launch_ticker_notification(TICKER_NAME_CONNECTOR_DISCONNECTED);
382 const static struct uevent_handler uhs[] = {
383 { HOST_SUBSYSTEM , subsystem_host_changed , NULL },
386 static int usbhost_init_booting_done(void *data)
390 unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_init_booting_done);
392 for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
393 ret = register_uevent_control(&uhs[i]);
395 _E("FAIL: reg_uevent_control()");
398 if (register_unmount_signal_handler() < 0)
399 _E("Failed to register handler for unmount signal");
401 if (register_device_all_signal_handler() < 0)
402 _E("Failed to register handler for device info");
404 if (register_usbhost_dbus_methods() < 0)
405 _E("Failed to register dbus handler for usbhost");
410 static void usbhost_init(void *data)
412 register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_init_booting_done);
415 static void usbhost_exit(void *data)
419 for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
420 unregister_uevent_control(&uhs[i]);
424 static const struct device_ops usbhost_device_ops = {
425 .priority = DEVICE_PRIORITY_NORMAL,
427 .init = usbhost_init,
428 .exit = usbhost_exit,
431 DEVICE_OPS_REGISTER(&usbhost_device_ops)