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 const char *dir_path[STORAGE_DIRECTORY_MAX];
33 const int tz_id[STORAGE_DIRECTORY_MAX] = {
34 [STORAGE_DIRECTORY_IMAGES] = TZ_USER_IMAGES,
35 [STORAGE_DIRECTORY_SOUNDS] = TZ_USER_SOUNDS,
36 [STORAGE_DIRECTORY_VIDEOS] = TZ_USER_VIDEOS,
37 [STORAGE_DIRECTORY_CAMERA] = TZ_USER_CAMERA,
38 [STORAGE_DIRECTORY_DOWNLOADS] = TZ_USER_DOWNLOADS,
39 [STORAGE_DIRECTORY_MUSIC] = TZ_USER_MUSIC,
40 [STORAGE_DIRECTORY_DOCUMENTS] = TZ_USER_DOCUMENTS,
41 [STORAGE_DIRECTORY_OTHERS] = TZ_USER_OTHERS,
44 static dd_list *st_int_head; /* Internal storage list */
46 static dd_list *compat_cb_list;
47 struct compat_cb_info {
48 storage_state_changed_cb user_cb;
52 void add_device(const struct storage_ops *st)
54 DD_LIST_APPEND(st_int_head, st);
57 void remove_device(const struct storage_ops *st)
59 DD_LIST_REMOVE(st_int_head, st);
62 int storage_ext_is_supported(void)
64 static int support = -1;
69 if (access(BLOCK_CONF_FILE, R_OK) == 0)
77 API int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data)
79 const struct storage_ops *st;
84 _E("Invalid parameter");
85 return STORAGE_ERROR_INVALID_PARAMETER;
88 DD_LIST_FOREACH(st_int_head, elem, st) {
89 ret = callback(st->storage_id, st->type, st->get_state(),
90 st->root(), user_data);
91 /* if the return value is false, will be stop to iterate */
96 if (!storage_ext_is_supported()) {
97 _D("Block module is not enabled");
98 return STORAGE_ERROR_NONE;
101 ret = storage_ext_foreach_device_list(callback, user_data);
103 _E("Failed to iterate external devices (%d)", ret); //LCOV_EXCL_LINE
104 return STORAGE_ERROR_OPERATION_FAILED;
107 return STORAGE_ERROR_NONE;
110 API int storage_get_root_directory(int storage_id, char **path)
112 const struct storage_ops *st;
119 return STORAGE_ERROR_NOT_SUPPORTED;
122 _E("Invalid parameger");
123 return STORAGE_ERROR_INVALID_PARAMETER;
126 /* internal storage */
127 DD_LIST_FOREACH(st_int_head, elem, st) {
128 if (st->storage_id != storage_id)
130 *path = strdup(st->root());
132 //LCOV_EXCL_START System Error
133 _E("Failed to copy the root string : %d", errno);
134 return STORAGE_ERROR_OUT_OF_MEMORY;
137 return STORAGE_ERROR_NONE;
140 /* external storage */
141 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
143 _E("Failed to get root path of external storage(%d, %d", storage_id, ret); //LCOV_EXCL_LINE
144 return STORAGE_ERROR_INVALID_PARAMETER;
147 *path = strdup(root);
149 _E("Failed to copy the root string : %d", errno); //LCOV_EXCL_LINE System Error
150 return STORAGE_ERROR_OUT_OF_MEMORY;
153 return STORAGE_ERROR_NONE;
156 API int storage_get_directory(int storage_id, storage_directory_e type, char **path)
158 const struct storage_ops *st;
168 return STORAGE_ERROR_NOT_SUPPORTED;
171 _E("Invalid parameger");
172 return STORAGE_ERROR_INVALID_PARAMETER;
175 if (type < 0 || type >= STORAGE_DIRECTORY_MAX) {
176 _E("Invalid parameter");
177 return STORAGE_ERROR_INVALID_PARAMETER;
180 /* internal storage */
182 DD_LIST_FOREACH(st_int_head, elem, st) {
183 if (st->storage_id != storage_id)
190 snprintf(root, sizeof(root), "%s", st->root());
191 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
192 temp2 = vconf_get_str(VCONFKEY_SETAPPL_CALL_RINGTONE_PATH_STR);
194 return STORAGE_ERROR_OPERATION_FAILED;
195 end = strrchr(temp2, '/');
198 snprintf(temp, PATH_MAX, "%s", temp2);
201 snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type]);
206 /* external storage */
207 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
208 _E("Not support directory : id(%d) type(%d)", storage_id, type); //LCOV_EXCL_LINE
209 return STORAGE_ERROR_NOT_SUPPORTED;
212 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
214 _E("Failed to get root dir for external storage(id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
215 return STORAGE_ERROR_NOT_SUPPORTED;
217 /* The operation is not decided */
219 return STORAGE_ERROR_NOT_SUPPORTED;
221 snprintf(temp, sizeof(temp), "%s/%s", root, dir_path[type]);
224 *path = strdup(temp);
226 _E("Failed to copy the directory(%d) string : %d", type, errno); //LCOV_EXCL_LINE
227 return STORAGE_ERROR_OUT_OF_MEMORY;
230 return STORAGE_ERROR_NONE;
233 API int storage_get_type(int storage_id, storage_type_e *type)
235 const struct storage_ops *st;
242 return STORAGE_ERROR_NOT_SUPPORTED;
245 _E("Invalid parameger");
246 return STORAGE_ERROR_INVALID_PARAMETER;
249 /* internal storage */
250 DD_LIST_FOREACH(st_int_head, elem, st) {
251 if (st->storage_id != storage_id)
254 return STORAGE_ERROR_NONE;
257 /* external storage */
258 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
260 _E("Failed to get type of external storage");
261 return STORAGE_ERROR_NOT_SUPPORTED;
264 *type = STORAGE_TYPE_EXTENDED_INTERNAL;
266 *type = STORAGE_TYPE_EXTERNAL;
268 return STORAGE_ERROR_NONE;
271 API int storage_get_state(int storage_id, storage_state_e *state)
273 const struct storage_ops *ops;
279 return STORAGE_ERROR_NOT_SUPPORTED;
282 _E("Invalid parameger");
283 return STORAGE_ERROR_INVALID_PARAMETER;
286 /* internal storage */
287 DD_LIST_FOREACH(st_int_head, elem, ops) {
288 if (ops->storage_id != storage_id)
290 *state = ops->get_state();
291 return STORAGE_ERROR_NONE;
294 /* external storage */
295 ret = storage_ext_get_state(storage_id, &st);
297 _E("Failed to get state (storage id(%d), ret(%d))", storage_id, ret); //LCOV_EXCL_LINE
298 return STORAGE_ERROR_OPERATION_FAILED;
302 return STORAGE_ERROR_NONE;
305 //LCOV_EXCL_START Not called Callback
306 static void compat_cb(int storage_id,
307 storage_dev_e dev, storage_state_e state,
308 const char *fstype, const char *fsuuid, const char *mountpath,
309 bool primary, int flags, void *user_data)
311 struct compat_cb_info* ccb_info;
314 if (storage_id == STORAGE_TYPE_EXTERNAL && dev == STORAGE_DEV_EXT_SDCARD)
315 DD_LIST_FOREACH(compat_cb_list, elem, ccb_info)
316 ccb_info->user_cb(storage_id, state, ccb_info->user_data);
320 API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data)
322 const struct storage_ops *st;
323 struct storage_cb_info info;
327 struct compat_cb_info* ccb_info;
328 static int compat_cb_init = 0;
331 return STORAGE_ERROR_NOT_SUPPORTED;
334 _E("Invalid parameger");
335 return STORAGE_ERROR_INVALID_PARAMETER;
338 /* For backward compatability */
339 if (storage_id == STORAGE_TYPE_EXTERNAL) {
340 if (!compat_cb_init) {
341 ret = storage_set_changed_cb(STORAGE_TYPE_EXTERNAL, compat_cb, NULL);
342 if (ret == STORAGE_ERROR_NONE)
348 ccb_info = malloc(sizeof(struct compat_cb_info));
349 if (ccb_info == NULL)
350 return STORAGE_ERROR_OPERATION_FAILED;
351 ccb_info->user_cb = callback;
352 ccb_info->user_data = user_data;
353 DD_LIST_APPEND(compat_cb_list, ccb_info);
355 return STORAGE_ERROR_NONE;
358 /* Internal storage does not support registering changed callback */
359 DD_LIST_FOREACH(st_int_head, elem, st)
360 if (st->storage_id == storage_id)
361 return STORAGE_ERROR_NONE;
363 /* external storage */
364 info.id = storage_id;
365 info.state_cb = callback;
366 info.user_data = user_data;
368 ret = storage_ext_register_cb(STORAGE_CALLBACK_ID, &info);
370 _E("Failed to register callback : id(%d)", storage_id); //LCOV_EXCL_LINE
371 return STORAGE_ERROR_OPERATION_FAILED;
374 return STORAGE_ERROR_NONE;
377 API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback)
379 const struct storage_ops *st;
380 struct storage_cb_info info;
385 return STORAGE_ERROR_NOT_SUPPORTED;
388 _E("Invalid parameger");
389 return STORAGE_ERROR_INVALID_PARAMETER;
392 /* For backward compatability */
393 if (storage_id == STORAGE_TYPE_EXTERNAL) {
395 struct compat_cb_info* ccb_info;
397 DD_LIST_FOREACH_SAFE(compat_cb_list, elem, elem_n, ccb_info) {
398 if (ccb_info->user_cb == callback) {
399 DD_LIST_REMOVE(compat_cb_list, ccb_info);
401 return STORAGE_ERROR_NONE;
404 return STORAGE_ERROR_OPERATION_FAILED;
407 /* Internal storage does not support registering changed callback */
408 DD_LIST_FOREACH(st_int_head, elem, st)
409 if (st->storage_id == storage_id)
410 return STORAGE_ERROR_NONE;
412 /* external storage */
413 info.id = storage_id;
414 info.state_cb = callback;
416 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_ID, &info);
418 _E("Failed to unregister callback : id(%d)", storage_id); //LCOV_EXCL_LINE
419 return STORAGE_ERROR_OPERATION_FAILED;
422 return STORAGE_ERROR_NONE;
425 API int storage_get_total_space(int storage_id, unsigned long long *bytes)
427 const struct storage_ops *st;
428 unsigned long long total;
433 return STORAGE_ERROR_NOT_SUPPORTED;
436 _E("Invalid parameger");
437 return STORAGE_ERROR_INVALID_PARAMETER;
440 /* internal storage */
441 DD_LIST_FOREACH(st_int_head, elem, st) {
442 if (st->storage_id != storage_id)
444 ret = st->get_space(&total, NULL);
448 /* external storage */
449 ret = storage_ext_get_space(storage_id, &total, NULL);
453 _E("Failed to get total memory : id(%d)", storage_id); //LCOV_EXCL_LINE
455 return STORAGE_ERROR_NOT_SUPPORTED;
456 return STORAGE_ERROR_OPERATION_FAILED;
460 return STORAGE_ERROR_NONE;
463 API int storage_get_available_space(int storage_id, unsigned long long *bytes)
465 const struct storage_ops *st;
466 unsigned long long avail;
471 return STORAGE_ERROR_NOT_SUPPORTED;
474 _E("Invalid parameger");
475 return STORAGE_ERROR_INVALID_PARAMETER;
478 /* internal storage */
479 DD_LIST_FOREACH(st_int_head, elem, st) {
480 if (st->storage_id != storage_id)
482 ret = st->get_space(NULL, &avail);
486 /* external storage */
487 ret = storage_ext_get_space(storage_id, NULL, &avail);
491 _E("Failed to get available memory : id(%d)", storage_id); //LCOV_EXCL_LINE
493 return STORAGE_ERROR_NOT_SUPPORTED;
494 return STORAGE_ERROR_OPERATION_FAILED;
498 return STORAGE_ERROR_NONE;
501 API int storage_set_changed_cb(storage_type_e type, storage_changed_cb callback, void *user_data)
504 struct storage_cb_info info;
506 if (type == STORAGE_TYPE_INTERNAL) {
507 _E("Internal storage is not supported");
508 return STORAGE_ERROR_NOT_SUPPORTED;
511 if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
512 _E("Invalid type (%d)", type);
513 return STORAGE_ERROR_INVALID_PARAMETER;
517 _E("Callback is NULL");
518 return STORAGE_ERROR_INVALID_PARAMETER;
521 if (!storage_ext_is_supported()) {
522 _E("Block module is not enabled");
523 return STORAGE_ERROR_NOT_SUPPORTED;
526 /* external storage */
528 info.type_cb = callback;
529 info.user_data = user_data;
531 ret = storage_ext_register_cb(STORAGE_CALLBACK_TYPE, &info);
533 _E("Failed to register storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
534 return STORAGE_ERROR_OPERATION_FAILED;
537 return STORAGE_ERROR_NONE;
540 API int storage_unset_changed_cb(storage_type_e type, storage_changed_cb callback)
542 struct storage_cb_info info;
545 if (type == STORAGE_TYPE_INTERNAL) {
546 _E("Internal storage is not supported");
547 return STORAGE_ERROR_NOT_SUPPORTED;
550 if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
551 _E("Invalid type (%d)", type);
552 return STORAGE_ERROR_INVALID_PARAMETER;
556 _E("Callback is NULL");
557 return STORAGE_ERROR_INVALID_PARAMETER;
560 if (!storage_ext_is_supported()) {
561 _E("Block module is not enabled");
562 return STORAGE_ERROR_NOT_SUPPORTED;
565 /* external storage */
567 info.type_cb = callback;
569 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_TYPE, &info);
571 _E("Failed to unregister storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
572 return STORAGE_ERROR_OPERATION_FAILED;
575 return STORAGE_ERROR_NONE;
578 static void __CONSTRUCTOR__ init(void)
584 for (i = 0 ; i <= STORAGE_DIRECTORY_OTHERS ; i++) {
585 tmp = tzplatform_getenv(tz_id[i]);
587 token = rindex(tmp, '/');
590 dir_path[i] = strdup(token);