Increase line coverage using LCOV_EXCL
[platform/core/system/libstorage.git] / src / storage-external-dbus.c
index 8b66ca3..5a23bc6 100755 (executable)
 #include <stdbool.h>
 #include <errno.h>
 #include <gio/gio.h>
-#include <glib.h>
 #include <assert.h>
 #include <limits.h>
+#include <glib.h>
 #include <sys/statvfs.h>
+#include <tzplatform_config.h>
+#include <libsyscommon/libgdbus.h>
+#include <libsyscommon/list.h>
 
 #include "log.h"
 #include "storage-external-dbus.h"
 
 #define CHECK_STR(a) (a ? a : "")
 
-#define STORAGE_EXT_GET_LIST       "GetDeviceList"
-#define STORAGE_EXT_GET_STATVFS    "GetStatvfs"
+#define STORAGE_EXT_GET_LIST               "GetDeviceList"
+#define STORAGE_EXT_GET_STATVFS            "GetStatvfs"
+#define STORAGE_EXT_GET_STORAGE_LEVEL      "GetStorageLevel"
 
-#define STORAGE_EXT_DEVICE_CHANGED "DeviceChanged"
-#define STORAGE_EXT_DEVICE_ADDED   "DeviceAdded"
-#define STORAGE_EXT_DEVICE_REMOVED "DeviceRemoved"
-#define STORAGE_EXT_DEVICE_BLOCKED "DeviceBlocked"
+#define STORAGE_EXT_DEVICE_CHANGED         "DeviceChanged"
+#define STORAGE_EXT_DEVICE_ADDED           "DeviceAdded"
+#define STORAGE_EXT_DEVICE_REMOVED         "DeviceRemoved"
+#define STORAGE_EXT_DEVICE_BLOCKED         "DeviceBlocked"
 
 #define DBUS_REPLY_TIMEOUT (-1)
 
+#define GET_DBUS_CONN_OR_EXIT() \
+       ({ \
+               dbus_handle_h dbus_handle = gdbus_get_connection(G_BUS_TYPE_SYSTEM, true); \
+               if (dbus_handle == NULL) { \
+                       _E("Failed to get dbus connection"); \
+                       return -EIO; \
+               } \
+               dbus_handle; \
+       })
+
+
 struct storage_ext_callback {
        storage_ext_changed_cb func;
        void *data;
        guint block_id;
 };
 
-static dd_list *changed_list;
+static GList *changed_list;
 
 static void storage_ext_release_internal(storage_ext_device *dev)
 {
@@ -73,15 +88,15 @@ void storage_ext_release_device(storage_ext_device **dev)
        *dev = NULL;
 }
 
