81894cb9002d1ff057310ef1db3f6372cf7cd71e
[framework/api/application.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 <sys/vfs.h>
22
23 #include <aul.h>
24 #include <dlog.h>
25 #include <vconf.h>
26
27 #include <app_storage.h>
28 #include <app_storage_private.h>
29
30 #ifdef LOG_TAG
31 #undef LOG_TAG
32 #endif
33
34 #define LOG_TAG "CAPI_APPFW_APPLICATION_STORAGE"
35
36 static int storage_initialize();
37 static int storage_register_device(storage_device_h device);
38 static int storage_get_storage(int id, storage_info_h* storage_info);
39
40 extern storage_device_h storage_internal_device();
41 extern storage_device_h storage_sdcard_device();
42 extern storage_device_h storage_usbhost_device();
43
44 extern int storage_internal_get_state();
45 extern int storage_sdcard_get_state();
46 extern int storage_usbhost_get_state();
47
48 #define STORAGE_MAX 3
49 static struct storage_info_s storage_info_table[STORAGE_MAX];
50 static int storage_num = 0;
51
52 static int storage_register_device(storage_device_h device)
53 {
54         if (device == NULL)
55         {
56                 return -1;
57         }
58
59         if (storage_num >= STORAGE_MAX)
60         {
61                 LOGE("failed to register device : not enough device table");
62                 return -1;
63         }
64
65         storage_info_table[storage_num].id = storage_num;
66         storage_info_table[storage_num].device = device;
67         storage_info_table[storage_num].state = device->get_state();
68         storage_info_table[storage_num].state_cb = NULL;
69         storage_info_table[storage_num].state_cb_data = NULL;
70
71         storage_num++;
72
73         return 0;
74 }
75
76 static int storage_initialize()
77 {
78         storage_device_h dev_internal;
79         storage_device_h dev_sdcard;
80         storage_device_h dev_usbhost;
81
82         dev_internal = storage_internal_device();
83         storage_register_device(dev_internal);
84
85         dev_sdcard = storage_sdcard_device();
86         storage_register_device(dev_sdcard);
87
88         dev_usbhost = storage_usbhost_device();
89         storage_register_device(dev_usbhost);
90
91         return 0;
92 }
93
94 static int storage_get_storage(int id, storage_info_h* storage_info)
95 {
96         int device_state = -1;
97
98         if (storage_num < 1)
99         {
100                 if (storage_initialize() != 0)
101                 {
102                         return STORAGE_ERROR_NOT_SUPPORTED;
103                 }
104         }
105
106         if (id < 0 || id >= storage_num)
107         {
108                 return STORAGE_ERROR_NOT_SUPPORTED;
109         }
110
111         switch (id)
112         {
113         case 0:
114                 device_state = storage_internal_get_state();
115                 break;
116         case 1:
117                 device_state = storage_sdcard_get_state();
118                 break;
119         case 2:
120                 device_state = storage_usbhost_get_state();
121                 break;
122         default:
123                 LOGE("Device statei is invalid");
124                 break;
125         }
126         storage_info_table[id].state = device_state;
127         *storage_info = &(storage_info_table[id]);
128
129         return STORAGE_ERROR_NONE;
130 }
131
132 int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data)
133 {
134         int storage_id = 0;
135         storage_info_h storage_info = NULL;
136         bool foreach_next = false;
137
138         if (callback == NULL)
139         {
140                 LOGE("INVALID_PARAMETER(0x%08x) : invalid callback", STORAGE_ERROR_INVALID_PARAMETER);
141                 return STORAGE_ERROR_INVALID_PARAMETER;
142         }
143
144         while (true)
145         {
146                 if (storage_get_storage(storage_id, &storage_info) != 0)
147                 {
148                         break;
149                 }
150
151                 storage_id++;
152
153                 foreach_next = callback(storage_info->id, storage_info->device->type, storage_info->state, storage_info->device->path, user_data);
154
155                 if (foreach_next == false)
156                 {
157                         break;
158                 }
159         }
160
161         return STORAGE_ERROR_NONE;
162 }
163
164
165 int storage_get_root_directory(int storage, char **path)
166 {
167         storage_info_h storage_info;
168
169         if (path == NULL)
170         {
171                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", STORAGE_ERROR_INVALID_PARAMETER);
172                 return STORAGE_ERROR_INVALID_PARAMETER;
173         }
174
175         if (storage_get_storage(storage, &storage_info) != 0)
176         {
177                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
178                 return STORAGE_ERROR_NOT_SUPPORTED;
179         }
180
181         *path = strdup(storage_info->device->path);
182
183         return STORAGE_ERROR_NONE;
184 }
185
186
187 int storage_get_type(int storage, storage_type_e *type)
188 {
189         storage_info_h storage_info;
190
191         if (type == NULL)
192         {
193                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", STORAGE_ERROR_INVALID_PARAMETER);
194                 return STORAGE_ERROR_INVALID_PARAMETER;
195         }
196
197         if (storage_get_storage(storage, &storage_info) != 0)
198         {
199                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
200                 return STORAGE_ERROR_NOT_SUPPORTED;
201         }
202
203         *type = storage_info->device->type;
204
205         return STORAGE_ERROR_NONE;
206 }
207
208
209 int storage_get_state(int storage, storage_state_e *state)
210 {
211         storage_info_h storage_info;
212         storage_dev_get_state get_state;
213
214         if (state == NULL)
215         {
216                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", STORAGE_ERROR_INVALID_PARAMETER);
217                 return STORAGE_ERROR_INVALID_PARAMETER;
218         }
219
220         if (storage_get_storage(storage, &storage_info) != 0)
221         {
222                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
223                 return STORAGE_ERROR_NOT_SUPPORTED;
224         }
225
226         get_state = storage_info->device->get_state;
227
228         if (get_state == NULL)
229         {
230                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
231                 return STORAGE_ERROR_NOT_SUPPORTED;
232         }
233
234         storage_info->state = get_state();
235
236         *state = storage_info->state;
237
238         return STORAGE_ERROR_NONE;
239 }
240
241
242 void storage_dispatch_state_event(storage_state_e state, void* data)
243 {
244         storage_info_h storage_info;
245         storage_state_changed_cb state_cb;
246
247         storage_info = data;
248
249         if (storage_info == NULL)
250         {
251                 LOGE("INVALID_PARAMETER(0x%08x) : invalid storage information", STORAGE_ERROR_INVALID_PARAMETER);
252                 return;
253         }
254
255         storage_info->state = state;
256         state_cb = storage_info->state_cb;
257
258         if (state_cb != NULL)
259         {
260                 state_cb(storage_info->id, state, storage_info->state_cb_data);
261         }
262 }
263
264
265 int storage_set_state_changed_cb(int storage, storage_state_changed_cb callback, void *user_data)
266 {
267         storage_info_h storage_info;
268         storage_dev_set_state_cb set_state_cb;
269
270         if (callback == NULL)
271         {
272                 LOGE("INVALID_PARAMETER(0x%08x) : invalid callback", STORAGE_ERROR_INVALID_PARAMETER);
273                 return STORAGE_ERROR_INVALID_PARAMETER;
274         }
275
276         if (storage_get_storage(storage, &storage_info) != 0)
277         {
278                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
279                 return STORAGE_ERROR_NOT_SUPPORTED;
280         }
281
282         storage_info->state_cb = callback;
283         storage_info->state_cb_data = user_data;
284
285         set_state_cb = storage_info->device->set_state_cb;
286
287         if (set_state_cb == NULL)
288         {
289                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
290                 return STORAGE_ERROR_NOT_SUPPORTED;
291         }
292
293         if (set_state_cb(storage_info) != 0)
294         {
295                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
296                 return STORAGE_ERROR_NOT_SUPPORTED;
297         }
298
299         return STORAGE_ERROR_NONE;
300 }
301
302
303 int storage_unset_state_changed_cb(int storage)
304 {
305         storage_info_h storage_info;
306         storage_dev_unset_state_cb unset_state_cb;
307
308         if (storage_get_storage(storage, &storage_info) != 0)
309         {
310                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
311                 return STORAGE_ERROR_NOT_SUPPORTED;
312         }
313
314         storage_info->state_cb = NULL;
315         unset_state_cb = storage_info->device->unset_state_cb;
316
317         if (unset_state_cb != NULL)
318         {
319                 unset_state_cb();
320         }
321
322         return STORAGE_ERROR_NONE;
323 }
324
325
326 int storage_get_total_space(int storage, unsigned long long *bytes)
327 {
328         storage_info_h storage_info;
329         storage_dev_get_space get_space;
330
331         if (bytes == NULL)
332         {
333                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", STORAGE_ERROR_INVALID_PARAMETER);
334                 return STORAGE_ERROR_INVALID_PARAMETER;
335         }
336
337         if (storage_get_storage(storage, &storage_info) != 0)
338         {
339                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
340                 return STORAGE_ERROR_NOT_SUPPORTED;
341         }
342
343         get_space = storage_info->device->get_space;
344
345         if (get_space == NULL)
346         {
347                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
348                 return STORAGE_ERROR_NOT_SUPPORTED;
349         }
350
351         if (get_space(bytes, NULL) != 0)
352         {
353                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
354                 return STORAGE_ERROR_NOT_SUPPORTED;
355         }
356
357         return STORAGE_ERROR_NONE;
358 }
359
360 int storage_get_available_space(int storage, unsigned long long *bytes)
361 {
362         storage_info_h storage_info;
363         storage_dev_get_space get_space;
364
365         if (bytes == NULL)
366         {
367                 LOGE("INVALID_PARAMETER(0x%08x) : invalid output param", STORAGE_ERROR_INVALID_PARAMETER);
368                 return STORAGE_ERROR_INVALID_PARAMETER;
369         }
370
371         if (storage_get_storage(storage, &storage_info) != 0)
372         {
373                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
374                 return STORAGE_ERROR_NOT_SUPPORTED;
375         }
376
377         get_space = storage_info->device->get_space;
378
379         if (get_space == NULL)
380         {
381                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
382                 return STORAGE_ERROR_NOT_SUPPORTED;
383         }
384
385         if (get_space(NULL, bytes) != 0)
386         {
387                 LOGE("NOT_SUPPORTED(0x%08x) : storage(%d)", STORAGE_ERROR_NOT_SUPPORTED, storage);
388                 return STORAGE_ERROR_NOT_SUPPORTED;
389         }
390
391         return STORAGE_ERROR_NONE;
392 }
393
394 int storage_statfs(const char *directory, unsigned long long *total, unsigned long long *available)
395 {
396         struct statfs fs;
397
398         if (statfs(directory, &fs) < 0)
399         {
400                 LOGE("statfs returns error(%d) directory(%s)\n", errno, directory);
401                 return -1;
402         }
403
404         if (total != NULL)
405         {
406                 *total = (unsigned long long)fs.f_bsize * (unsigned long long)fs.f_blocks;
407         }
408
409         if (available != NULL)
410         {
411                 *available = (unsigned long long)fs.f_bsize * (unsigned long long)fs.f_bavail;
412         }
413
414         return 0;
415 }
416