cbe34b5a02d8ad99424e27662d9d975b6b084f63
[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
23 #include "common.h"
24 #include "list.h"
25 #include "log.h"
26
27 const char *dir_path[STORAGE_DIRECTORY_MAX] = {
28         [STORAGE_DIRECTORY_IMAGES] = "Images",
29         [STORAGE_DIRECTORY_SOUNDS] = "Sounds",
30         [STORAGE_DIRECTORY_VIDEOS] = "Videos",
31         [STORAGE_DIRECTORY_CAMERA] = "DCIM",
32         [STORAGE_DIRECTORY_DOWNLOADS] = "Downloads",
33         [STORAGE_DIRECTORY_MUSIC] = "Music",
34         [STORAGE_DIRECTORY_DOCUMENTS] = "Documents",
35         [STORAGE_DIRECTORY_OTHERS] = "Others",
36         [STORAGE_DIRECTORY_SYSTEM_RINGTONES] = "/opt/usr/share/settings/Ringtones",
37 };
38
39 static dd_list *st_head;
40
41 void add_device(const struct storage_ops *st)
42 {
43         DD_LIST_APPEND(st_head, st);
44 }
45
46 void remove_device(const struct storage_ops *st)
47 {
48         DD_LIST_REMOVE(st_head, st);
49 }
50
51 API int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data)
52 {
53         const struct storage_ops *st;
54         dd_list *elem;
55         int storage_id = 0, ret;
56
57         if (!callback) {
58                 _E("Invalid parameter");
59                 return STORAGE_ERROR_INVALID_PARAMETER;
60         }
61
62         DD_LIST_FOREACH(st_head, elem, st) {
63                 ret = callback(storage_id, st->type, st->get_state(),
64                                 st->root(), user_data);
65                 /* if the return value is false, will be stop to iterate */
66                 if (!ret)
67                         break;
68                 storage_id++;
69         }
70
71         return STORAGE_ERROR_NONE;
72 }
73
74 API int storage_get_root_directory(int storage_id, char **path)
75 {
76         const struct storage_ops *st;
77
78         if (!path) {
79                 _E("Invalid parameger");
80                 return STORAGE_ERROR_INVALID_PARAMETER;
81         }
82
83         st = DD_LIST_NTH(st_head, storage_id);
84         if (!st) {
85                 _E("Not supported storage : id(%d)", storage_id);
86                 return STORAGE_ERROR_NOT_SUPPORTED;
87         }
88
89         *path = strdup(st->root());
90         if (!*path) {
91                 _E("Failed to copy the root string : %d", errno);
92                 return STORAGE_ERROR_OUT_OF_MEMORY;
93         }
94
95         return STORAGE_ERROR_NONE;
96 }
97
98 API int storage_get_directory(int storage_id, storage_directory_e type, char **path)
99 {
100         const struct storage_ops *st;
101         const char *root;
102         char temp[PATH_MAX];
103
104         if (!path) {
105                 _E("Invalid parameger");
106                 return STORAGE_ERROR_INVALID_PARAMETER;
107         }
108
109         if (type < 0 || type >= STORAGE_DIRECTORY_MAX) {
110                 _E("Invalid parameter");
111                 return STORAGE_ERROR_INVALID_PARAMETER;
112         }
113
114         st = DD_LIST_NTH(st_head, storage_id);
115         if (!st) {
116                 _E("Not supported storage : id(%d)", storage_id);
117                 return STORAGE_ERROR_NOT_SUPPORTED;
118         }
119
120         if (st->type != STORAGE_TYPE_INTERNAL
121             && type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
122                 _E("Not support directory : id(%d) type(%d)", storage_id, type);
123                 return STORAGE_ERROR_NOT_SUPPORTED;
124         }
125
126         root = st->root();
127         if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES)
128                 snprintf(temp, PATH_MAX, "%s", dir_path[type]);
129         else
130                 snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type]);
131
132         *path = strdup(temp);
133         if (!*path) {
134                 _E("Failed to copy the directory(%d) string : %d", type, errno);
135                 return STORAGE_ERROR_OUT_OF_MEMORY;
136         }
137
138         return STORAGE_ERROR_NONE;
139 }
140
141 API int storage_get_type(int storage_id, storage_type_e *type)
142 {
143         const struct storage_ops *st;
144
145         if (!type) {
146                 _E("Invalid parameger");
147                 return STORAGE_ERROR_INVALID_PARAMETER;
148         }
149
150         st = DD_LIST_NTH(st_head, storage_id);
151         if (!st) {
152                 _E("Not supported storage : id(%d)", storage_id);
153                 return STORAGE_ERROR_NOT_SUPPORTED;
154         }
155
156         *type = st->type;
157
158         return STORAGE_ERROR_NONE;
159 }
160
161 API int storage_get_state(int storage_id, storage_state_e *state)
162 {
163         const struct storage_ops *st;
164
165         if (!state) {
166                 _E("Invalid parameger");
167                 return STORAGE_ERROR_INVALID_PARAMETER;
168         }
169
170         st = DD_LIST_NTH(st_head, storage_id);
171         if (!st) {
172                 _E("Not supported storage : id(%d)", storage_id);
173                 return STORAGE_ERROR_NOT_SUPPORTED;
174         }
175
176         *state = st->get_state();
177
178         return STORAGE_ERROR_NONE;
179 }
180
181 API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data)
182 {
183         const struct storage_ops *st;
184         struct storage_cb_info info;
185         int ret;
186
187         if (!callback) {
188                 _E("Invalid parameger");
189                 return STORAGE_ERROR_INVALID_PARAMETER;
190         }
191
192         st = DD_LIST_NTH(st_head, storage_id);
193         if (!st) {
194                 _E("Not supported storage : id(%d)", storage_id);
195                 return STORAGE_ERROR_NOT_SUPPORTED;
196         }
197
198         /* do not register changed callback in case of internal memory */
199         if (st->type == STORAGE_TYPE_INTERNAL)
200                 return STORAGE_ERROR_NONE;
201
202         info.id = storage_id;
203         info.state_cb = callback;
204         info.user_data = user_data;
205
206         ret = st->register_cb(STORAGE_CALLBACK_STATE, &info);
207         if (ret < 0) {
208                 _E("Failed to register callback : id(%d)", storage_id);
209                 return STORAGE_ERROR_OPERATION_FAILED;
210         }
211
212         return STORAGE_ERROR_NONE;
213 }
214
215 API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback)
216 {
217         const struct storage_ops *st;
218         struct storage_cb_info info;
219         int ret;
220
221         if (!callback) {
222                 _E("Invalid parameger");
223                 return STORAGE_ERROR_INVALID_PARAMETER;
224         }
225
226         st = DD_LIST_NTH(st_head, storage_id);
227         if (!st) {
228                 _E("Not supported storage : id(%d)", storage_id);
229                 return STORAGE_ERROR_NOT_SUPPORTED;
230         }
231
232         /* in case of internal memory, it does not register changed callback */
233         if (st->type == STORAGE_TYPE_INTERNAL)
234                 return STORAGE_ERROR_NONE;
235
236         info.id = storage_id;
237         info.state_cb = callback;
238
239         ret = st->unregister_cb(STORAGE_CALLBACK_STATE, &info);
240         if (ret < 0) {
241                 _E("Failed to unregister callback : id(%d)", storage_id);
242                 return STORAGE_ERROR_OPERATION_FAILED;
243         }
244
245         return STORAGE_ERROR_NONE;
246 }
247
248 API int storage_get_total_space(int storage_id, unsigned long long *bytes)
249 {
250         const struct storage_ops *st;
251         unsigned long long total;
252         int ret;
253
254         if (!bytes) {
255                 _E("Invalid parameger");
256                 return STORAGE_ERROR_INVALID_PARAMETER;
257         }
258
259         st = DD_LIST_NTH(st_head, storage_id);
260         if (!st) {
261                 _E("Not supported storage : id(%d)", storage_id);
262                 return STORAGE_ERROR_NOT_SUPPORTED;
263         }
264
265         ret = st->get_space(&total, NULL);
266         if (ret < 0) {
267                 _E("Failed to get total memory : id(%d)", storage_id);
268                 return STORAGE_ERROR_OPERATION_FAILED;
269         }
270
271         *bytes = total;
272
273         return STORAGE_ERROR_NONE;
274 }
275
276 API int storage_get_available_space(int storage_id, unsigned long long *bytes)
277 {
278         const struct storage_ops *st;
279         unsigned long long avail;
280         int ret;
281
282         if (!bytes) {
283                 _E("Invalid parameger");
284                 return STORAGE_ERROR_INVALID_PARAMETER;
285         }
286
287         st = DD_LIST_NTH(st_head, storage_id);
288         if (!st) {
289                 _E("Not supported storage : id(%d)", storage_id);
290                 return STORAGE_ERROR_NOT_SUPPORTED;
291         }
292
293         ret = st->get_space(NULL, &avail);
294         if (ret < 0) {
295                 _E("Failed to get available memory : id(%d)", storage_id);
296                 return STORAGE_ERROR_OPERATION_FAILED;
297         }
298
299         *bytes = avail;
300
301         return STORAGE_ERROR_NONE;
302 }