2 * Copyright (c) 2011 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.
27 #include "storage-external.h"
29 const char *dir_path[STORAGE_DIRECTORY_MAX] = {
30 [STORAGE_DIRECTORY_IMAGES] = "Images",
31 [STORAGE_DIRECTORY_SOUNDS] = "Sounds",
32 [STORAGE_DIRECTORY_VIDEOS] = "Videos",
33 [STORAGE_DIRECTORY_CAMERA] = "Camera",
34 [STORAGE_DIRECTORY_DOWNLOADS] = "Downloads",
35 [STORAGE_DIRECTORY_MUSIC] = "Music",
36 [STORAGE_DIRECTORY_DOCUMENTS] = "Documents",
37 [STORAGE_DIRECTORY_OTHERS] = "Others",
38 [STORAGE_DIRECTORY_SYSTEM_RINGTONES] = "",
41 static dd_list *st_int_head; /* Internal storage list */
43 static dd_list *compat_cb_list;
44 struct compat_cb_info {
45 storage_state_changed_cb user_cb;
49 void add_device(const struct storage_ops *st)
51 DD_LIST_APPEND(st_int_head, st);
54 void remove_device(const struct storage_ops *st)
56 DD_LIST_REMOVE(st_int_head, st);
59 API int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data)
61 const struct storage_ops *st;
66 _E("Invalid parameter");
67 return STORAGE_ERROR_INVALID_PARAMETER;
70 DD_LIST_FOREACH(st_int_head, elem, st) {
71 ret = callback(st->storage_id, st->type, st->get_state(),
72 st->root(), user_data);
73 /* if the return value is false, will be stop to iterate */
78 ret = storage_ext_foreach_device_list(callback, user_data);
80 _E("Failed to iterate external devices (%d)", ret); //LCOV_EXCL_LINE
81 return STORAGE_ERROR_OPERATION_FAILED;
84 return STORAGE_ERROR_NONE;
87 API int storage_get_root_directory(int storage_id, char **path)
89 const struct storage_ops *st;
95 return STORAGE_ERROR_NOT_SUPPORTED;
98 _E("Invalid parameger");
99 return STORAGE_ERROR_INVALID_PARAMETER;
102 /* internal storage */
103 DD_LIST_FOREACH(st_int_head, elem, st) {
104 if (st->storage_id != storage_id)
106 *path = strdup(st->root());
108 //LCOV_EXCL_START System Error
109 _E("Failed to copy the root string : %d", errno);
110 return STORAGE_ERROR_OUT_OF_MEMORY;
113 return STORAGE_ERROR_NONE;
116 /* external storage */
117 ret = storage_ext_get_root(storage_id, root, sizeof(root));
119 _E("Failed to get root path of external storage(%d, %d", storage_id, ret); //LCOV_EXCL_LINE
120 return STORAGE_ERROR_INVALID_PARAMETER;
123 *path = strdup(root);
125 _E("Failed to copy the root string : %d", errno);
126 return STORAGE_ERROR_OUT_OF_MEMORY;
129 return STORAGE_ERROR_NONE;
132 API int storage_get_directory(int storage_id, storage_directory_e type, char **path)
134 const struct storage_ops *st;
143 return STORAGE_ERROR_NOT_SUPPORTED;
146 _E("Invalid parameger");
147 return STORAGE_ERROR_INVALID_PARAMETER;
150 if (type < 0 || type >= STORAGE_DIRECTORY_MAX) {
151 _E("Invalid parameter");
152 return STORAGE_ERROR_INVALID_PARAMETER;
155 /* internal storage */
157 DD_LIST_FOREACH(st_int_head, elem, st) {
158 if (st->storage_id != storage_id)
165 snprintf(root, sizeof(root), "%s", st->root());
166 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
167 temp2 = vconf_get_str(VCONFKEY_SETAPPL_CALL_RINGTONE_PATH_STR);
169 return STORAGE_ERROR_OPERATION_FAILED;
170 end = strrchr(temp2, '/');
173 snprintf(temp, PATH_MAX, "%s", temp2);
176 snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type]);
181 /* external storage */
182 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
183 _E("Not support directory : id(%d) type(%d)", storage_id, type); //LCOV_EXCL_LINE
184 return STORAGE_ERROR_NOT_SUPPORTED;
187 ret = storage_ext_get_root(storage_id, root, sizeof(root));
189 _E("Failed to get root dir for external storage(id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
190 return STORAGE_ERROR_OPERATION_FAILED;
193 snprintf(temp, sizeof(temp), "%s/%s", root, dir_path[type]);
196 *path = strdup(temp);
198 _E("Failed to copy the directory(%d) string : %d", type, errno); //LCOV_EXCL_LINE
199 return STORAGE_ERROR_OUT_OF_MEMORY;
202 return STORAGE_ERROR_NONE;
205 API int storage_get_type(int storage_id, storage_type_e *type)
207 const struct storage_ops *st;
211 return STORAGE_ERROR_NOT_SUPPORTED;
214 _E("Invalid parameger");
215 return STORAGE_ERROR_INVALID_PARAMETER;
218 /* internal storage */
219 DD_LIST_FOREACH(st_int_head, elem, st) {
220 if (st->storage_id != storage_id)
223 return STORAGE_ERROR_NONE;
226 /* external storage */
227 *type = STORAGE_TYPE_EXTERNAL;
229 return STORAGE_ERROR_NONE;
232 API int storage_get_state(int storage_id, storage_state_e *state)
234 const struct storage_ops *ops;
240 return STORAGE_ERROR_NOT_SUPPORTED;
243 _E("Invalid parameger");
244 return STORAGE_ERROR_INVALID_PARAMETER;
247 /* internal storage */
248 DD_LIST_FOREACH(st_int_head, elem, ops) {
249 if (ops->storage_id != storage_id)
251 *state = ops->get_state();
252 return STORAGE_ERROR_NONE;
255 /* external storage */
256 ret = storage_ext_get_state(storage_id, &st);
258 _E("Failed to get state (storage id(%d), ret(%d))", storage_id, ret); //LCOV_EXCL_LINE
259 return STORAGE_ERROR_OPERATION_FAILED;
263 return STORAGE_ERROR_NONE;
266 static void compat_cb(int storage_id,
267 storage_dev_e dev, storage_state_e state,
268 const char *fstype, const char *fsuuid, const char *mountpath,
269 bool primary, int flags, void *user_data)
271 struct compat_cb_info* ccb_info;
274 if (storage_id == STORAGE_TYPE_EXTERNAL && dev == STORAGE_DEV_EXT_SDCARD)
275 DD_LIST_FOREACH(compat_cb_list, elem, ccb_info)
276 ccb_info->user_cb(storage_id, state, ccb_info->user_data);
279 API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data)
281 const struct storage_ops *st;
282 struct storage_cb_info info;
286 struct compat_cb_info* ccb_info;
287 static int compat_cb_init = 0;
290 return STORAGE_ERROR_NOT_SUPPORTED;
293 _E("Invalid parameger");
294 return STORAGE_ERROR_INVALID_PARAMETER;
297 /* For backward compatability */
298 if (storage_id == STORAGE_TYPE_EXTERNAL) {
299 if (!compat_cb_init) {
300 ret = storage_set_changed_cb(STORAGE_TYPE_EXTERNAL, compat_cb, NULL);
301 if (ret == STORAGE_ERROR_NONE)
307 ccb_info = malloc(sizeof(struct compat_cb_info));
308 if (ccb_info == NULL)
309 return STORAGE_ERROR_OPERATION_FAILED;
310 ccb_info->user_cb = callback;
311 ccb_info->user_data = user_data;
312 DD_LIST_APPEND(compat_cb_list, ccb_info);
314 return STORAGE_ERROR_NONE;
317 /* Internal storage does not support registering changed callback */
318 DD_LIST_FOREACH(st_int_head, elem, st)
319 if (st->storage_id == storage_id)
320 return STORAGE_ERROR_NONE;
322 /* external storage */
323 info.id = storage_id;
324 info.state_cb = callback;
325 info.user_data = user_data;
327 ret = storage_ext_register_cb(STORAGE_CALLBACK_ID, &info);
329 _E("Failed to register callback : id(%d)", storage_id); //LCOV_EXCL_LINE
330 return STORAGE_ERROR_OPERATION_FAILED;
333 return STORAGE_ERROR_NONE;
336 API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback)
338 const struct storage_ops *st;
339 struct storage_cb_info info;
344 return STORAGE_ERROR_NOT_SUPPORTED;
347 _E("Invalid parameger");
348 return STORAGE_ERROR_INVALID_PARAMETER;
351 /* For backward compatability */
352 if (storage_id == STORAGE_TYPE_EXTERNAL) {
354 struct compat_cb_info* ccb_info;
356 DD_LIST_FOREACH_SAFE(compat_cb_list, elem, elem_n, ccb_info) {
357 if (ccb_info->user_cb == callback) {
358 DD_LIST_REMOVE(compat_cb_list, ccb_info);
360 return STORAGE_ERROR_NONE;
363 return STORAGE_ERROR_OPERATION_FAILED;
366 /* Internal storage does not support registering changed callback */
367 DD_LIST_FOREACH(st_int_head, elem, st)
368 if (st->storage_id == storage_id)
369 return STORAGE_ERROR_NONE;
371 /* external storage */
372 info.id = storage_id;
373 info.state_cb = callback;
375 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_ID, &info);
377 _E("Failed to unregister callback : id(%d)", storage_id); //LCOV_EXCL_LINE
378 return STORAGE_ERROR_OPERATION_FAILED;
381 return STORAGE_ERROR_NONE;
384 API int storage_get_total_space(int storage_id, unsigned long long *bytes)
386 const struct storage_ops *st;
387 unsigned long long total;
392 return STORAGE_ERROR_NOT_SUPPORTED;
395 _E("Invalid parameger");
396 return STORAGE_ERROR_INVALID_PARAMETER;
399 /* internal storage */
400 DD_LIST_FOREACH(st_int_head, elem, st) {
401 if (st->storage_id != storage_id)
403 ret = st->get_space(&total, NULL);
407 /* external storage */
408 ret = storage_ext_get_space(storage_id, &total, NULL);
412 _E("Failed to get total memory : id(%d)", storage_id); //LCOV_EXCL_LINE
414 return STORAGE_ERROR_NOT_SUPPORTED;
415 return STORAGE_ERROR_OPERATION_FAILED;
419 return STORAGE_ERROR_NONE;
422 API int storage_get_available_space(int storage_id, unsigned long long *bytes)
424 const struct storage_ops *st;
425 unsigned long long avail;
430 return STORAGE_ERROR_NOT_SUPPORTED;
433 _E("Invalid parameger");
434 return STORAGE_ERROR_INVALID_PARAMETER;
437 /* internal storage */
438 DD_LIST_FOREACH(st_int_head, elem, st) {
439 if (st->storage_id != storage_id)
441 ret = st->get_space(NULL, &avail);
445 /* external storage */
446 ret = storage_ext_get_space(storage_id, NULL, &avail);
450 _E("Failed to get available memory : id(%d)", storage_id); //LCOV_EXCL_LINE
452 return STORAGE_ERROR_NOT_SUPPORTED;
453 return STORAGE_ERROR_OPERATION_FAILED;
457 return STORAGE_ERROR_NONE;
460 API int storage_set_changed_cb(storage_type_e type, storage_changed_cb callback, void *user_data)
463 struct storage_cb_info info;
465 if (type == STORAGE_TYPE_INTERNAL) {
466 _E("Internal storage is not supported");
467 return STORAGE_ERROR_NOT_SUPPORTED;
470 if (type != STORAGE_TYPE_EXTERNAL) {
471 _E("Invalid type (%d)", type);
472 return STORAGE_ERROR_INVALID_PARAMETER;
476 _E("Callback is NULL");
477 return STORAGE_ERROR_INVALID_PARAMETER;
480 /* external storage */
482 info.type_cb = callback;
483 info.user_data = user_data;
485 ret = storage_ext_register_cb(STORAGE_CALLBACK_TYPE, &info);
487 _E("Failed to register storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
488 return STORAGE_ERROR_OPERATION_FAILED;
491 return STORAGE_ERROR_NONE;
494 API int storage_unset_changed_cb(storage_type_e type, storage_changed_cb callback)
496 struct storage_cb_info info;
499 if (type == STORAGE_TYPE_INTERNAL) {
500 _E("Internal storage is not supported");
501 return STORAGE_ERROR_NOT_SUPPORTED;
504 if (type != STORAGE_TYPE_EXTERNAL) {
505 _E("Invalid type (%d)", type);
506 return STORAGE_ERROR_INVALID_PARAMETER;
510 _E("Callback is NULL");
511 return STORAGE_ERROR_INVALID_PARAMETER;
514 /* external storage */
516 info.type_cb = callback;
518 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_TYPE, &info);
520 _E("Failed to unregister storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
521 return STORAGE_ERROR_OPERATION_FAILED;
524 return STORAGE_ERROR_NONE;