Increase line coverage using LCOV_EXCL
[platform/core/system/libstorage.git] / src / storage.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <vconf.h>
23 #include <tzplatform_config.h>
24 #include <libsyscommon/list.h>
25
26 #include "common.h"
27 #include "log.h"
28 #include "storage-external.h"
29
30 const char *dir_path[STORAGE_DIRECTORY_MAX];
31
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,
41 };
42
43 static GList *st_int_head; /* Internal storage list */
44
45 static GList *compat_cb_list;
46 struct compat_cb_info {
47         storage_state_changed_cb user_cb;
48         void *user_data;
49 };
50
51 void add_device(const struct storage_ops *st)
52 {
53         SYS_G_LIST_APPEND(st_int_head, st);
54 }
55
56 void remove_device(const struct storage_ops *st)
57 {
58         SYS_G_LIST_REMOVE(st_int_head, st);
59 }
60
61 API int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data)
62 {
63         const struct storage_ops *st;
64         GList *elem;
65         int ret_val;
66         bool user = true;
67
68         if (!callback) {
69                 _E("Invalid parameter");
70                 return STORAGE_ERROR_INVALID_PARAMETER;
71         }
72
73         if (getuid() <= USER_UID_START)
74                 user = false;
75
76         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
77                 if (user) {
78                         ret_val = 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 */
81                         if (!ret_val)
82                                 break;
83                 }
84         }
85
86         if (!storage_ext_is_supported()) {
87                 //LCOV_EXCL_START
88                 _D("Block module is not enabled");
89                 return STORAGE_ERROR_NONE;
90                 //LCOV_EXCL_STOP
91         }
92
93         ret_val = storage_ext_foreach_device_list(callback, user_data);
94         if (ret_val < 0) {
95                 _E("Failed to iterate external devices (%d)", ret_val); //LCOV_EXCL_LINE
96                 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
97         }
98
99         return STORAGE_ERROR_NONE;
100 }
101
102 API int storage_get_root_directory(int storage_id, char **path)
103 {
104         const struct storage_ops *st;
105         GList *elem;
106         char root[PATH_MAX];
107         int ret_val;
108         bool extendedint;
109         bool user = true;
110
111         if (storage_id < 0)
112                 return STORAGE_ERROR_INVALID_PARAMETER;
113
114         if (!path) {
115                 _E("Invalid parameger");
116                 return STORAGE_ERROR_INVALID_PARAMETER;
117         }
118
119         if (getuid() <= USER_UID_START)
120                 user = false;
121
122         /* internal storage */
123         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
124                 if (st->storage_id != storage_id)
125                         continue;
126                 if (!user) {
127                         _E("Only apps and user session daemons are allowed "
128                                         "to use storage_get_root_directory(INTERNAL_STORAGE_ID, ...)");
129                         return STORAGE_ERROR_INVALID_PARAMETER;
130                 }
131
132                 *path = strdup(st->root());
133                 if (!*path) {
134 //LCOV_EXCL_START System Error
135                         _E("Failed to copy the root string : %d", errno);
136                         return STORAGE_ERROR_OUT_OF_MEMORY;
137 //LCOV_EXCL_STOP
138                 }
139                 return STORAGE_ERROR_NONE;
140         }
141
142         /* external storage */
143         if (!storage_ext_is_supported()) {
144                 //LCOV_EXCL_START
145                 _D("Block module is not enabled");
146                 return STORAGE_ERROR_NOT_SUPPORTED;
147                 //LCOV_EXCL_STOP
148         }
149
150         ret_val = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
151         if (ret_val < 0) {
152                 _E("Failed to get root path of external storage(%d, %d", storage_id, ret_val);
153                 if (ret_val == -ENODEV || ret_val == -EINVAL)
154                         return STORAGE_ERROR_INVALID_PARAMETER;
155                 //LCOV_EXCL_START
156                 else if (ret_val == -ENOMEM)
157                         return STORAGE_ERROR_OUT_OF_MEMORY;
158                 else
159                         return STORAGE_ERROR_OPERATION_FAILED;
160                 //LCOV_EXCL_STOP
161         }
162
163         *path = strdup(root);
164         if (!*path) {
165                 //LCOV_EXCL_START System error
166                 _E("Failed to copy the root string : %d", errno);
167                 return STORAGE_ERROR_OUT_OF_MEMORY;
168                 //LCOV_EXCL_STOP
169         }
170
171         return STORAGE_ERROR_NONE;
172 }
173
174 API int storage_get_directory(int storage_id, storage_directory_e type, char **path)
175 {
176         const struct storage_ops *st;
177         char root[PATH_MAX];
178         char temp[PATH_MAX];
179         char *temp2, *end;
180         int ret_val;
181         GList *elem;
182         bool found;
183         bool extendedint;
184         bool user = true;
185
186         if (storage_id < 0)
187                 return STORAGE_ERROR_INVALID_PARAMETER;
188
189         if (!path) {
190                 _E("Invalid parameger");
191                 return STORAGE_ERROR_INVALID_PARAMETER;
192         }
193
194         if (type < 0 || type >= STORAGE_DIRECTORY_MAX) {
195                 _E("Invalid parameter");
196                 return STORAGE_ERROR_INVALID_PARAMETER;
197         }
198
199         /* internal storage */
200         found = false;
201         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
202                 if (st->storage_id != storage_id)
203                         continue;
204                 found = true;
205                 break;
206         }
207
208         if (getuid() <= USER_UID_START)
209                 user = false;
210
211         if (found && st) {
212                 if (!user) {
213                         _E("Only apps and user session daemons are allowed "
214                                         "to use storage_get_root_directory(INTERNAL_STORAGE_ID, ...)");
215
216                         return STORAGE_ERROR_INVALID_PARAMETER;
217                 }
218
219                 snprintf(root, sizeof(root), "%s", st->root());
220                 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
221                         temp2 = vconf_get_str(VCONFKEY_SETAPPL_CALL_RINGTONE_PATH_STR);
222                         if (temp2 == NULL)
223                                 return STORAGE_ERROR_OPERATION_FAILED;
224                         end = strrchr(temp2, '/');
225                         if (end)
226                                 *end = '\0';
227                         snprintf(temp, PATH_MAX, "%s", temp2);
228                         free(temp2);
229                 } else {
230                         if ((ret_val = snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type])) > PATH_MAX - 1) {
231                                 //LCOV_EXCL_START
232                                 _E("Path is longer than buffer. Need %d size of buffer.", ret_val + 1);
233                                 return STORAGE_ERROR_OUT_OF_MEMORY;
234                                 //LCOV_EXCL_STOP
235                         }
236                 }
237
238                 goto out;
239         }
240
241         /* external storage */
242         if (!storage_ext_is_supported()) {
243                 //LCOV_EXCL_START
244                 _D("Block module is not enabled");
245                 return STORAGE_ERROR_NOT_SUPPORTED;
246                 //LCOV_EXCL_STOP
247         }
248
249         if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
250                 _E("Not support directory : id(%d) type(%d)", storage_id, type);
251                 return STORAGE_ERROR_INVALID_PARAMETER;
252         }
253
254         ret_val = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
255         if (ret_val < 0) {
256                 _E("Failed to get root dir for external storage(id:%d, ret:%d)", storage_id, ret_val);
257                 if (ret_val == -ENODEV || ret_val == -EINVAL)
258                         return STORAGE_ERROR_INVALID_PARAMETER;
259                 //LCOV_EXCL_START
260                 else if (ret_val == -ENOMEM)
261                         return STORAGE_ERROR_OUT_OF_MEMORY;
262                 else
263                         return STORAGE_ERROR_OPERATION_FAILED;
264                 //LCOV_EXCL_STOP
265         }
266         /* The operation is not decided */
267         if (extendedint)
268                 return STORAGE_ERROR_INVALID_PARAMETER;
269
270         if ((ret_val = snprintf(temp, sizeof(temp), "%s/%s", root, dir_path[type])) > sizeof(temp) - 1) {
271                 //LCOV_EXCL_START
272                 _E("Path is longer than buffer. Need %d size of buffer.", ret_val + 1);
273                 return STORAGE_ERROR_OUT_OF_MEMORY;
274                 //LCOV_EXCL_STOP
275         }
276
277 out:
278         *path = strdup(temp);
279         if (!*path) {
280                 //LCOV_EXCL_START System error
281                 _E("Failed to copy the directory(%d) string : %d", type, errno);
282                 return STORAGE_ERROR_OUT_OF_MEMORY;
283                 //LCOV_EXCL_STOP
284         }
285
286         return STORAGE_ERROR_NONE;
287 }
288
289 API int storage_get_type(int storage_id, storage_type_e *type)
290 {
291         const struct storage_ops *st;
292         GList *elem;
293         char root[PATH_MAX];
294         int ret_val;
295         bool extendedint;
296
297         if (storage_id < 0)
298                 return STORAGE_ERROR_INVALID_PARAMETER;
299
300         if (!type) {
301                 _E("Invalid parameger");
302                 return STORAGE_ERROR_INVALID_PARAMETER;
303         }
304
305         /* internal storage */
306         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
307                 if (st->storage_id != storage_id)
308                         continue;
309                 *type = st->type;
310                 return STORAGE_ERROR_NONE;
311         }
312
313         /* external storage */
314         if (!storage_ext_is_supported()) {
315                 //LCOV_EXCL_START
316                 _D("Block module is not enabled");
317                 return STORAGE_ERROR_NOT_SUPPORTED;
318                 //LCOV_EXCL_STOP
319         }
320
321         ret_val = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
322         if (ret_val < 0) {
323                 _E("Failed to get type of external storage");
324                 if (ret_val == -ENODEV || ret_val == -EINVAL)
325                         return STORAGE_ERROR_INVALID_PARAMETER;
326                 //LCOV_EXCL_START
327                 else if (ret_val == -ENOMEM)
328                         return STORAGE_ERROR_OUT_OF_MEMORY;
329                 else
330                         return STORAGE_ERROR_OPERATION_FAILED;
331                 //LCOV_EXCL_STOP
332         }
333         if (extendedint)
334                 *type = STORAGE_TYPE_EXTENDED_INTERNAL;
335         else
336                 *type = STORAGE_TYPE_EXTERNAL;
337
338         return STORAGE_ERROR_NONE;
339 }
340
341 API int storage_get_state(int storage_id, storage_state_e *state)
342 {
343         const struct storage_ops *ops;
344         storage_state_e st;
345         GList *elem;
346         int ret_val;
347
348         if (storage_id < 0)
349                 return STORAGE_ERROR_INVALID_PARAMETER;
350
351         if (!state) {
352                 _E("Invalid parameger");
353                 return STORAGE_ERROR_INVALID_PARAMETER;
354         }
355
356         /* internal storage */
357         SYS_G_LIST_FOREACH(st_int_head, elem, ops) {
358                 if (ops->storage_id != storage_id)
359                         continue;
360                 *state = ops->get_state();
361                 return STORAGE_ERROR_NONE;
362         }
363
364         /* external storage */
365         if (!storage_ext_is_supported()) {
366                 //LCOV_EXCL_START
367                 _D("Block module is not enabled");
368                 return STORAGE_ERROR_NOT_SUPPORTED;
369                 //LCOV_EXCL_STOP
370         }
371
372         ret_val = storage_ext_get_state(storage_id, &st);
373         if (ret_val < 0) {
374                 _E("Failed to get state (storage id(%d), ret_val(%d))", storage_id, ret_val);
375                 if (ret_val == -ENODEV || ret_val == -EINVAL)
376                         return STORAGE_ERROR_INVALID_PARAMETER;
377                 //LCOV_EXCL_START
378                 else if (ret_val == -ENOMEM)
379                         return STORAGE_ERROR_OUT_OF_MEMORY;
380                 else
381                         return STORAGE_ERROR_OPERATION_FAILED;
382                 //LCOV_EXCL_STOP
383         }
384
385         *state = st;
386         return STORAGE_ERROR_NONE;
387 }
388
389 //LCOV_EXCL_START Not called Callback
390 static void compat_cb(int storage_id,
391                 storage_dev_e dev, storage_state_e state,
392                 const char *fstype, const char *fsuuid, const char *mountpath,
393                 bool primary, int flags, void *user_data)
394 {
395         struct compat_cb_info* ccb_info;
396         GList *elem;
397
398         if (storage_id == STORAGE_TYPE_EXTERNAL && dev == STORAGE_DEV_EXT_SDCARD)
399                 SYS_G_LIST_FOREACH(compat_cb_list, elem, ccb_info)
400                         ccb_info->user_cb(storage_id, state, ccb_info->user_data);
401 }
402 //LCOV_EXCL_STOP
403
404 API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data)
405 {
406         const struct storage_ops *st;
407         struct storage_cb_info info;
408         int ret;
409         GList *elem;
410
411         struct compat_cb_info* ccb_info;
412         static int compat_cb_init = 0;
413
414         if (storage_id < 0)
415                 return STORAGE_ERROR_INVALID_PARAMETER;
416
417         if (!callback) {
418                 _E("Invalid parameger");
419                 return STORAGE_ERROR_INVALID_PARAMETER;
420         }
421
422         /* For backward compatability */
423         if (storage_id == STORAGE_TYPE_EXTERNAL) {
424                 if (!storage_ext_is_supported()) {
425                         //LCOV_EXCL_START
426                         _D("Block module is not enabled");
427                         return STORAGE_ERROR_NOT_SUPPORTED;
428                         //LCOV_EXCL_STOP
429                 }
430
431                 if (!compat_cb_init) {
432                         ret = storage_set_changed_cb(STORAGE_TYPE_EXTERNAL, compat_cb, NULL);
433                         if (ret == STORAGE_ERROR_NONE)
434                                 compat_cb_init = 1;
435                         else
436                                 return ret;
437                 }
438
439                 ccb_info = malloc(sizeof(struct compat_cb_info));
440                 if (ccb_info == NULL)
441                         return STORAGE_ERROR_OPERATION_FAILED;
442                 ccb_info->user_cb = callback;
443                 ccb_info->user_data = user_data;
444                 SYS_G_LIST_APPEND(compat_cb_list, ccb_info);
445
446                 return STORAGE_ERROR_NONE;
447         }
448
449         /* Internal storage does not support registering changed callback */
450         SYS_G_LIST_FOREACH(st_int_head, elem, st)
451                 if (st->storage_id == storage_id)
452                         return STORAGE_ERROR_NONE;
453
454         /* external storage */
455         if (!storage_ext_is_supported()) {
456                 //LCOV_EXCL_START
457                 _D("Block module is not enabled");
458                 return STORAGE_ERROR_NOT_SUPPORTED;
459                 //LCOV_EXCL_STOP
460         }
461
462         info.id = storage_id;
463         info.state_cb = callback;
464         info.user_data = user_data;
465
466         ret = storage_ext_register_cb(STORAGE_CALLBACK_ID, &info);
467         if (ret < 0) {
468                 //LCOV_EXCL_START
469                 _E("Failed to register callback : id(%d)", storage_id);
470                 return STORAGE_ERROR_OPERATION_FAILED;
471                 //LCOV_EXCL_STOP
472         }
473
474         return STORAGE_ERROR_NONE;
475 }
476
477 API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback)
478 {
479         const struct storage_ops *st;
480         struct storage_cb_info info;
481         int ret_val;
482         GList *elem;
483
484         if (storage_id < 0)
485                 return STORAGE_ERROR_INVALID_PARAMETER;
486
487         if (!callback) {
488                 _E("Invalid parameger");
489                 return STORAGE_ERROR_INVALID_PARAMETER;
490         }
491
492         /* For backward compatability */
493         if (storage_id == STORAGE_TYPE_EXTERNAL) {
494                 if (!storage_ext_is_supported()) {
495                         //LCOV_EXCL_START
496                         _D("Block module is not enabled");
497                         return STORAGE_ERROR_NOT_SUPPORTED;
498                         //LCOV_EXCL_STOP
499                 }
500
501                 GList *elem_n;
502                 struct compat_cb_info* ccb_info;
503
504                 SYS_G_LIST_FOREACH_SAFE(compat_cb_list, elem, elem_n, ccb_info) {
505                         if (ccb_info->user_cb == callback) {
506                                 SYS_G_LIST_REMOVE(compat_cb_list, ccb_info);
507                                 free(ccb_info);
508                                 return STORAGE_ERROR_NONE;
509                         }
510                 }
511                 return STORAGE_ERROR_OPERATION_FAILED;
512         }
513
514         /* Internal storage does not support registering changed callback */
515         SYS_G_LIST_FOREACH(st_int_head, elem, st)
516                 if (st->storage_id == storage_id)
517                         return STORAGE_ERROR_NONE;
518
519         /* external storage */
520         if (!storage_ext_is_supported()) {
521                 //LCOV_EXCL_START
522                 _D("Block module is not enabled");
523                 return STORAGE_ERROR_NOT_SUPPORTED;
524                 //LCOV_EXCL_STOP
525         }
526
527         info.id = storage_id;
528         info.state_cb = callback;
529
530         ret_val = storage_ext_unregister_cb(STORAGE_CALLBACK_ID, &info);
531         if (ret_val < 0) {
532                 //LCOV_EXCL_START
533                 _E("Failed to unregister callback : id(%d)", storage_id);
534                 return STORAGE_ERROR_OPERATION_FAILED;
535                 //LCOV_EXCL_STOP
536         }
537
538         return STORAGE_ERROR_NONE;
539 }
540
541 API int storage_get_total_space(int storage_id, unsigned long long *bytes)
542 {
543         const struct storage_ops *st;
544         unsigned long long total;
545         int ret_val;
546         GList *elem;
547
548         if (storage_id < 0)
549                 return STORAGE_ERROR_INVALID_PARAMETER;
550
551         if (!bytes) {
552                 _E("Invalid parameger");
553                 return STORAGE_ERROR_INVALID_PARAMETER;
554         }
555
556         /* internal storage */
557         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
558                 if (st->storage_id != storage_id)
559                         continue;
560                 ret_val = st->get_space(&total, NULL);
561                 goto out;
562         }
563
564         /* external storage */
565         if (!storage_ext_is_supported()) {
566                 //LCOV_EXCL_START
567                 _D("Block module is not enabled");
568                 return STORAGE_ERROR_NOT_SUPPORTED;
569                 //LCOV_EXCL_STOP
570         }
571
572         ret_val = storage_ext_get_space(storage_id, &total, NULL);
573
574 out:
575         if (ret_val < 0) {
576                 _E("Failed to get total memory : id(%d)", storage_id);
577                 if (ret_val == -ENODEV || ret_val == -EINVAL)
578                         return STORAGE_ERROR_INVALID_PARAMETER;
579                 //LCOV_EXCL_START
580                 else if (ret_val == -ENOMEM)
581                         return STORAGE_ERROR_OUT_OF_MEMORY;
582                 else
583                         return STORAGE_ERROR_OPERATION_FAILED;
584                 //LCOV_EXCL_STOP
585         }
586
587         *bytes = total;
588         return STORAGE_ERROR_NONE;
589 }
590
591 API int storage_get_available_space(int storage_id, unsigned long long *bytes)
592 {
593         const struct storage_ops *st;
594         unsigned long long avail;
595         int ret_val;
596         GList *elem;
597
598         if (storage_id < 0)
599                 return STORAGE_ERROR_INVALID_PARAMETER;
600
601         if (!bytes) {
602                 _E("Invalid parameger");
603                 return STORAGE_ERROR_INVALID_PARAMETER;
604         }
605
606         /* internal storage */
607         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
608                 if (st->storage_id != storage_id)
609                         continue;
610                 ret_val = st->get_space(NULL, &avail);
611                 goto out;
612         }
613
614         /* external storage */
615         if (!storage_ext_is_supported()) {
616                 //LCOV_EXCL_START
617                 _D("Block module is not enabled");
618                 return STORAGE_ERROR_NOT_SUPPORTED;
619                 //LCOV_EXCL_STOP
620         }
621
622         ret_val = storage_ext_get_space(storage_id, NULL, &avail);
623
624 out:
625         if (ret_val < 0) {
626                 _E("Failed to get available memory : id(%d)", storage_id);
627                 if (ret_val == -ENODEV || ret_val == -EINVAL)
628                         return STORAGE_ERROR_INVALID_PARAMETER;
629                 //LCOV_EXCL_START
630                 else if (ret_val == -ENOMEM)
631                         return STORAGE_ERROR_OUT_OF_MEMORY;
632                 else
633                         return STORAGE_ERROR_OPERATION_FAILED;
634                 //LCOV_EXCL_STOP
635         }
636
637         *bytes = avail;
638         return STORAGE_ERROR_NONE;
639 }
640
641 API int storage_set_changed_cb(storage_type_e type, storage_changed_cb callback, void *user_data)
642 {
643         int ret_val;
644         struct storage_cb_info info;
645
646         if (type == STORAGE_TYPE_INTERNAL) {
647                 _E("Internal storage is not supported");
648                 return STORAGE_ERROR_INVALID_PARAMETER;
649         }
650
651         if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
652                 _E("Invalid type (%d)", type);
653                 return STORAGE_ERROR_INVALID_PARAMETER;
654         }
655
656         if (!callback) {
657                 _E("Callback is NULL");
658                 return STORAGE_ERROR_INVALID_PARAMETER;
659         }
660
661         if (!storage_ext_is_supported()) {
662                 //LCOV_EXCL_START
663                 _E("Block module is not enabled");
664                 return STORAGE_ERROR_NOT_SUPPORTED;
665                 //LCOV_EXCL_STOP
666         }
667
668         /* external storage */
669         info.type = type;
670         info.type_cb = callback;
671         info.user_data = user_data;
672
673         ret_val = storage_ext_register_cb(STORAGE_CALLBACK_TYPE, &info);
674         if (ret_val < 0) {
675                 //LCOV_EXCL_START
676                 _E("Failed to register storage callback(ret:%d)", ret_val);
677                 return STORAGE_ERROR_OPERATION_FAILED;
678                 //LCOV_EXCL_STOP
679         }
680
681         return STORAGE_ERROR_NONE;
682 }
683
684 API int storage_unset_changed_cb(storage_type_e type, storage_changed_cb callback)
685 {
686         struct storage_cb_info info;
687         int ret_val;
688
689         if (type == STORAGE_TYPE_INTERNAL) {
690                 _E("Internal storage is not supported");
691                 return STORAGE_ERROR_INVALID_PARAMETER;
692         }
693
694         if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
695                 _E("Invalid type (%d)", type);
696                 return STORAGE_ERROR_INVALID_PARAMETER;
697         }
698
699         if (!callback) {
700                 _E("Callback is NULL");
701                 return STORAGE_ERROR_INVALID_PARAMETER;
702         }
703
704         if (!storage_ext_is_supported()) {
705                 //LCOV_EXCL_START
706                 _E("Block module is not enabled");
707                 return STORAGE_ERROR_NOT_SUPPORTED;
708                 //LCOV_EXCL_STOP
709         }
710
711         /* external storage */
712         info.type = type;
713         info.type_cb = callback;
714
715         ret_val = storage_ext_unregister_cb(STORAGE_CALLBACK_TYPE, &info);
716         if (ret_val < 0) {
717                 //LCOV_EXCL_START
718                 _E("Failed to unregister storage callback(ret:%d)", ret_val);
719                 return STORAGE_ERROR_OPERATION_FAILED;
720                 //LCOV_EXCL_STOP
721         }
722
723         return STORAGE_ERROR_NONE;
724 }
725
726 API int storage_get_type_dev(int storage_id, storage_type_e *type, storage_dev_e *dev)
727 {
728         storage_ext_device *ext_dev;
729         int ret;
730
731         if (storage_id < 0 || !type || !dev) {
732                 _E("Invalid parameter");
733                 return STORAGE_ERROR_INVALID_PARAMETER;
734         }
735
736         ret = storage_get_type(storage_id, type);
737         if (ret != STORAGE_ERROR_NONE) {
738                 //LCOV_EXCL_START
739                 _E("Failed to get storage type: %d", ret);
740                 return ret;
741                 //LCOV_EXCL_STOP
742         }
743         if (*type == STORAGE_TYPE_INTERNAL || *type == STORAGE_TYPE_EXTENDED_INTERNAL)
744                 return STORAGE_ERROR_INVALID_PARAMETER;
745
746         if (!storage_ext_is_supported()) {
747                 //LCOV_EXCL_START
748                 _D("Block module is not enabled");
749                 return STORAGE_ERROR_NOT_SUPPORTED;
750                 //LCOV_EXCL_STOP
751         }
752
753         ext_dev = calloc(1, sizeof(storage_ext_device));
754         if (!ext_dev) {
755                 //LCOV_EXCL_START System Error
756                 _E("calloc failed");
757                 return STORAGE_ERROR_OUT_OF_MEMORY;
758                 //LCOV_EXCL_STOP
759         }
760
761         ret = storage_ext_get_device_info(storage_id, ext_dev);
762         if (ret < 0) {
763                 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
764                 if (ret == -ENODEV) {
765                         ret =  STORAGE_ERROR_INVALID_PARAMETER;
766                         goto out;
767                 }
768                 //LCOV_EXCL_START
769                 ret = STORAGE_ERROR_OPERATION_FAILED;
770                 goto out;
771                 //LCOV_EXCL_STOP
772         }
773
774         if (ext_dev->type == STORAGE_EXT_SCSI)
775                 *dev = STORAGE_DEV_EXT_USB_MASS_STORAGE;
776         else if (ext_dev->type == STORAGE_EXT_MMC)
777                 *dev = STORAGE_DEV_EXT_SDCARD;
778         ret = STORAGE_ERROR_NONE;
779         _I("type: %d(internal:0, external:1) dev: %d(sdcard: 1001, usb: 1002)", *type, *dev);
780
781 out:
782         storage_ext_release_device(&ext_dev);
783         return ret;
784 }
785
786 static void __CONSTRUCTOR__ init(void)
787 {
788         const char *tmp;
789         char *token;
790         int i;
791
792         for (i = 0 ; i <= STORAGE_DIRECTORY_OTHERS ; i++) {
793                 tmp = tzplatform_getenv(tz_id[i]);
794                 if (tmp != NULL) {
795                         token = rindex(tmp, '/');
796                         if (token != NULL) {
797                                 token++;
798                                 dir_path[i] = strdup(token);
799                         }
800                 }
801         }
802 }