-void storage_ext_release_list(dd_list **list)
+void storage_ext_release_list(GList **list)
 {
        storage_ext_device *dev;
-       dd_list *elem;
+       GList *elem;
 
        if (*list == NULL)
                return;
 
-       DD_LIST_FOREACH(*list, elem, dev) {
+       SYS_G_LIST_FOREACH(*list, elem, dev) {
                storage_ext_release_internal(dev);
                free(dev);
        }
@@ -90,87 +105,40 @@ void storage_ext_release_list(dd_list **list)
        *list = NULL;
 }
 
-static GDBusConnection *get_dbus_connection(void)
+int storage_ext_get_list(GList **list)
 {
-       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) {
-//LCOV_EXCL_START System Error
-               if (err) {
-                       _E("fail to get dbus connection : %s", err->message);
-                       g_clear_error(&err);
-               } else
-                       _E("fail to get dbus connection");
-               return NULL;
-//LCOV_EXCL_STOP
-       }
-       return conn;
-}
-
-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)
-               return NULL;
-
-       conn = get_dbus_connection();
-       if (!conn) {
-               _E("fail to get dbus connection"); //LCOV_EXCL_LINE
-               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) {
-//LCOV_EXCL_START System Error
-               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;
-//LCOV_EXCL_STOP
-       }
-
-       return ret;
-}
-
-int storage_ext_get_list(dd_list **list)
-{
-       GVariant *result;
+       GVariant *reply;
        GVariantIter *iter;
        storage_ext_device *elem, info;
-       int ret;
+       int ret, ret_dbus;
 
        if (!list)
                return -EINVAL;
 
-       result = dbus_method_call_sync(STORAGE_EXT_BUS_NAME,
+       dbus_handle_h dbus_handle = GET_DBUS_CONN_OR_EXIT();
+
+       ret_dbus = gdbus_priv_call_sync_with_reply(dbus_handle,
+                       STORAGE_EXT_BUS_NAME,
                        STORAGE_EXT_PATH_MANAGER,
                        STORAGE_EXT_IFACE_MANAGER,
                        STORAGE_EXT_GET_LIST,
-                       g_variant_new("(s)", "all"));
-       if (!result) {
+                       g_variant_new("(s)", "all"),
+                       &reply);
+
+       gdbus_free_connection(dbus_handle);
+
+       if (ret_dbus < 0) {
                _E("Failed to get storage_ext device info"); //LCOV_EXCL_LINE
-               return -EIO;
+               return -EIO; //LCOV_EXCL_LINE
        }
 
-       g_variant_get(result, "(a(issssssisibii))", &iter);
+       if (!g_variant_get_safe(reply, "(a(issssssisibii))", &iter)) {
+               //LCOV_EXCL_START Dbus type error
+               _E("Failed to get params from gvariant.");
+               g_variant_unref(reply);
+               return -EIO;
+               //LCOV_EXCL_STOP
+       }
 
        while (g_variant_iter_loop(iter, "(issssssisibii)",
                                &info.type, &info.devnode, &info.syspath,
@@ -182,9 +150,11 @@ int storage_ext_get_list(dd_list **list)
 
                elem = (storage_ext_device *)malloc(sizeof(storage_ext_device));
                if (!elem) {
-                       _E("malloc() failed"); //LCOV_EXCL_LINE
+                       //LCOV_EXCL_START System error
+                       _E("malloc() failed");
                        ret = -ENOMEM;
                        goto out;
+                       //LCOV_EXCL_STOP
                }
 
                elem->type = info.type;
@@ -201,43 +171,55 @@ int storage_ext_get_list(dd_list **list)
                elem->flags = info.flags;
                elem->storage_id = info.storage_id;
 
-               DD_LIST_APPEND(*list, elem);
+               SYS_G_LIST_APPEND(*list, elem);
        }
 
-       ret = g_list_length(*list);
+       ret = SYS_G_LIST_LENGTH(*list);
 
 out:
        if (ret < 0)
                storage_ext_release_list(list); //LCOV_EXCL_LINE System Error
        g_variant_iter_free(iter);
-       g_variant_unref(result);
+       g_variant_unref(reply);
        return ret;
 }
 
 int storage_ext_get_statvfs(char *path, struct statvfs_32 *buf)
 {
-       GVariant *result;
+       GVariant *reply;
+       int ret_dbus;
        guint64 bsize, frsize, blocks, bfree, bavail, files, ffree, favail, fsid, flag, namemax;
 
        assert(buf);
 
        memset(buf, 0, sizeof(struct statvfs_32));
 
-       result = dbus_method_call_sync(STORAGE_EXT_BUS_NAME,
+       dbus_handle_h dbus_handle = GET_DBUS_CONN_OR_EXIT();
+
+       ret_dbus = gdbus_priv_call_sync_with_reply(dbus_handle,
+                       STORAGE_EXT_BUS_NAME,
                        STORAGE_EXT_PATH_STORAGE,
                        STORAGE_EXT_IFACE_STORAGE,
                        STORAGE_EXT_GET_STATVFS,
-                       g_variant_new("(s)", path));
-       if (!result) {
+                       g_variant_new("(s)", path),
+                       &reply);
+
+       gdbus_free_connection(dbus_handle);
+
+       if (ret_dbus < 0) {
                _E("Failed to get storage_ext device info"); //LCOV_EXCL_LINE
-               return -EIO;
+               return -EIO; //LCOV_EXCL_LINE
        }
 
-       g_variant_get(result, "(ttttttttttt)",
+       if (!g_variant_get_safe(reply, "(ttttttttttt)",
                        &bsize, &frsize, &blocks,
                        &bfree, &bavail, &files,
                        &ffree, &favail, &fsid,
-                       &flag, &namemax);
+                       &flag, &namemax)) {
+               _E("Failed to get params from gvariant.");
+               g_variant_unref(reply);
+               return -EIO;
+       }
 //     %llu bsize, frsize, blocks, bfree, bavail, files, ffree, favail, fsid, flag, namemax
 
        buf->f_bsize  = (unsigned long)bsize;
@@ -258,27 +240,41 @@ int storage_ext_get_statvfs(char *path, struct statvfs_32 *buf)
 
 int storage_ext_get_statvfs_size64(char *path, struct statvfs *buf)
 {
-       GVariant *result;
+       GVariant *reply;
+       int ret_dbus;
 
        assert(buf);
 
        memset(buf, 0, sizeof(struct statvfs));
 
-       result = dbus_method_call_sync(STORAGE_EXT_BUS_NAME,
+       dbus_handle_h dbus_handle = GET_DBUS_CONN_OR_EXIT();
+
+       ret_dbus = gdbus_priv_call_sync_with_reply(dbus_handle,
+                       STORAGE_EXT_BUS_NAME,
                        STORAGE_EXT_PATH_STORAGE,
                        STORAGE_EXT_IFACE_STORAGE,
                        STORAGE_EXT_GET_STATVFS,
-                       g_variant_new("(s)", path));
-       if (!result) {
+                       g_variant_new("(s)", path),
+                       &reply);
+
+       gdbus_free_connection(dbus_handle);
+
+       if (ret_dbus < 0) {
                _E("Failed to get storage_ext device info"); //LCOV_EXCL_LINE
-               return -EIO;
+               return -EIO; //LCOV_EXCL_LINE
        }
 
-       g_variant_get(result, "(ttttttttttt)",
+       if (!g_variant_get_safe(reply, "(ttttttttttt)",
                        &(buf->f_bsize), &(buf->f_frsize), &(buf->f_blocks),
                        &(buf->f_bfree), &(buf->f_bavail), &(buf->f_files),
                        &(buf->f_ffree), &(buf->f_favail), &(buf->f_fsid),
-                       &(buf->f_flag), &(buf->f_namemax));
+                       &(buf->f_flag), &(buf->f_namemax))) {
+               //LCOV_EXCL_START Dbus type error
+               _E("Failed to get params from gvariant.");
+               g_variant_unref(reply);
+               return -EIO;
+               //LCOV_EXCL_STOP
+       }
 
 //     %lu buf->f_bsize, buf->f_frsize, buf->f_fsid, buf->f_flag, buf->f_namemax
 //     %llu buf->f_blocks, buf->f_bfree, buf->f_bavail, buf->f_files, buf->f_ffree, buf->f_favail
@@ -286,13 +282,69 @@ int storage_ext_get_statvfs_size64(char *path, struct statvfs *buf)
        return 0;
 }
 
+int storage_ext_get_storage_level(const char *path, char **level)
+{
+       GVariant *reply;
+       int ret_dbus;
+       char *reply_val;
+       enum tzplatform_variable id;
+
+       if (!strcmp(path, tzplatform_getenv(TZ_SYS_USER)))
+               id = TZ_SYS_USER;
+       else if (!strcmp(path, tzplatform_getenv(TZ_SYS_TMP)))
+               id = TZ_SYS_TMP;
+       else if (!strcmp(path, tzplatform_getenv(TZ_SYS_OPT)))
+               id = TZ_SYS_OPT;
+       else {
+               _E("Invalid path");
+               return -EINVAL;
+       }
+
+       dbus_handle_h dbus_handle = GET_DBUS_CONN_OR_EXIT();
+
+       ret_dbus = gdbus_priv_call_sync_with_reply(
+                       dbus_handle,
+                       STORAGE_EXT_BUS_NAME,
+                       STORAGE_EXT_PATH_STORAGE,
+                       STORAGE_EXT_IFACE_STORAGE,
+                       STORAGE_EXT_GET_STORAGE_LEVEL,
+                       g_variant_new("(i)", id),
+                       &reply);
+
+       gdbus_free_connection(dbus_handle);
+
+       if (ret_dbus < 0) {
+               //LCOV_EXCL_START Dbus error
+               _E("Failed to get %d level", id);
+               return -EIO;
+               //LCOV_EXCL_STOP
+       }
+
+       if (!g_variant_get_safe(reply, "(s)", &reply_val)) {
+               //LCOV_EXCL_START Dbus type error
+               _E("Failed to get params from gvariant.");
+               g_variant_unref(reply);
+               return -EIO;
+               //LCOV_EXCL_STOP
+       }
+
+       *level = strdup(reply_val);
+       g_free(reply_val);
+       g_variant_unref(reply);
+
+       if (*level == NULL)
+               return -ENOMEM; //LCOV_EXCL_LINE
+
+       return 0;
+}
+
 //LCOV_EXCL_START Not called Callback
 static void storage_ext_device_changed(GVariant *params, enum storage_ext_state state, gpointer user_data)
 {
        storage_ext_device *dev;
-       dd_list *elem;
+       GList *elem;
        struct storage_ext_callback *callback;
-       int ret;
+       int ret_val;
 
        if (!params)
                return;
@@ -301,7 +353,7 @@ static void storage_ext_device_changed(GVariant *params, enum storage_ext_state
        if (!dev)
                return;
 
-       g_variant_get(params, "(issssssisibii)",
+       if (!g_variant_get_safe(params, "(issssssisibii)",
                        &dev->type,
                        &dev->devnode,
                        &dev->syspath,
@@ -314,7 +366,8 @@ static void storage_ext_device_changed(GVariant *params, enum storage_ext_state
                        &dev->state,
                        &dev->primary,
                        &dev->flags,
-                       &dev->storage_id);
+                       &dev->storage_id))
+               return;
 
        /* Callback is called when unmount is started(DeviceBlocked signal) */
        if (state == STORAGE_EXT_CHANGED && dev->state == STORAGE_EXT_UNMOUNTED) {
@@ -322,12 +375,12 @@ static void storage_ext_device_changed(GVariant *params, enum storage_ext_state
                return;
        }
 
-       DD_LIST_FOREACH(changed_list, elem, callback) {
+       SYS_G_LIST_FOREACH(changed_list, elem, callback) {
                if (!callback->func)
                        continue;
-               ret = callback->func(dev, state, callback->data);
-               if (ret < 0)
-                       _E("Failed to call callback for devnode(%s, %d)", dev->devnode, ret);
+               ret_val = callback->func(dev, state, callback->data);
+               if (ret_val < 0)
+                       _E("Failed to call callback for devnode(%s, %d)", dev->devnode, ret_val);
        }
 
        storage_ext_release_device(&dev);
@@ -376,15 +429,14 @@ static void storage_ext_changed(GDBusConnection *conn,
 
 int storage_ext_register_device_change(storage_ext_changed_cb func, void *data)
 {
-       GDBusConnection *conn;
        guint block_id = 0;
        struct storage_ext_callback *callback;
-       dd_list *elem;
+       GList *elem;
 
        if (!func)
                return -EINVAL;
 
-       DD_LIST_FOREACH(changed_list, elem, callback) {
+       SYS_G_LIST_FOREACH(changed_list, elem, callback) {
                if (callback->func != func)
                        continue;
                if (callback->block_id == 0)
@@ -401,22 +453,9 @@ int storage_ext_register_device_change(storage_ext_changed_cb func, void *data)
                //LCOV_EXCL_STOP
        }
 
-       conn = get_dbus_connection();
-       if (!conn) {
-               //LCOV_EXCL_START System Error
-               free(callback);
-               _E("Failed to get dbus connection");
-               return -EPERM;
-               //LCOV_EXCL_STOP
-       }
-
-       block_id = g_dbus_connection_signal_subscribe(conn,
-                       NULL,
+       block_id = gdbus_signal_subscribe(NULL, NULL,
                        STORAGE_EXT_IFACE_MANAGER,
                        NULL,
-                       NULL,
-                       NULL,
-                       G_DBUS_SIGNAL_FLAGS_NONE,
                        storage_ext_changed,
                        NULL,
                        NULL);
@@ -432,73 +471,76 @@ int storage_ext_register_device_change(storage_ext_changed_cb func, void *data)
        callback->data = data;
        callback->block_id = block_id;
 
-       DD_LIST_APPEND(changed_list, callback);
+       SYS_G_LIST_APPEND(changed_list, callback);
 
        return 0;
 }
 
 void storage_ext_unregister_device_change(storage_ext_changed_cb func)
 {
-       GDBusConnection *conn;
        struct storage_ext_callback *callback;
-       dd_list *elem;
-       dd_list *elem_n;
+       GList *elem;
+       GList *elem_n;
 
        if (!func)
                return;
 
-       conn = get_dbus_connection();
-       if (!conn) {
-//LCOV_EXCL_START System Error
-               _E("fail to get dbus connection");
-               return;
-//LCOV_EXCL_STOP
-       }
-
-       DD_LIST_FOREACH_SAFE(changed_list, elem, elem_n, callback) {
+       SYS_G_LIST_FOREACH_SAFE(changed_list, elem, elem_n, callback) {
                if (callback->func != func)
                        continue;
                if (callback->block_id > 0)
-                       g_dbus_connection_signal_unsubscribe(conn, callback->block_id);
+                       gdbus_signal_unsubscribe(NULL, callback->block_id);
 
-               DD_LIST_REMOVE(changed_list, callback);
+               SYS_G_LIST_REMOVE(changed_list, callback);
                free(callback);
        }
 }
 
 int storage_ext_get_device_info(int storage_id, storage_ext_device *info)
 {
-       GVariant *result;
+       GVariant *reply;
+       int ret_dbus;
 
-       result = dbus_method_call_sync(STORAGE_EXT_BUS_NAME,
+       dbus_handle_h dbus_handle = GET_DBUS_CONN_OR_EXIT();
+
+       ret_dbus = gdbus_priv_call_sync_with_reply(dbus_handle,
+                       STORAGE_EXT_BUS_NAME,
                        STORAGE_EXT_PATH_MANAGER,
                        STORAGE_EXT_IFACE_MANAGER,
                        "GetDeviceInfo",
-                       g_variant_new("(i)", storage_id));
-       if (!result) {
+                       g_variant_new("(i)", storage_id),
+                       &reply);
+
+       gdbus_free_connection(dbus_handle);
+
+       if (ret_dbus < 0) {
                _E("There is no storage with the storage id (%d)", storage_id); //LCOV_EXCL_LINE
-               return -ENODEV;
+               return -ENODEV; //LCOV_EXCL_LINE
        }
 
-       if (g_variant_check_format_string(result, "(issssssisibii)", true)) {
-               g_variant_get(result, "(issssssisibii)",
+       if (!g_variant_get_safe(reply, "(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);
-       } else {
-               _E("No storage with the storage id (%d)", storage_id); //LCOV_EXCL_LINE
-               return -ENODEV;
+                               &info->flags, &info->storage_id)) {
+               //LCOV_EXCL_START Dbus error
+               _E("No storage with the storage id (%d)", storage_id);
+               ret_dbus = -ENODEV;
+               goto out;
+               //LCOV_EXCL_STOP
        }
 
        if (info->storage_id < 0) {
-               _E("No storage with the storage id (%d)", storage_id); //LCOV_EXCL_LINE
-               return -ENODEV;
+               //LCOV_EXCL_START Dbus error
+               _E("No storage with the storage id (%d)", storage_id);
+               ret_dbus = -ENODEV;
+               goto out;
+               //LCOV_EXCL_STOP
        }
 
-       g_variant_unref(result);
-
+out:
+       g_variant_unref(reply);
        return 0;
 }