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.
23 #include <tzplatform_config.h>
28 #include "storage-external.h"
30 #define BLOCK_CONF_FILE "/etc/storaged/block.conf"
31 #define USER_UID_START 5000
33 const char *dir_path[STORAGE_DIRECTORY_MAX];
35 const int tz_id[STORAGE_DIRECTORY_MAX] = {
36 [STORAGE_DIRECTORY_IMAGES] = TZ_USER_IMAGES,
37 [STORAGE_DIRECTORY_SOUNDS] = TZ_USER_SOUNDS,
38 [STORAGE_DIRECTORY_VIDEOS] = TZ_USER_VIDEOS,
39 [STORAGE_DIRECTORY_CAMERA] = TZ_USER_CAMERA,
40 [STORAGE_DIRECTORY_DOWNLOADS] = TZ_USER_DOWNLOADS,
41 [STORAGE_DIRECTORY_MUSIC] = TZ_USER_MUSIC,
42 [STORAGE_DIRECTORY_DOCUMENTS] = TZ_USER_DOCUMENTS,
43 [STORAGE_DIRECTORY_OTHERS] = TZ_USER_OTHERS,
46 static dd_list *st_int_head; /* Internal storage list */
48 static dd_list *compat_cb_list;
49 struct compat_cb_info {
50 storage_state_changed_cb user_cb;
54 void add_device(const struct storage_ops *st)
56 DD_LIST_APPEND(st_int_head, st);
59 void remove_device(const struct storage_ops *st)
61 DD_LIST_REMOVE(st_int_head, st);
64 int storage_ext_is_supported(void)
66 static int support = -1;
71 if (access(BLOCK_CONF_FILE, R_OK) == 0)
79 API int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data)
81 const struct storage_ops *st;
87 _E("Invalid parameter");
88 return STORAGE_ERROR_INVALID_PARAMETER;
91 if (getuid() < USER_UID_START)
94 DD_LIST_FOREACH(st_int_head, elem, st) {
96 ret = callback(st->storage_id, st->type, st->get_state(),
97 st->root(), user_data);
98 /* if the return value is false, will be stop to iterate */
104 if (!storage_ext_is_supported()) {
105 _D("Block module is not enabled");
106 return STORAGE_ERROR_NONE;
109 ret = storage_ext_foreach_device_list(callback, user_data);
111 _E("Failed to iterate external devices (%d)", ret); //LCOV_EXCL_LINE
112 return STORAGE_ERROR_OPERATION_FAILED;
115 return STORAGE_ERROR_NONE;
118 API int storage_get_root_directory(int storage_id, char **path)
120 const struct storage_ops *st;
128 return STORAGE_ERROR_NOT_SUPPORTED;
131 _E("Invalid parameger");
132 return STORAGE_ERROR_INVALID_PARAMETER;
135 if (getuid() < USER_UID_START)
138 /* internal storage */
139 DD_LIST_FOREACH(st_int_head, elem, st) {
140 if (st->storage_id != storage_id)
143 _E("Only Tizen applications and user session daemons can use \
144 storage_get_root_directory(id , ...)");
145 return STORAGE_ERROR_INVALID_PARAMETER;
148 *path = strdup(st->root());
150 //LCOV_EXCL_START System Error
151 _E("Failed to copy the root string : %d", errno);
152 return STORAGE_ERROR_OUT_OF_MEMORY;
155 return STORAGE_ERROR_NONE;
158 /* external storage */
159 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
161 _E("Failed to get root path of external storage(%d, %d", storage_id, ret); //LCOV_EXCL_LINE
162 return STORAGE_ERROR_INVALID_PARAMETER;
165 *path = strdup(root);
167 _E("Failed to copy the root string : %d", errno); //LCOV_EXCL_LINE System Error
168 return STORAGE_ERROR_OUT_OF_MEMORY;
171 return STORAGE_ERROR_NONE;
174 API int storage_get_directory(int storage_id, storage_directory_e type, char **path)
176 const struct storage_ops *st;
187 return STORAGE_ERROR_NOT_SUPPORTED;
190 _E("Invalid parameger");
191 return STORAGE_ERROR_INVALID_PARAMETER;
194 if (type < 0 || type >= STORAGE_DIRECTORY_MAX) {
195 _E("Invalid parameter");
196 return STORAGE_ERROR_INVALID_PARAMETER;
199 /* internal storage */
201 DD_LIST_FOREACH(st_int_head, elem, st) {
202 if (st->storage_id != storage_id)
208 if (getuid() < USER_UID_START)
213 _E("Only Tizen applications and user session daemons can use \
214 storage_get_directory(id, ...)");
215 return STORAGE_ERROR_INVALID_PARAMETER;
218 snprintf(root, sizeof(root), "%s", st->root());
219 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
220 temp2 = vconf_get_str(VCONFKEY_SETAPPL_CALL_RINGTONE_PATH_STR);
222 return STORAGE_ERROR_OPERATION_FAILED;
223 end = strrchr(temp2, '/');
226 snprintf(temp, PATH_MAX, "%s", temp2);
229 snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type]);
234 /* external storage */
235 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
236 _E("Not support directory : id(%d) type(%d)", storage_id, type); //LCOV_EXCL_LINE
237 return STORAGE_ERROR_NOT_SUPPORTED;
240 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
242 _E("Failed to get root dir for external storage(id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
243 return STORAGE_ERROR_NOT_SUPPORTED;
245 /* The operation is not decided */
247 return STORAGE_ERROR_NOT_SUPPORTED;
249 snprintf(temp, sizeof(temp), "%s/%s", root, dir_path[type]);
252 *path = strdup(temp);
254 _E("Failed to copy the directory(%d) string : %d", type, errno); //LCOV_EXCL_LINE
255 return STORAGE_ERROR_OUT_OF_MEMORY;
258 return STORAGE_ERROR_NONE;
261 API int storage_get_type(int storage_id, storage_type_e *type)
263 const struct storage_ops *st;
270 return STORAGE_ERROR_NOT_SUPPORTED;
273 _E("Invalid parameger");
274 return STORAGE_ERROR_INVALID_PARAMETER;
277 /* internal storage */
278 DD_LIST_FOREACH(st_int_head, elem, st) {
279 if (st->storage_id != storage_id)
282 return STORAGE_ERROR_NONE;
285 /* external storage */
286 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
288 _E("Failed to get type of external storage");
289 return STORAGE_ERROR_NOT_SUPPORTED;
292 *type = STORAGE_TYPE_EXTENDED_INTERNAL;
294 *type = STORAGE_TYPE_EXTERNAL;
296 return STORAGE_ERROR_NONE;
299 API int storage_get_state(int storage_id, storage_state_e *state)
301 const struct storage_ops *ops;
307 return STORAGE_ERROR_NOT_SUPPORTED;
310 _E("Invalid parameger");
311 return STORAGE_ERROR_INVALID_PARAMETER;
314 /* internal storage */
315 DD_LIST_FOREACH(st_int_head, elem, ops) {
316 if (ops->storage_id != storage_id)
318 *state = ops->get_state();
319 return STORAGE_ERROR_NONE;
322 /* external storage */
323 ret = storage_ext_get_state(storage_id, &st);
325 _E("Failed to get state (storage id(%d), ret(%d))", storage_id, ret); //LCOV_EXCL_LINE
326 return STORAGE_ERROR_OPERATION_FAILED;
330 return STORAGE_ERROR_NONE;
333 //LCOV_EXCL_START Not called Callback
334 static void compat_cb(int storage_id,
335 storage_dev_e dev, storage_state_e state,
336 const char *fstype, const char *fsuuid, const char *mountpath,
337 bool primary, int flags, void *user_data)
339 struct compat_cb_info* ccb_info;
342 if (storage_id == STORAGE_TYPE_EXTERNAL && dev == STORAGE_DEV_EXT_SDCARD)
343 DD_LIST_FOREACH(compat_cb_list, elem, ccb_info)
344 ccb_info->user_cb(storage_id, state, ccb_info->user_data);
348 API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data)
350 const struct storage_ops *st;
351 struct storage_cb_info info;
355 struct compat_cb_info* ccb_info;
356 static int compat_cb_init = 0;
359 return STORAGE_ERROR_NOT_SUPPORTED;
362 _E("Invalid parameger");
363 return STORAGE_ERROR_INVALID_PARAMETER;
366 /* For backward compatability */
367 if (storage_id == STORAGE_TYPE_EXTERNAL) {
368 if (!compat_cb_init) {
369 ret = storage_set_changed_cb(STORAGE_TYPE_EXTERNAL, compat_cb, NULL);
370 if (ret == STORAGE_ERROR_NONE)
376 ccb_info = malloc(sizeof(struct compat_cb_info));
377 if (ccb_info == NULL)
378 return STORAGE_ERROR_OPERATION_FAILED;
379 ccb_info->user_cb = callback;
380 ccb_info->user_data = user_data;
381 DD_LIST_APPEND(compat_cb_list, ccb_info);
383 return STORAGE_ERROR_NONE;
386 /* Internal storage does not support registering changed callback */
387 DD_LIST_FOREACH(st_int_head, elem, st)
388 if (st->storage_id == storage_id)
389 return STORAGE_ERROR_NONE;
391 /* external storage */
392 info.id = storage_id;
393 info.state_cb = callback;
394 info.user_data = user_data;
396 ret = storage_ext_register_cb(STORAGE_CALLBACK_ID, &info);
398 _E("Failed to register callback : id(%d)", storage_id); //LCOV_EXCL_LINE
399 return STORAGE_ERROR_OPERATION_FAILED;
402 return STORAGE_ERROR_NONE;
405 API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback)
407 const struct storage_ops *st;
408 struct storage_cb_info info;
413 return STORAGE_ERROR_NOT_SUPPORTED;
416 _E("Invalid parameger");
417 return STORAGE_ERROR_INVALID_PARAMETER;
420 /* For backward compatability */
421 if (storage_id == STORAGE_TYPE_EXTERNAL) {
423 struct compat_cb_info* ccb_info;
425 DD_LIST_FOREACH_SAFE(compat_cb_list, elem, elem_n, ccb_info) {
426 if (ccb_info->user_cb == callback) {
427 DD_LIST_REMOVE(compat_cb_list, ccb_info);
429 return STORAGE_ERROR_NONE;
432 return STORAGE_ERROR_OPERATION_FAILED;
435 /* Internal storage does not support registering changed callback */
436 DD_LIST_FOREACH(st_int_head, elem, st)
437 if (st->storage_id == storage_id)
438 return STORAGE_ERROR_NONE;
440 /* external storage */
441 info.id = storage_id;
442 info.state_cb = callback;
444 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_ID, &info);
446 _E("Failed to unregister callback : id(%d)", storage_id); //LCOV_EXCL_LINE
447 return STORAGE_ERROR_OPERATION_FAILED;
450 return STORAGE_ERROR_NONE;
453 API int storage_get_total_space(int storage_id, unsigned long long *bytes)
455 const struct storage_ops *st;
456 unsigned long long total;
461 return STORAGE_ERROR_NOT_SUPPORTED;
464 _E("Invalid parameger");
465 return STORAGE_ERROR_INVALID_PARAMETER;
468 /* internal storage */
469 DD_LIST_FOREACH(st_int_head, elem, st) {
470 if (st->storage_id != storage_id)
472 ret = st->get_space(&total, NULL);
476 /* external storage */
477 ret = storage_ext_get_space(storage_id, &total, NULL);
481 _E("Failed to get total memory : id(%d)", storage_id); //LCOV_EXCL_LINE
483 return STORAGE_ERROR_NOT_SUPPORTED;
484 return STORAGE_ERROR_OPERATION_FAILED;
488 return STORAGE_ERROR_NONE;
491 API int storage_get_available_space(int storage_id, unsigned long long *bytes)
493 const struct storage_ops *st;
494 unsigned long long avail;
499 return STORAGE_ERROR_NOT_SUPPORTED;
502 _E("Invalid parameger");
503 return STORAGE_ERROR_INVALID_PARAMETER;
506 /* internal storage */
507 DD_LIST_FOREACH(st_int_head, elem, st) {
508 if (st->storage_id != storage_id)
510 ret = st->get_space(NULL, &avail);
514 /* external storage */
515 ret = storage_ext_get_space(storage_id, NULL, &avail);
519 _E("Failed to get available memory : id(%d)", storage_id); //LCOV_EXCL_LINE
521 return STORAGE_ERROR_NOT_SUPPORTED;
522 return STORAGE_ERROR_OPERATION_FAILED;
526 return STORAGE_ERROR_NONE;
529 API int storage_set_changed_cb(storage_type_e type, storage_changed_cb callback, void *user_data)
532 struct storage_cb_info info;
534 if (type == STORAGE_TYPE_INTERNAL) {
535 _E("Internal storage is not supported");
536 return STORAGE_ERROR_NOT_SUPPORTED;
539 if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
540 _E("Invalid type (%d)", type);
541 return STORAGE_ERROR_INVALID_PARAMETER;
545 _E("Callback is NULL");
546 return STORAGE_ERROR_INVALID_PARAMETER;
549 if (!storage_ext_is_supported()) {
550 _E("Block module is not enabled");
551 return STORAGE_ERROR_NOT_SUPPORTED;
554 /* external storage */
556 info.type_cb = callback;
557 info.user_data = user_data;
559 ret = storage_ext_register_cb(STORAGE_CALLBACK_TYPE, &info);
561 _E("Failed to register storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
562 return STORAGE_ERROR_OPERATION_FAILED;
565 return STORAGE_ERROR_NONE;
568 API int storage_unset_changed_cb(storage_type_e type, storage_changed_cb callback)
570 struct storage_cb_info info;
573 if (type == STORAGE_TYPE_INTERNAL) {
574 _E("Internal storage is not supported");
575 return STORAGE_ERROR_NOT_SUPPORTED;
578 if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
579 _E("Invalid type (%d)", type);
580 return STORAGE_ERROR_INVALID_PARAMETER;
584 _E("Callback is NULL");
585 return STORAGE_ERROR_INVALID_PARAMETER;
588 if (!storage_ext_is_supported()) {
589 _E("Block module is not enabled");
590 return STORAGE_ERROR_NOT_SUPPORTED;
593 /* external storage */
595 info.type_cb = callback;
597 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_TYPE, &info);
599 _E("Failed to unregister storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
600 return STORAGE_ERROR_OPERATION_FAILED;
603 return STORAGE_ERROR_NONE;
606 static void __CONSTRUCTOR__ init(void)
612 for (i = 0 ; i <= STORAGE_DIRECTORY_OTHERS ; i++) {
613 tmp = tzplatform_getenv(tz_id[i]);
615 token = rindex(tmp, '/');
618 dir_path[i] = strdup(token);