- External storage information can be get from deviced.
Thus the dbus method call from deviced is used to
get the information.
Change-Id: Iac56c26ed766b8a72a78ba970152c7105b0672a1
Signed-off-by: Taeyoung Kim <ty317.kim@samsung.com>
SET(INC_DIR include)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/${INC_DIR})
-SET(dependents "dlog capi-base-common vconf glib-2.0 libtzplatform-config capi-system-system-settings")
+SET(dependents
+ dlog
+ capi-base-common
+ vconf
+ glib-2.0
+ gio-2.0
+ libtzplatform-config
+ capi-system-system-settings
+)
SET(pc_dependents "capi-base-common")
INCLUDE(FindPkgConfig)
src/statvfs.c
src/storage.c
src/storage-internal.c
- src/storage-sdcard.c)
+ src/storage-external.c
+ src/storage-external-dbus.c)
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} ${TARGET_SRCS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${rpkgs_LDFLAGS})
BuildRequires: pkgconfig(capi-base-common)
BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gio-2.0)
BuildRequires: pkgconfig(libtzplatform-config)
BuildRequires: pkgconfig(capi-system-system-settings)
--- /dev/null
+/*
+ * libstorage
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <vconf.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <gio/gio.h>
+#include <glib.h>
+#include <limits.h>
+
+#include "log.h"
+#include "storage-external-dbus.h"
+
+#define CHECK_STR(a) (a ? a : "")
+
+#define STORAGE_EXT_GET_LIST "GetDeviceList"
+
+#define DBUS_REPLY_TIMEOUT (-1)
+
+static void storage_ext_release_internal(storage_ext_device *dev)
+{
+ if (!dev)
+ return;
+ free(dev->devnode);
+ free(dev->syspath);
+ free(dev->fs_usage);
+ free(dev->fs_type);
+ free(dev->fs_version);
+ free(dev->fs_uuid);
+ free(dev->mount_point);
+}
+
+void storage_ext_release_device(storage_ext_device **dev)
+{
+ if (!dev || !*dev)
+ return;
+ storage_ext_release_internal(*dev);
+ free(*dev);
+ *dev = NULL;
+}
+
+void storage_ext_release_list(dd_list **list)
+{
+ storage_ext_device *dev;
+ dd_list *elem;
+
+ if (*list == NULL)
+ return;
+
+ DD_LIST_FOREACH(*list, elem, dev) {
+ storage_ext_release_internal(dev);
+ free(dev);
+ }
+
+ g_list_free(*list);
+ *list = NULL;
+}
+
+static GDBusConnection *get_dbus_connection(void)
+{
+ GError *err = NULL;
+ static GDBusConnection *conn;
+
+ if (conn)
+ return conn;
+
+#if !GLIB_CHECK_VERSION(2, 35, 0)
+ g_type_init();
+#endif
+
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+ if (!conn) {
+ if (err) {
+ _E("fail to get dbus connection : %s", err->message);
+ g_clear_error(&err);
+ } else
+ _E("fail to get dbus connection");
+ return NULL;
+ }
+ return conn;
+}
+
+static GVariant *dbus_method_call_sync(const gchar *dest, const gchar *path,
+ const gchar *iface, const gchar *method, GVariant *param)
+{
+ GDBusConnection *conn;
+ GError *err = NULL;
+ GVariant *ret;
+
+ if (!dest || !path || !iface || !method || !param)
+ return NULL;
+
+ conn = get_dbus_connection();
+ if (!conn) {
+ _E("fail to get dbus connection");
+ return NULL;
+ }
+
+ ret = g_dbus_connection_call_sync(conn,
+ dest, path, iface, method,
+ param, NULL, G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &err);
+ if (!ret) {
+ if (err) {
+ _E("dbus method sync call failed(%s)", err->message);
+ g_clear_error(&err);
+ } else
+ _E("g_dbus_connection_call_sync() failed");
+ return NULL;
+ }
+
+ return ret;
+}
+
+int storage_ext_get_list(dd_list **list)
+{
+ GVariant *result;
+ GVariantIter *iter;
+ storage_ext_device *elem, info;
+ int ret;
+
+ if (!list)
+ return -EINVAL;
+
+ result = dbus_method_call_sync(STORAGE_EXT_BUS_NAME,
+ STORAGE_EXT_PATH_MANAGER,
+ STORAGE_EXT_IFACE_MANAGER,
+ STORAGE_EXT_GET_LIST,
+ g_variant_new("(s)", "all"));
+ if (!result) {
+ _E("Failed to get storage_ext device info");
+ return -EIO;
+ }
+
+ g_variant_get(result, "(a(issssssisibii))", &iter);
+
+ while (g_variant_iter_loop(iter, "(issssssisibii)",
+ &info.type, &info.devnode, &info.syspath,
+ &info.fs_usage, &info.fs_type,
+ &info.fs_version, &info.fs_uuid,
+ &info.readonly, &info.mount_point,
+ &info.state, &info.primary,
+ &info.flags, &info.storage_id)) {
+
+ elem = (storage_ext_device *)malloc(sizeof(storage_ext_device));
+ if (!elem) {
+ _E("malloc() failed");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ elem->type = info.type;
+ elem->readonly = info.readonly;
+ elem->state = info.state;
+ elem->primary = info.primary;
+ elem->devnode = strdup(CHECK_STR(info.devnode));
+ elem->syspath = strdup(CHECK_STR(info.syspath));
+ elem->fs_usage = strdup(CHECK_STR(info.fs_usage));
+ elem->fs_type = strdup(CHECK_STR(info.fs_type));
+ elem->fs_version = strdup(CHECK_STR(info.fs_version));
+ elem->fs_uuid = strdup(CHECK_STR(info.fs_uuid));
+ elem->mount_point = strdup(CHECK_STR(info.mount_point));
+ elem->flags = info.flags;
+ elem->storage_id = info.storage_id;
+
+ DD_LIST_APPEND(*list, elem);
+ }
+
+ ret = g_list_length(*list);
+
+out:
+ if (ret < 0)
+ storage_ext_release_list(list);
+ g_variant_iter_free(iter);
+ g_variant_unref(result);
+ return ret;
+}
--- /dev/null
+/*
+ * libstorage
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __STORAGE_EXTERNAL_DBUS_H__
+#define __STORAGE_EXTERNAL_DBUS_H__
+
+#include <stdbool.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include "list.h"
+
+#define STORAGE_EXT_BUS_NAME "org.tizen.system.deviced"
+#define STORAGE_EXT_PATH "/Org/Tizen/System/DeviceD/Block"
+#define STORAGE_EXT_PATH_DEVICES STORAGE_EXT_PATH"/Devices"
+#define STORAGE_EXT_PATH_MANAGER STORAGE_EXT_PATH"/Manager"
+#define STORAGE_EXT_IFACE STORAGE_EXT_BUS_NAME".Block"
+#define STORAGE_EXT_IFACE_MANAGER STORAGE_EXT_BUS_NAME".BlockManager"
+
+enum mount_state {
+ STORAGE_EXT_UNMOUNTED,
+ STORAGE_EXT_MOUNTED,
+};
+
+enum storage_ext_state {
+ STORAGE_EXT_REMOVED,
+ STORAGE_EXT_ADDED,
+ STORAGE_EXT_CHANGED,
+};
+
+enum storage_ext_type {
+ STORAGE_EXT_SCSI,
+ STORAGE_EXT_MMC,
+};
+
+enum storage_ext_flags {
+ FLAG_NONE = 0,
+ UNMOUNT_UNSAFE = 1 << 0,
+ FS_BROKEN = 1 << 1,
+ FS_EMPTY = 1 << 2,
+ FS_NOT_SUPPORTED = 1 << 3,
+ MOUNT_READONLY = 1 << 4,
+};
+
+typedef struct _storage_ext_device {
+ enum storage_ext_type type;
+ char *devnode;
+ char *syspath;
+ char *fs_usage;
+ char *fs_type;
+ char *fs_version;
+ char *fs_uuid;
+ bool readonly;
+ char *mount_point;
+ enum mount_state state;
+ bool primary; /* the first partition */
+ int flags;
+ int storage_id;
+} storage_ext_device;
+
+void storage_ext_release_device(storage_ext_device **dev);
+void storage_ext_release_list(dd_list **list);
+int storage_ext_get_list(dd_list **list);
+
+#endif /* __STORAGE_EXTERNAL_DBUS_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/statvfs.h>
+#include <vconf.h>
+#include <tzplatform_config.h>
+
+#include "common.h"
+#include "list.h"
+#include "log.h"
+#include "storage-external-dbus.h"
+
+static int storage_ext_get_dev_state(storage_ext_device *dev,
+ enum storage_ext_state blk_state,
+ storage_state_e *state)
+{
+ if (!dev || !state)
+ return -EINVAL;
+
+ switch (blk_state) {
+ case STORAGE_EXT_REMOVED:
+ *state = STORAGE_STATE_REMOVED;
+ return 0;
+ case STORAGE_EXT_CHANGED:
+ switch (dev->state) {
+ case STORAGE_EXT_UNMOUNTED:
+ *state = STORAGE_STATE_UNMOUNTABLE;
+ return 0;
+ case STORAGE_EXT_MOUNTED:
+ if (dev->flags & MOUNT_READONLY)
+ *state = STORAGE_STATE_MOUNTED_READ_ONLY;
+ else
+ *state = STORAGE_STATE_MOUNTED;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+int storage_ext_foreach_device_list(storage_device_supported_cb callback, void *user_data)
+{
+ int ret;
+ bool ret_cb;
+ dd_list *list = NULL, *elem;
+ storage_ext_device *dev;
+ storage_state_e state;
+
+ if (!callback)
+ return -EINVAL;
+
+ ret = storage_ext_get_list(&list);
+ if (ret < 0) {
+ _E("Failed to get external storage list from deviced (%d)", errno);
+ return ret;
+ }
+
+ DD_LIST_FOREACH(list, elem, dev) {
+ ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state);
+ if (ret < 0) {
+ _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret);
+ continue;
+ }
+
+ ret_cb = callback(dev->storage_id, STORAGE_TYPE_EXTERNAL,
+ state, dev->mount_point, user_data);
+ if (!ret_cb)
+ break;
+ }
+
+ if (list)
+ storage_ext_release_list(&list);
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __STORAGE_EXTERNAL_H__
+#define __STORAGE_EXTERNAL_H__
+
+#include <stdio.h>
+#include "common.h"
+#include "storage-external-dbus.h"
+
+int storage_ext_foreach_device_list(storage_device_supported_cb callback, void *user_data);
+
+#endif /* __STORAGE_EXTERNAL_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/statvfs.h>
-#include <vconf.h>
-#include <tzplatform_config.h>
-
-#include "common.h"
-#include "list.h"
-#include "log.h"
-
-#define SDCARD_NODE "sdcard"
-
-#ifndef __USE_FILE_OFFSET64
-int __WEAK__ storage_get_external_memory_size(struct statvfs *buf);
-#else
-int __WEAK__ storage_get_external_memory_size64(struct statvfs *buf);
-#endif
-
-static dd_list *cb_list[STORAGE_CALLBACK_MAX];
-
-static int sdcard_get_state(void)
-{
- int val, ret;
-
- ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &val);
- if (ret < 0)
- return -EPERM;
-
- switch (val) {
- case VCONFKEY_SYSMAN_MMC_MOUNTED:
- return STORAGE_STATE_MOUNTED;
- case VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED:
- return STORAGE_STATE_UNMOUNTABLE;
- case VCONFKEY_SYSMAN_MMC_REMOVED:
- default:
- break;
- }
-
- return STORAGE_STATE_REMOVED;
-}
-
-static int sdcard_get_space(unsigned long long *total, unsigned long long *available)
-{
- storage_state_e state;
- struct statvfs s;
- int ret;
- unsigned long long t = 0, a = 0;
-
- state = sdcard_get_state();
- if (state >= STORAGE_STATE_MOUNTED) {
-#ifndef __USE_FILE_OFFSET64
- ret = storage_get_external_memory_size(&s);
-#else
- ret = storage_get_external_memory_size64(&s);
-#endif
- if (ret < 0)
- return -EPERM;
-
- t = (unsigned long long)s.f_frsize*s.f_blocks;
- a = (unsigned long long)s.f_bsize*s.f_bavail;
- }
-
- if (total)
- *total = t;
- if (available)
- *available = a;
-
- return 0;
-}
-
-static const char *sdcard_get_root(void)
-{
- return tzplatform_mkpath(TZ_SYS_MEDIA, SDCARD_NODE);
-}
-
-static void sdcard_state_cb(keynode_t *key, void *data)
-{
- struct storage_cb_info *cb_info;
- dd_list *elem;
- storage_state_e state;
-
- state = sdcard_get_state();
-
- DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_STATE], elem, cb_info)
- cb_info->state_cb(cb_info->id, state, cb_info->user_data);
-}
-
-static int register_request(enum storage_cb_type type)
-{
- switch (type) {
- case STORAGE_CALLBACK_STATE:
- return vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
- sdcard_state_cb, NULL);
- default:
- break;
- }
-
- return -EINVAL;
-}
-
-static int release_request(enum storage_cb_type type)
-{
- switch (type) {
- case STORAGE_CALLBACK_STATE:
- return vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
- sdcard_state_cb);
- default:
- break;
- }
-
- return -EINVAL;
-}
-
-static int sdcard_register_cb(enum storage_cb_type type, struct storage_cb_info *info)
-{
- struct storage_cb_info *cb_info;
- dd_list *elem;
- int ret, n;
-
- if (type < 0 || type >= STORAGE_CALLBACK_MAX)
- return -EINVAL;
-
- if (!info)
- return -EINVAL;
-
- /* check if it is the first request */
- n = DD_LIST_LENGTH(cb_list[type]);
- if (n == 0) {
- ret = register_request(type);
- if (ret < 0)
- return -EPERM;
- }
-
- /* check for the same request */
- DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
- if (cb_info->id == info->id &&
- cb_info->state_cb == info->state_cb)
- return -EEXIST;
- }
-
- /* add device changed callback to list (local) */
- cb_info = malloc(sizeof(struct storage_cb_info));
- if (!cb_info)
- return -errno;
-
- memcpy(cb_info, info, sizeof(struct storage_cb_info));
- DD_LIST_APPEND(cb_list[type], cb_info);
-
- return 0;
-}
-
-static int sdcard_unregister_cb(enum storage_cb_type type, struct storage_cb_info *info)
-{
- struct storage_cb_info *cb_info;
- dd_list *elem;
- int ret, n;
-
- if (type < 0 || type >= STORAGE_CALLBACK_MAX)
- return -EINVAL;
-
- if (!info)
- return -EINVAL;
-
- /* search for the same element with callback */
- DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
- if (cb_info->id == info->id &&
- cb_info->state_cb == info->state_cb)
- break;
- }
-
- if (!cb_info)
- return -EINVAL;
-
- /* remove device callback from list (local) */
- DD_LIST_REMOVE(cb_list[type], cb_info);
- free(cb_info);
-
- /* check if this callback is last element */
- n = DD_LIST_LENGTH(cb_list[type]);
- if (n == 0) {
- ret = release_request(type);
- if (ret < 0)
- return -EPERM;
- }
-
- return 0;
-}
-
-const struct storage_ops sdcard = {
- .type = STORAGE_TYPE_EXTERNAL,
- .root = sdcard_get_root,
- .get_state = sdcard_get_state,
- .get_space = sdcard_get_space,
- .register_cb = sdcard_register_cb,
- .unregister_cb = sdcard_unregister_cb,
-};
-
-STORAGE_OPS_REGISTER(&sdcard)
#include "common.h"
#include "list.h"
#include "log.h"
+#include "storage-external.h"
const char *dir_path[STORAGE_DIRECTORY_MAX] = {
[STORAGE_DIRECTORY_IMAGES] = "Images",
break;
}
- /* TODO external storage */
+ ret = storage_ext_foreach_device_list(callback, user_data);
+ if (ret < 0) {
+ _E("Failed to iterate external devices (%d)", ret);
+ return STORAGE_ERROR_OPERATION_FAILED;
+ }
return STORAGE_ERROR_NONE;
}