2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <sys/statvfs.h>
24 #include <tzplatform_config.h>
29 #include "storage-external-dbus.h"
31 static dd_list *cb_list[STORAGE_CALLBACK_MAX];
33 static int storage_ext_get_dev_state(storage_ext_device *dev,
34 enum storage_ext_state blk_state,
35 storage_state_e *state)
41 case STORAGE_EXT_REMOVED:
42 *state = STORAGE_STATE_REMOVED;
44 case STORAGE_EXT_CHANGED:
46 case STORAGE_EXT_UNMOUNTED:
47 *state = STORAGE_STATE_UNMOUNTABLE;
49 case STORAGE_EXT_MOUNTED:
50 if (dev->flags & MOUNT_READONLY)
51 *state = STORAGE_STATE_MOUNTED_READ_ONLY;
53 *state = STORAGE_STATE_MOUNTED;
63 int storage_ext_get_space(int storage_id,
64 unsigned long long *total, unsigned long long *available)
66 storage_state_e state;
69 unsigned long long t = 0, a = 0;
70 storage_ext_device *dev;
75 dev = calloc(1, sizeof(storage_ext_device));
77 //LCOV_EXCL_START System Error
83 ret = storage_ext_get_device_info(storage_id, dev);
85 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
89 ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state);
91 _E("Failed to get state of storage (id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
95 if (state >= STORAGE_STATE_MOUNTED) {
96 #ifndef __USE_FILE_OFFSET64
97 ret = storage_get_external_memory_size_with_path(dev->mount_point, &s);
99 ret = storage_get_external_memory_size64_with_path(dev->mount_point, &s);
102 _E("Failed to get external memory size of (%s)(ret:%d)", dev->mount_point, ret); //LCOV_EXCL_LINE
106 t = (unsigned long long)s.f_frsize*s.f_blocks;
107 a = (unsigned long long)s.f_bsize*s.f_bavail;
117 storage_ext_release_device(&dev);
121 int storage_ext_foreach_device_list(storage_device_supported_cb callback, void *user_data)
125 dd_list *list = NULL, *elem;
126 storage_ext_device *dev;
127 storage_state_e state;
132 ret = storage_ext_get_list(&list);
134 _E("Failed to get external storage list from deviced (%d)", errno); //LCOV_EXCL_LINE
138 DD_LIST_FOREACH(list, elem, dev) {
139 ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state);
141 _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret); //LCOV_EXCL_LINE
145 ret_cb = callback(dev->storage_id, STORAGE_TYPE_EXTERNAL,
146 state, dev->mount_point, user_data);
152 storage_ext_release_list(&list);
156 //LCOV_EXCL_START Not called Callback
157 static int storage_ext_state_changed(storage_ext_device *dev, enum storage_ext_state blk_state, void *data)
159 enum storage_cb_type type = (enum storage_cb_type)data;
160 struct storage_cb_info *cb_info;
162 storage_state_e state;
168 if (type != STORAGE_CALLBACK_STATE)
171 ret = storage_ext_get_dev_state(dev, blk_state, &state);
173 _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret);
177 DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_STATE], elem, cb_info)
178 cb_info->state_cb(cb_info->id, state, cb_info->user_data);
184 int storage_ext_register_cb(enum storage_cb_type type, struct storage_cb_info *info)
186 struct storage_cb_info *cb_info;
190 if (type < 0 || type >= STORAGE_CALLBACK_MAX)
196 /* check if it is the first request */
197 n = DD_LIST_LENGTH(cb_list[type]);
199 ret = storage_ext_register_device_change(storage_ext_state_changed, (void *)type);
204 /* check for the same request */
205 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
206 if (cb_info->id == info->id &&
207 cb_info->state_cb == info->state_cb)
211 /* add device changed callback to list (local) */
212 cb_info = malloc(sizeof(struct storage_cb_info));
216 memcpy(cb_info, info, sizeof(struct storage_cb_info));
217 DD_LIST_APPEND(cb_list[type], cb_info);
222 int storage_ext_unregister_cb(enum storage_cb_type type, struct storage_cb_info *info)
224 struct storage_cb_info *cb_info;
228 if (type < 0 || type >= STORAGE_CALLBACK_MAX)
234 /* search for the same element with callback */
235 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
236 if (cb_info->id == info->id &&
237 cb_info->state_cb == info->state_cb)
244 /* remove device callback from list (local) */
245 DD_LIST_REMOVE(cb_list[type], cb_info);
248 /* check if this callback is last element */
249 n = DD_LIST_LENGTH(cb_list[type]);
251 storage_ext_unregister_device_change(storage_ext_state_changed);
256 int storage_ext_get_root(int storage_id, char *path, size_t len)
258 storage_ext_device *dev;
267 dev = calloc(1, sizeof(storage_ext_device));
269 //LCOV_EXCL_START System Error
275 ret = storage_ext_get_device_info(storage_id, dev);
277 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
281 snprintf(path, len, "%s", dev->mount_point);
285 storage_ext_release_device(&dev);
289 int storage_ext_get_state(int storage_id, storage_state_e *state)
291 storage_ext_device *dev;
300 dev = calloc(1, sizeof(storage_ext_device));
302 //LCOV_EXCL_START System Error
308 ret = storage_ext_get_device_info(storage_id, dev);
310 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
314 ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, state);
316 _E("Failed to get state of storage id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
319 storage_ext_release_device(&dev);
323 int storage_ext_get_primary_mmc_path(char *path, size_t len)
325 dd_list *list = NULL, *elem;
326 storage_ext_device *dev;
329 ret = storage_ext_get_list(&list);
331 _E("Failed to get external storage list from deviced (%d)", errno); //LCOV_EXCL_LINE
335 DD_LIST_FOREACH(list, elem, dev) {
337 snprintf(path, len, "%s", dev->mount_point);
347 storage_ext_release_list(&list);