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;
68 _E("Invalid parameter");
69 return STORAGE_ERROR_INVALID_PARAMETER;
72 DD_LIST_FOREACH(st_int_head, elem, st) {
73 ret = callback(st->storage_id, st->type, st->get_state(),
74 st->root(), user_data);
75 /* if the return value is false, will be stop to iterate */
80 ret = storage_ext_foreach_device_list(callback, user_data);
82 _E("Failed to iterate external devices (%d)", ret); //LCOV_EXCL_LINE
83 return STORAGE_ERROR_OPERATION_FAILED;
86 return STORAGE_ERROR_NONE;
89 API int storage_get_root_directory(int storage_id, char **path)
91 const struct storage_ops *st;
98 return STORAGE_ERROR_NOT_SUPPORTED;
101 _E("Invalid parameger");
102 return STORAGE_ERROR_INVALID_PARAMETER;
105 /* internal storage */
106 DD_LIST_FOREACH(st_int_head, elem, st) {
107 if (st->storage_id != storage_id)
109 *path = strdup(st->root());
111 //LCOV_EXCL_START System Error
112 _E("Failed to copy the root string : %d", errno);
113 return STORAGE_ERROR_OUT_OF_MEMORY;
116 return STORAGE_ERROR_NONE;
119 /* external storage */
120 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
122 _E("Failed to get root path of external storage(%d, %d", storage_id, ret); //LCOV_EXCL_LINE
123 return STORAGE_ERROR_INVALID_PARAMETER;
126 *path = strdup(root);
128 _E("Failed to copy the root string : %d", errno); //LCOV_EXCL_LINE System Error
129 return STORAGE_ERROR_OUT_OF_MEMORY;
132 return STORAGE_ERROR_NONE;
135 API int storage_get_directory(int storage_id, storage_directory_e type, char **path)
137 const struct storage_ops *st;
147 return STORAGE_ERROR_NOT_SUPPORTED;
150 _E("Invalid parameger");
151 return STORAGE_ERROR_INVALID_PARAMETER;
154 if (type < 0 || type >= STORAGE_DIRECTORY_MAX) {
155 _E("Invalid parameter");
156 return STORAGE_ERROR_INVALID_PARAMETER;
159 /* internal storage */
161 DD_LIST_FOREACH(st_int_head, elem, st) {
162 if (st->storage_id != storage_id)
169 snprintf(root, sizeof(root), "%s", st->root());
170 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
171 temp2 = vconf_get_str(VCONFKEY_SETAPPL_CALL_RINGTONE_PATH_STR);
173 return STORAGE_ERROR_OPERATION_FAILED;
174 end = strrchr(temp2, '/');
177 snprintf(temp, PATH_MAX, "%s", temp2);
180 snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type]);
185 /* external storage */
186 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
187 _E("Not support directory : id(%d) type(%d)", storage_id, type); //LCOV_EXCL_LINE
188 return STORAGE_ERROR_NOT_SUPPORTED;
191 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
193 _E("Failed to get root dir for external storage(id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
194 return STORAGE_ERROR_NOT_SUPPORTED;
196 /* The operation is not decided */
198 return STORAGE_ERROR_NOT_SUPPORTED;
200 snprintf(temp, sizeof(temp), "%s/%s", root, dir_path[type]);
203 *path = strdup(temp);
205 _E("Failed to copy the directory(%d) string : %d", type, errno); //LCOV_EXCL_LINE
206 return STORAGE_ERROR_OUT_OF_MEMORY;
209 return STORAGE_ERROR_NONE;
212 API int storage_get_type(int storage_id, storage_type_e *type)
214 const struct storage_ops *st;
221 return STORAGE_ERROR_NOT_SUPPORTED;
224 _E("Invalid parameger");
225 return STORAGE_ERROR_INVALID_PARAMETER;
228 /* internal storage */
229 DD_LIST_FOREACH(st_int_head, elem, st) {
230 if (st->storage_id != storage_id)
233 return STORAGE_ERROR_NONE;
236 /* external storage */
237 ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
239 _E("Failed to get type of external storage");
240 return STORAGE_ERROR_NOT_SUPPORTED;
243 *type = STORAGE_TYPE_EXTENDED_INTERNAL;
245 *type = STORAGE_TYPE_EXTERNAL;
247 return STORAGE_ERROR_NONE;
250 API int storage_get_state(int storage_id, storage_state_e *state)
252 const struct storage_ops *ops;
258 return STORAGE_ERROR_NOT_SUPPORTED;
261 _E("Invalid parameger");
262 return STORAGE_ERROR_INVALID_PARAMETER;
265 /* internal storage */
266 DD_LIST_FOREACH(st_int_head, elem, ops) {
267 if (ops->storage_id != storage_id)
269 *state = ops->get_state();
270 return STORAGE_ERROR_NONE;
273 /* external storage */
274 ret = storage_ext_get_state(storage_id, &st);
276 _E("Failed to get state (storage id(%d), ret(%d))", storage_id, ret); //LCOV_EXCL_LINE
277 return STORAGE_ERROR_OPERATION_FAILED;
281 return STORAGE_ERROR_NONE;
284 //LCOV_EXCL_START Not called Callback
285 static void compat_cb(int storage_id,
286 storage_dev_e dev, storage_state_e state,
287 const char *fstype, const char *fsuuid, const char *mountpath,
288 bool primary, int flags, void *user_data)
290 struct compat_cb_info* ccb_info;
293 if (storage_id == STORAGE_TYPE_EXTERNAL && dev == STORAGE_DEV_EXT_SDCARD)
294 DD_LIST_FOREACH(compat_cb_list, elem, ccb_info)
295 ccb_info->user_cb(storage_id, state, ccb_info->user_data);
299 API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data)
301 const struct storage_ops *st;
302 struct storage_cb_info info;
306 struct compat_cb_info* ccb_info;
307 static int compat_cb_init = 0;
310 return STORAGE_ERROR_NOT_SUPPORTED;
313 _E("Invalid parameger");
314 return STORAGE_ERROR_INVALID_PARAMETER;
317 /* For backward compatability */
318 if (storage_id == STORAGE_TYPE_EXTERNAL) {
319 if (!compat_cb_init) {
320 ret = storage_set_changed_cb(STORAGE_TYPE_EXTERNAL, compat_cb, NULL);
321 if (ret == STORAGE_ERROR_NONE)
327 ccb_info = malloc(sizeof(struct compat_cb_info));
328 if (ccb_info == NULL)
329 return STORAGE_ERROR_OPERATION_FAILED;
330 ccb_info->user_cb = callback;
331 ccb_info->user_data = user_data;
332 DD_LIST_APPEND(compat_cb_list, ccb_info);
334 return STORAGE_ERROR_NONE;
337 /* Internal storage does not support registering changed callback */
338 DD_LIST_FOREACH(st_int_head, elem, st)
339 if (st->storage_id == storage_id)
340 return STORAGE_ERROR_NONE;
342 /* external storage */
343 info.id = storage_id;
344 info.state_cb = callback;
345 info.user_data = user_data;
347 ret = storage_ext_register_cb(STORAGE_CALLBACK_ID, &info);
349 _E("Failed to register callback : id(%d)", storage_id); //LCOV_EXCL_LINE
350 return STORAGE_ERROR_OPERATION_FAILED;
353 return STORAGE_ERROR_NONE;
356 API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback)
358 const struct storage_ops *st;
359 struct storage_cb_info info;
364 return STORAGE_ERROR_NOT_SUPPORTED;
367 _E("Invalid parameger");
368 return STORAGE_ERROR_INVALID_PARAMETER;
371 /* For backward compatability */
372 if (storage_id == STORAGE_TYPE_EXTERNAL) {
374 struct compat_cb_info* ccb_info;
376 DD_LIST_FOREACH_SAFE(compat_cb_list, elem, elem_n, ccb_info) {
377 if (ccb_info->user_cb == callback) {
378 DD_LIST_REMOVE(compat_cb_list, ccb_info);
380 return STORAGE_ERROR_NONE;
383 return STORAGE_ERROR_OPERATION_FAILED;
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;
395 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_ID, &info);
397 _E("Failed to unregister callback : id(%d)", storage_id); //LCOV_EXCL_LINE
398 return STORAGE_ERROR_OPERATION_FAILED;
401 return STORAGE_ERROR_NONE;
404 API int storage_get_total_space(int storage_id, unsigned long long *bytes)
406 const struct storage_ops *st;
407 unsigned long long total;
412 return STORAGE_ERROR_NOT_SUPPORTED;
415 _E("Invalid parameger");
416 return STORAGE_ERROR_INVALID_PARAMETER;
419 /* internal storage */
420 DD_LIST_FOREACH(st_int_head, elem, st) {
421 if (st->storage_id != storage_id)
423 ret = st->get_space(&total, NULL);
427 /* external storage */
428 ret = storage_ext_get_space(storage_id, &total, NULL);
432 _E("Failed to get total memory : id(%d)", storage_id); //LCOV_EXCL_LINE
434 return STORAGE_ERROR_NOT_SUPPORTED;
435 return STORAGE_ERROR_OPERATION_FAILED;
439 return STORAGE_ERROR_NONE;
442 API int storage_get_available_space(int storage_id, unsigned long long *bytes)
444 const struct storage_ops *st;
445 unsigned long long avail;
450 return STORAGE_ERROR_NOT_SUPPORTED;
453 _E("Invalid parameger");
454 return STORAGE_ERROR_INVALID_PARAMETER;
457 /* internal storage */
458 DD_LIST_FOREACH(st_int_head, elem, st) {
459 if (st->storage_id != storage_id)
461 ret = st->get_space(NULL, &avail);
465 /* external storage */
466 ret = storage_ext_get_space(storage_id, NULL, &avail);
470 _E("Failed to get available memory : id(%d)", storage_id); //LCOV_EXCL_LINE
472 return STORAGE_ERROR_NOT_SUPPORTED;
473 return STORAGE_ERROR_OPERATION_FAILED;
477 return STORAGE_ERROR_NONE;
480 API int storage_set_changed_cb(storage_type_e type, storage_changed_cb callback, void *user_data)
483 struct storage_cb_info info;
485 if (type == STORAGE_TYPE_INTERNAL) {
486 _E("Internal storage is not supported");
487 return STORAGE_ERROR_NOT_SUPPORTED;
490 if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
491 _E("Invalid type (%d)", type);
492 return STORAGE_ERROR_INVALID_PARAMETER;
496 _E("Callback is NULL");
497 return STORAGE_ERROR_INVALID_PARAMETER;
500 /* external storage */
502 info.type_cb = callback;
503 info.user_data = user_data;
505 ret = storage_ext_register_cb(STORAGE_CALLBACK_TYPE, &info);
507 _E("Failed to register storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
508 return STORAGE_ERROR_OPERATION_FAILED;
511 return STORAGE_ERROR_NONE;
514 API int storage_unset_changed_cb(storage_type_e type, storage_changed_cb callback)
516 struct storage_cb_info info;
519 if (type == STORAGE_TYPE_INTERNAL) {
520 _E("Internal storage is not supported");
521 return STORAGE_ERROR_NOT_SUPPORTED;
524 if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
525 _E("Invalid type (%d)", type);
526 return STORAGE_ERROR_INVALID_PARAMETER;
530 _E("Callback is NULL");
531 return STORAGE_ERROR_INVALID_PARAMETER;
534 /* external storage */
536 info.type_cb = callback;
538 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_TYPE, &info);
540 _E("Failed to unregister storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
541 return STORAGE_ERROR_OPERATION_FAILED;
544 return STORAGE_ERROR_NONE;
547 static void __CONSTRUCTOR__ init(void)
553 for (i = 0 ; i <= STORAGE_DIRECTORY_OTHERS ; i++) {
554 tmp = tzplatform_getenv(tz_id[i]);
556 token = rindex(tmp, '/');
559 dir_path[i] = strdup(token);