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 const char *dir_path[STORAGE_DIRECTORY_MAX];
32 const int tz_id[STORAGE_DIRECTORY_MAX] = {
33 [STORAGE_DIRECTORY_IMAGES] = TZ_USER_IMAGES,
34 [STORAGE_DIRECTORY_SOUNDS] = TZ_USER_SOUNDS,
35 [STORAGE_DIRECTORY_VIDEOS] = TZ_USER_VIDEOS,
36 [STORAGE_DIRECTORY_CAMERA] = TZ_USER_CAMERA,
37 [STORAGE_DIRECTORY_DOWNLOADS] = TZ_USER_DOWNLOADS,
38 [STORAGE_DIRECTORY_MUSIC] = TZ_USER_MUSIC,
39 [STORAGE_DIRECTORY_DOCUMENTS] = TZ_USER_DOCUMENTS,
40 [STORAGE_DIRECTORY_OTHERS] = TZ_USER_OTHERS,
43 static dd_list *st_int_head; /* Internal storage list */
45 static dd_list *compat_cb_list;
46 struct compat_cb_info {
47 storage_state_changed_cb user_cb;
51 void add_device(const struct storage_ops *st)
53 DD_LIST_APPEND(st_int_head, st);
56 void remove_device(const struct storage_ops *st)
58 DD_LIST_REMOVE(st_int_head, st);
61 API int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data)
63 const struct storage_ops *st;
69 _E("Invalid parameter");
70 return STORAGE_ERROR_INVALID_PARAMETER;
73 if (getuid() <= USER_UID_START)
76 DD_LIST_FOREACH(st_int_head, elem, st) {
78 ret = callback(st->storage_id, st->type, st->get_state(),
79 st->root(), user_data);
80 /* if the return value is false, will be stop to iterate */
86 if (!storage_ext_is_supported()) {
87 _D("Block module is not enabled");
88 return STORAGE_ERROR_NONE;
91 ret = storage_ext_foreach_device_list(callback, user_data);
93 _E("Failed to iterate external devices (%d)", ret); //LCOV_EXCL_LINE
94 return STORAGE_ERROR_OPERATION_FAILED;
97 return STORAGE_ERROR_NONE;
100 API int storage_get_root_directory(int storage_id, char **path)
102 const struct storage_ops *st;
110 return STORAGE_ERROR_NOT_SUPPORTED;
113 _E("Invalid parameger");
114 return STORAGE_ERROR_INVALID_PARAMETER;
117 if (getuid() <= USER_UID_START)
120 /* internal storage */
121 DD_LIST_FOREACH(st_int_head, elem, st) {
122 if (st->storage_id != storage_id)
125 _E("Only apps and user session daemons are allowed "
126 "to use storage_get_root_directory(INTERNAL_STORAGE_ID, ...)");
127 return STORAGE_ERROR_INVALID_PARAMETER;
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;
169 return STORAGE_ERROR_NOT_SUPPORTED;
172 _E("Invalid parameger");
173 return STORAGE_ERROR_INVALID_PARAMETER;
176 if (type < 0 || type >= STORAGE_DIRECTORY_MAX) {
177 _E("Invalid parameter");
178 return STORAGE_ERROR_INVALID_PARAMETER;
181 /* internal storage */
183 DD_LIST_FOREACH(st_int_head, elem, st) {
184 if (st->storage_id != storage_id)
190 if (getuid() <= USER_UID_START)
195 _E("Only apps and user session daemons are allowed "
196 "to use storage_get_root_directory(INTERNAL_STORAGE_ID, ...)");
198 return STORAGE_ERROR_INVALID_PARAMETER;
201 snprintf(root, sizeof(root), "%s", st->root());
202 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
203 temp2 = vconf_get_str(VCONFKEY_SETAPPL_CALL_RINGTONE_PATH_STR);
205 return STORAGE_ERROR_OPERATION_FAILED;
206 end = strrchr(temp2, '/');
209 snprintf(temp, PATH_MAX, "%s", temp2);
212 snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type]);
217 /* external storage */
218 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
219 _E("Not support directory : id(%d) type(%d)", storage_id, type); //LCOV_EXCL_LINE
220 return STORAGE_ERROR_NOT_SUPPORTED;
223 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
225 _E("Failed to get root dir for external storage(id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
226 return STORAGE_ERROR_NOT_SUPPORTED;
228 /* The operation is not decided */
230 return STORAGE_ERROR_NOT_SUPPORTED;
232 snprintf(temp, sizeof(temp), "%s/%s", root, dir_path[type]);
235 *path = strdup(temp);
237 _E("Failed to copy the directory(%d) string : %d", type, errno); //LCOV_EXCL_LINE
238 return STORAGE_ERROR_OUT_OF_MEMORY;
241 return STORAGE_ERROR_NONE;
244 API int storage_get_type(int storage_id, storage_type_e *type)
246 const struct storage_ops *st;
253 return STORAGE_ERROR_NOT_SUPPORTED;
256 _E("Invalid parameger");
257 return STORAGE_ERROR_INVALID_PARAMETER;
260 /* internal storage */
261 DD_LIST_FOREACH(st_int_head, elem, st) {
262 if (st->storage_id != storage_id)
265 return STORAGE_ERROR_NONE;
268 /* external storage */
269 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
271 _E("Failed to get type of external storage");
272 return STORAGE_ERROR_NOT_SUPPORTED;
275 *type = STORAGE_TYPE_EXTENDED_INTERNAL;
277 *type = STORAGE_TYPE_EXTERNAL;
279 return STORAGE_ERROR_NONE;
282 API int storage_get_state(int storage_id, storage_state_e *state)
284 const struct storage_ops *ops;
290 return STORAGE_ERROR_NOT_SUPPORTED;
293 _E("Invalid parameger");
294 return STORAGE_ERROR_INVALID_PARAMETER;
297 /* internal storage */
298 DD_LIST_FOREACH(st_int_head, elem, ops) {
299 if (ops->storage_id != storage_id)
301 *state = ops->get_state();
302 return STORAGE_ERROR_NONE;
305 /* external storage */
306 ret = storage_ext_get_state(storage_id, &st);
308 _E("Failed to get state (storage id(%d), ret(%d))", storage_id, ret); //LCOV_EXCL_LINE
309 return STORAGE_ERROR_OPERATION_FAILED;
313 return STORAGE_ERROR_NONE;
316 //LCOV_EXCL_START Not called Callback
317 static void compat_cb(int storage_id,
318 storage_dev_e dev, storage_state_e state,
319 const char *fstype, const char *fsuuid, const char *mountpath,
320 bool primary, int flags, void *user_data)
322 struct compat_cb_info* ccb_info;
325 if (storage_id == STORAGE_TYPE_EXTERNAL && dev == STORAGE_DEV_EXT_SDCARD)
326 DD_LIST_FOREACH(compat_cb_list, elem, ccb_info)
327 ccb_info->user_cb(storage_id, state, ccb_info->user_data);
331 API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data)
333 const struct storage_ops *st;
334 struct storage_cb_info info;
338 struct compat_cb_info* ccb_info;
339 static int compat_cb_init = 0;
342 return STORAGE_ERROR_NOT_SUPPORTED;
345 _E("Invalid parameger");
346 return STORAGE_ERROR_INVALID_PARAMETER;
349 /* For backward compatability */
350 if (storage_id == STORAGE_TYPE_EXTERNAL) {
351 if (!compat_cb_init) {
352 ret = storage_set_changed_cb(STORAGE_TYPE_EXTERNAL, compat_cb, NULL);
353 if (ret == STORAGE_ERROR_NONE)
359 ccb_info = malloc(sizeof(struct compat_cb_info));
360 if (ccb_info == NULL)
361 return STORAGE_ERROR_OPERATION_FAILED;
362 ccb_info->user_cb = callback;
363 ccb_info->user_data = user_data;
364 DD_LIST_APPEND(compat_cb_list, ccb_info);
366 return STORAGE_ERROR_NONE;
369 /* Internal storage does not support registering changed callback */
370 DD_LIST_FOREACH(st_int_head, elem, st)
371 if (st->storage_id == storage_id)
372 return STORAGE_ERROR_NONE;
374 /* external storage */
375 info.id = storage_id;
376 info.state_cb = callback;
377 info.user_data = user_data;
379 ret = storage_ext_register_cb(STORAGE_CALLBACK_ID, &info);
381 _E("Failed to register callback : id(%d)", storage_id); //LCOV_EXCL_LINE
382 return STORAGE_ERROR_OPERATION_FAILED;
385 return STORAGE_ERROR_NONE;
388 API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback)
390 const struct storage_ops *st;
391 struct storage_cb_info info;
396 return STORAGE_ERROR_NOT_SUPPORTED;
399 _E("Invalid parameger");
400 return STORAGE_ERROR_INVALID_PARAMETER;
403 /* For backward compatability */
404 if (storage_id == STORAGE_TYPE_EXTERNAL) {
406 struct compat_cb_info* ccb_info;
408 DD_LIST_FOREACH_SAFE(compat_cb_list, elem, elem_n, ccb_info) {
409 if (ccb_info->user_cb == callback) {
410 DD_LIST_REMOVE(compat_cb_list, ccb_info);
412 return STORAGE_ERROR_NONE;
415 return STORAGE_ERROR_OPERATION_FAILED;
418 /* Internal storage does not support registering changed callback */
419 DD_LIST_FOREACH(st_int_head, elem, st)
420 if (st->storage_id == storage_id)
421 return STORAGE_ERROR_NONE;
423 /* external storage */
424 info.id = storage_id;
425 info.state_cb = callback;
427 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_ID, &info);
429 _E("Failed to unregister callback : id(%d)", storage_id); //LCOV_EXCL_LINE
430 return STORAGE_ERROR_OPERATION_FAILED;
433 return STORAGE_ERROR_NONE;
436 API int storage_get_total_space(int storage_id, unsigned long long *bytes)
438 const struct storage_ops *st;
439 unsigned long long total;
444 return STORAGE_ERROR_NOT_SUPPORTED;
447 _E("Invalid parameger");
448 return STORAGE_ERROR_INVALID_PARAMETER;
451 /* internal storage */
452 DD_LIST_FOREACH(st_int_head, elem, st) {
453 if (st->storage_id != storage_id)
455 ret = st->get_space(&total, NULL);
459 /* external storage */
460 ret = storage_ext_get_space(storage_id, &total, NULL);
464 _E("Failed to get total memory : id(%d)", storage_id); //LCOV_EXCL_LINE
466 return STORAGE_ERROR_NOT_SUPPORTED;
467 return STORAGE_ERROR_OPERATION_FAILED;
471 return STORAGE_ERROR_NONE;
474 API int storage_get_available_space(int storage_id, unsigned long long *bytes)
476 const struct storage_ops *st;
477 unsigned long long avail;
482 return STORAGE_ERROR_NOT_SUPPORTED;
485 _E("Invalid parameger");
486 return STORAGE_ERROR_INVALID_PARAMETER;
489 /* internal storage */
490 DD_LIST_FOREACH(st_int_head, elem, st) {
491 if (st->storage_id != storage_id)
493 ret = st->get_space(NULL, &avail);
497 /* external storage */
498 ret = storage_ext_get_space(storage_id, NULL, &avail);
502 _E("Failed to get available memory : id(%d)", storage_id); //LCOV_EXCL_LINE
504 return STORAGE_ERROR_NOT_SUPPORTED;
505 return STORAGE_ERROR_OPERATION_FAILED;
509 return STORAGE_ERROR_NONE;
512 API int storage_set_changed_cb(storage_type_e type, storage_changed_cb callback, void *user_data)
515 struct storage_cb_info info;
517 if (type == STORAGE_TYPE_INTERNAL) {
518 _E("Internal storage is not supported");
519 return STORAGE_ERROR_NOT_SUPPORTED;
522 if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
523 _E("Invalid type (%d)", type);
524 return STORAGE_ERROR_INVALID_PARAMETER;
528 _E("Callback is NULL");
529 return STORAGE_ERROR_INVALID_PARAMETER;
532 if (!storage_ext_is_supported()) {
533 _E("Block module is not enabled");
534 return STORAGE_ERROR_NOT_SUPPORTED;
537 /* external storage */
539 info.type_cb = callback;
540 info.user_data = user_data;
542 ret = storage_ext_register_cb(STORAGE_CALLBACK_TYPE, &info);
544 _E("Failed to register storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
545 return STORAGE_ERROR_OPERATION_FAILED;
548 return STORAGE_ERROR_NONE;
551 API int storage_unset_changed_cb(storage_type_e type, storage_changed_cb callback)
553 struct storage_cb_info info;
556 if (type == STORAGE_TYPE_INTERNAL) {
557 _E("Internal storage is not supported");
558 return STORAGE_ERROR_NOT_SUPPORTED;
561 if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
562 _E("Invalid type (%d)", type);
563 return STORAGE_ERROR_INVALID_PARAMETER;
567 _E("Callback is NULL");
568 return STORAGE_ERROR_INVALID_PARAMETER;
571 if (!storage_ext_is_supported()) {
572 _E("Block module is not enabled");
573 return STORAGE_ERROR_NOT_SUPPORTED;
576 /* external storage */
578 info.type_cb = callback;
580 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_TYPE, &info);
582 _E("Failed to unregister storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
583 return STORAGE_ERROR_OPERATION_FAILED;
586 return STORAGE_ERROR_NONE;
589 static void __CONSTRUCTOR__ init(void)
595 for (i = 0 ; i <= STORAGE_DIRECTORY_OTHERS ; i++) {
596 tmp = tzplatform_getenv(tz_id[i]);
598 token = rindex(tmp, '/');
601 dir_path[i] = strdup(token);