From 4306eaee52ee3fcd853fb2b9f08ce69c8e8e7093 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Tue, 3 Jul 2018 11:44:20 +0900 Subject: [PATCH] Add internal apis to mount/unmount/format primary sdcard - storage_request_mount_mmc - storage_request_unmount_mmc - storage_request_format_mmc - storage_format_mmc Change-Id: I48bef7b586da884d314bbc64a5938e363c7ca00f Signed-off-by: pr.jung --- include/storage-internal.h | 82 +++++++++++++++++++ src/storage-external-dbus.c | 78 ++++++++++++++++++ src/storage-external-dbus.h | 4 + src/storage-inhouse.c | 193 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 357 insertions(+) diff --git a/include/storage-internal.h b/include/storage-internal.h index 53795d2..e3bd50a 100644 --- a/include/storage-internal.h +++ b/include/storage-internal.h @@ -50,6 +50,8 @@ extern "C" { * @retval #STORAGE_ERROR_NONE Successful * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #STORAGE_ERROR_NO_DEVICE No such device + * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed + * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory */ int storage_get_primary_sdcard(int *storage_id, char **path); @@ -58,6 +60,86 @@ int storage_get_origin_internal_path(const char* compat, int len, char* origin); int storage_get_storage_level(const char *path, char **level); /** + * @brief This structure defines the data for receive result of mmc operations(mount/unmount/format) + */ +struct mmc_contents { + void (*mmc_cb) (int result, void* data); /**< user callback function for receive result of mmc operations */ + void* user_data; /**< input data for callback function's second-param(data) */ +}; + +/** + * @brief This API is used to mount mmc.\n + * + * @param[in] mmc_data for receive result of mount operation + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_NO_DEVICE No such device + * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed + * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory + */ +int storage_request_mount_mmc(struct mmc_contents *mmc_data); + +/** + * @brief This API is used to unmount mmc.\n + * + * @param[in] mmc_data for receive result of unmount operation + * @param[in] option type of unmount option \n + * 0 : Normal unmount \n + * (if other process still access a sdcard, \n + * unmount will be failed.) \n + * 1 : Force unmount \n + * (if other process still access a sdcard, \n + * this process will be received SIGTERM or SIGKILL.) + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_NO_DEVICE No such device + * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed + * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory + */ +int storage_request_unmount_mmc(struct mmc_contents *mmc_data, int option); + +/** + * @brief This API is used to format mmc.\n + * + * @param[in] mmc_data for receive result of format operation + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_NO_DEVICE No such device + * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed + * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory + */ +int storage_request_format_mmc(struct mmc_contents *mmc_data); + +/** + * @brief This API is used to format mmc.\n + * + * @param[in] mmc_data for receive result of format operation + * @param[in] option FMT_NORMAL is 0, FMT_FORCE is 1 + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_NO_DEVICE No such device + * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed + * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory + */ +int storage_format_mmc(struct mmc_contents *mmc_data, int option); + +/** * @} */ diff --git a/src/storage-external-dbus.c b/src/storage-external-dbus.c index f070e8f..5d45189 100755 --- a/src/storage-external-dbus.c +++ b/src/storage-external-dbus.c @@ -51,6 +51,11 @@ struct storage_ext_callback { guint block_id; }; +typedef struct { + dbus_pending_cb func; + void *data; +} pending_call_data; + static dd_list *changed_list; static void storage_ext_release_internal(storage_ext_device *dev) @@ -118,6 +123,79 @@ static GDBusConnection *get_dbus_connection(void) return conn; } +static void _cb_pending(GDBusConnection *conn, + GAsyncResult *res, + gpointer user_data) +{ + GVariant *reply = NULL; + GError *err = NULL; + pending_call_data *data = (pending_call_data *)user_data; + + reply = g_dbus_connection_call_finish(conn, res, &err); + if (!reply || err) { + if (!err) + g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED, + "Error during g_dbus_connection_call"); + + if (data && data->func) + data->func(NULL, data->data, err); + goto out; + } + + if (data && data->func) + data->func(reply, data->data, err); +out: + if (err) + g_error_free(err); + if (data) + free(data); +} + +int dbus_method_async_with_reply_var(const char *dest, const char *path, + const char *iface, const char *method, GVariant *param, + dbus_pending_cb cb, int timeout, void *data) +{ + GDBusConnection *conn; + pending_call_data *pdata = NULL; + int ret = 0; + + if (!dest || !path || !iface || !method) + return -EINVAL; + + if (timeout < -1) { + _E("wrong timeout %d", timeout); + return -EINVAL; + } + + conn = get_dbus_connection(); + if (!conn) { + _E("fail to get dbus connection"); //LCOV_EXCL_LINE + return -1; + } + + if (cb) { + pdata = (pending_call_data*)malloc(sizeof(pending_call_data)); + if (!pdata) { + ret = -ENOMEM; + goto err; + } + + pdata->func = cb; + pdata->data = data; + } + + g_dbus_connection_call(conn, dest, path, iface, method, + param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, + (GAsyncReadyCallback)_cb_pending, + pdata); + + return ret; +err: + if (param) + g_variant_unref(param); + return ret; +} + GVariant *dbus_method_call_sync(const gchar *dest, const gchar *path, const gchar *iface, const gchar *method, GVariant *param) { diff --git a/src/storage-external-dbus.h b/src/storage-external-dbus.h index b71d2e4..273e388 100644 --- a/src/storage-external-dbus.h +++ b/src/storage-external-dbus.h @@ -108,6 +108,10 @@ void storage_ext_unregister_device_change(storage_ext_changed_cb func); int storage_ext_get_device_info(int storage_id, storage_ext_device *info); int storage_ext_get_storage_level(const char *path, char **level); +typedef void (*dbus_pending_cb)(GVariant *var, void *user_data, GError *err); +int dbus_method_async_with_reply_var(const char *dest, const char *path, + const char *iface, const char *method, GVariant *param, + dbus_pending_cb cb, int timeout, void *data); /* storage-internal.c */ GVariant *dbus_method_call_sync(const gchar *dest, const gchar *path, const gchar *iface, const gchar *method, GVariant *param); diff --git a/src/storage-inhouse.c b/src/storage-inhouse.c index 051b6b9..d5ed6b5 100755 --- a/src/storage-inhouse.c +++ b/src/storage-inhouse.c @@ -27,6 +27,8 @@ #include "storage-internal.h" #include "storage-external-dbus.h" +#define FORMAT_TIMEOUT (120*1000) + /* Get compat path from origin Multi-user path from TZ_USER_CONTENT/.. to /opt/usr/media/.. @@ -198,3 +200,194 @@ API int storage_get_storage_level(const char *path, char **level) return STORAGE_ERROR_NONE; } + +static void mount_mmc_cb(GVariant *var, void *user_data, GError *err) +{ + struct mmc_contents *mmc_data = (struct mmc_contents*)user_data; + int mmc_ret = -1; + + _D("mount_mmc_cb called"); + + if (!var) { + _E("no message [%s]", err->message); + mmc_ret = -EBADMSG; + goto exit; + } + + g_variant_get(var, "(i)", &mmc_ret); + + _I("Mount State : %d", mmc_ret); + +exit: + if (var) + g_variant_unref(var); + (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data); +} + +API int storage_request_mount_mmc(struct mmc_contents *mmc_data) +{ + void (*mount_cb)(GVariant *, void *, GError *) = NULL; + void *data = NULL; + char *path; + int ret; + int id; + + if (mmc_data && mmc_data->mmc_cb) { + _I("Mount callback exists"); + mount_cb = mount_mmc_cb; + data = mmc_data; + } + + ret = storage_get_primary_sdcard(&id, &path); + if (ret != STORAGE_ERROR_NONE) + return ret; + + ret = dbus_method_async_with_reply_var(STORAGE_EXT_BUS_NAME, + STORAGE_EXT_PATH_MANAGER, + STORAGE_EXT_IFACE_MANAGER, + "Mount", + g_variant_new("(is)", id, ""), + mount_cb, + -1, + data); + + _I("Mount Request %s", ret == 0 ? "Success" : "Failed"); + + if (ret == -ENOMEM) + return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error + if (ret < 0) + return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE + + return STORAGE_ERROR_NONE; +} + +static void unmount_mmc_cb(GVariant *var, void *user_data, GError *err) +{ + struct mmc_contents *mmc_data = (struct mmc_contents*)user_data; + int mmc_ret; + + _D("unmount_mmc_cb called"); + + if (!var) { + _E("no message [%s]", err->message); + mmc_ret = -EBADMSG; + goto exit; + } + + g_variant_get(var, "(i)", &mmc_ret); + + _I("Unmount State : %d", mmc_ret); + +exit: + if (var) + g_variant_unref(var); + (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data); +} + +API int storage_request_unmount_mmc(struct mmc_contents *mmc_data, int option) +{ + void (*unmount_cb)(GVariant *, void *, GError *) = NULL; + void *data = NULL; + char *path; + int ret; + int id; + + if (option < 0 || option > 1) + return STORAGE_ERROR_INVALID_PARAMETER; + + if (mmc_data && mmc_data->mmc_cb) { + _I("Unmount callback exists"); + unmount_cb = unmount_mmc_cb; + data = mmc_data; + } + + ret = storage_get_primary_sdcard(&id, &path); + if (ret != STORAGE_ERROR_NONE) + return ret; + + ret = dbus_method_async_with_reply_var(STORAGE_EXT_BUS_NAME, + STORAGE_EXT_PATH_MANAGER, + STORAGE_EXT_IFACE_MANAGER, + "Unmount", + g_variant_new("(ii)", id, option), + unmount_cb, + -1, + data); + + _I("Unmount Request %s", ret == 0 ? "Success" : "Failed"); + + if (ret == -ENOMEM) + return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error + if (ret < 0) + return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE + + return STORAGE_ERROR_NONE; +} + +static void format_mmc_cb(GVariant *var, void *user_data, GError *err) +{ + struct mmc_contents *mmc_data = (struct mmc_contents*)user_data; + int mmc_ret; + + _D("format_mmc_cb called"); + + if (!var) { + _E("no message [%s]", err->message); + mmc_ret = -EBADMSG; + goto exit; + } + + g_variant_get(var, "(i)", &mmc_ret); + + _I("Format State : %d", mmc_ret); + +exit: + if (var) + g_variant_unref(var); + (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data); +} + +API int storage_request_format_mmc(struct mmc_contents *mmc_data) +{ + return storage_format_mmc(mmc_data, 1); +} + +API int storage_format_mmc(struct mmc_contents *mmc_data, int option) +{ + void (*format_cb)(GVariant *, void *, GError *) = NULL; + void *data = NULL; + char *path; + int ret; + int id; + + if (option < 0 || option > 1) + return STORAGE_ERROR_INVALID_PARAMETER; + + if (mmc_data && mmc_data->mmc_cb) { + _I("Format callback exists"); + format_cb = format_mmc_cb; + data = mmc_data; + } + + ret = storage_get_primary_sdcard(&id, &path); + if (ret != STORAGE_ERROR_NONE) + return ret; + + ret = dbus_method_async_with_reply_var(STORAGE_EXT_BUS_NAME, + STORAGE_EXT_PATH_MANAGER, + STORAGE_EXT_IFACE_MANAGER, + "Format", + g_variant_new("(ii)", id, option), + format_cb, + FORMAT_TIMEOUT, + data); + + _I("Format Request %s", ret == 0 ? "Success" : "Failed"); + + if (ret == -ENOMEM) + return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error + if (ret < 0) + return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE + + return STORAGE_ERROR_NONE; +} -- 2.7.4