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.
22 #include <system_settings.h>
27 #include "storage-external.h"
29 const char *dir_path[STORAGE_DIRECTORY_MAX] = {
30 [STORAGE_DIRECTORY_IMAGES] = "Images",
31 [STORAGE_DIRECTORY_SOUNDS] = "Sounds",
32 [STORAGE_DIRECTORY_VIDEOS] = "Videos",
33 [STORAGE_DIRECTORY_CAMERA] = "Camera",
34 [STORAGE_DIRECTORY_DOWNLOADS] = "Downloads",
35 [STORAGE_DIRECTORY_MUSIC] = "Music",
36 [STORAGE_DIRECTORY_DOCUMENTS] = "Documents",
37 [STORAGE_DIRECTORY_OTHERS] = "Others",
38 [STORAGE_DIRECTORY_SYSTEM_RINGTONES] = "",
41 static dd_list *st_int_head; /* Internal storage list */
43 static dd_list *compat_cb_list;
44 struct compat_cb_info {
45 storage_state_changed_cb user_cb;
49 void add_device(const struct storage_ops *st)
51 DD_LIST_APPEND(st_int_head, st);
54 void remove_device(const struct storage_ops *st)
56 DD_LIST_REMOVE(st_int_head, st);
59 API int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data)
61 const struct storage_ops *st;
66 _E("Invalid parameter");
67 return STORAGE_ERROR_INVALID_PARAMETER;
70 DD_LIST_FOREACH(st_int_head, elem, st) {
71 ret = callback(st->storage_id, st->type, st->get_state(),
72 st->root(), user_data);
73 /* if the return value is false, will be stop to iterate */
78 ret = storage_ext_foreach_device_list(callback, user_data);
80 _E("Failed to iterate external devices (%d)", ret); //LCOV_EXCL_LINE
81 return STORAGE_ERROR_OPERATION_FAILED;
84 return STORAGE_ERROR_NONE;
87 API int storage_get_root_directory(int storage_id, char **path)
89 const struct storage_ops *st;
95 return STORAGE_ERROR_NOT_SUPPORTED;
98 _E("Invalid parameger");
99 return STORAGE_ERROR_INVALID_PARAMETER;
102 /* internal storage */
103 DD_LIST_FOREACH(st_int_head, elem, st) {
104 if (st->storage_id != storage_id)
106 *path = strdup(st->root());
108 //LCOV_EXCL_START System Error
109 _E("Failed to copy the root string : %d", errno);
110 return STORAGE_ERROR_OUT_OF_MEMORY;
113 return STORAGE_ERROR_NONE;
116 /* external storage */
117 ret = storage_ext_get_root(storage_id, root, sizeof(root));
119 _E("Failed to get root path of external storage(%d, %d", storage_id, ret); //LCOV_EXCL_LINE
120 return STORAGE_ERROR_INVALID_PARAMETER;
123 *path = strdup(root);
125 _E("Failed to copy the root string : %d", errno);
126 return STORAGE_ERROR_OUT_OF_MEMORY;
129 return STORAGE_ERROR_NONE;
132 API int storage_get_directory(int storage_id, storage_directory_e type, char **path)
134 const struct storage_ops *st;
143 return STORAGE_ERROR_NOT_SUPPORTED;
146 _E("Invalid parameger");
147 return STORAGE_ERROR_INVALID_PARAMETER;
150 if (type < 0 || type >= STORAGE_DIRECTORY_MAX) {
151 _E("Invalid parameter");
152 return STORAGE_ERROR_INVALID_PARAMETER;
155 /* internal storage */
157 DD_LIST_FOREACH(st_int_head, elem, st) {
158 if (st->storage_id != storage_id)
165 snprintf(root, sizeof(root), "%s", st->root());
166 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
167 ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_INCOMING_CALL_RINGTONE, &temp2);
169 _E("Failed to get ringtone path : %d", ret); //LCOV_EXCL_LINE
170 return STORAGE_ERROR_OPERATION_FAILED;
172 end = strrchr(temp2, '/');
175 snprintf(temp, PATH_MAX, "%s", temp2);
178 snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type]);
183 /* external storage */
184 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
185 _E("Not support directory : id(%d) type(%d)", storage_id, type); //LCOV_EXCL_LINE
186 return STORAGE_ERROR_NOT_SUPPORTED;
189 ret = storage_ext_get_root(storage_id, root, sizeof(root));
191 _E("Failed to get root dir for external storage(id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
192 return STORAGE_ERROR_OPERATION_FAILED;
195 snprintf(temp, sizeof(temp), "%s/%s", root, dir_path[type]);
198 *path = strdup(temp);
200 _E("Failed to copy the directory(%d) string : %d", type, errno); //LCOV_EXCL_LINE
201 return STORAGE_ERROR_OUT_OF_MEMORY;
204 return STORAGE_ERROR_NONE;
207 API int storage_get_type(int storage_id, storage_type_e *type)
209 const struct storage_ops *st;
213 return STORAGE_ERROR_NOT_SUPPORTED;
216 _E("Invalid parameger");
217 return STORAGE_ERROR_INVALID_PARAMETER;
220 /* internal storage */
221 DD_LIST_FOREACH(st_int_head, elem, st) {
222 if (st->storage_id != storage_id)
225 return STORAGE_ERROR_NONE;
228 /* external storage */
229 *type = STORAGE_TYPE_EXTERNAL;
231 return STORAGE_ERROR_NONE;
234 API int storage_get_state(int storage_id, storage_state_e *state)
236 const struct storage_ops *ops;
242 return STORAGE_ERROR_NOT_SUPPORTED;
245 _E("Invalid parameger");
246 return STORAGE_ERROR_INVALID_PARAMETER;
249 /* internal storage */
250 DD_LIST_FOREACH(st_int_head, elem, ops) {
251 if (ops->storage_id != storage_id)
253 *state = ops->get_state();
254 return STORAGE_ERROR_NONE;
257 /* external storage */
258 ret = storage_ext_get_state(storage_id, &st);
260 _E("Failed to get state (storage id(%d), ret(%d))", storage_id, ret); //LCOV_EXCL_LINE
261 return STORAGE_ERROR_OPERATION_FAILED;
265 return STORAGE_ERROR_NONE;
268 static void compat_cb(int storage_id,
269 storage_dev_e dev, storage_state_e state,
270 const char *fstype, const char *fsuuid, const char *mountpath,
271 bool primary, int flags, void *user_data)
273 struct compat_cb_info* ccb_info;
276 if (storage_id == STORAGE_TYPE_EXTERNAL && dev == STORAGE_DEV_EXT_SDCARD)
277 DD_LIST_FOREACH(compat_cb_list, elem, ccb_info)
278 ccb_info->user_cb(storage_id, state, ccb_info->user_data);
281 API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data)
283 const struct storage_ops *st;
284 struct storage_cb_info info;
288 struct compat_cb_info* ccb_info;
289 static int compat_cb_init = 0;
292 return STORAGE_ERROR_NOT_SUPPORTED;
295 _E("Invalid parameger");
296 return STORAGE_ERROR_INVALID_PARAMETER;
299 /* For backward compatability */
300 if (storage_id == STORAGE_TYPE_EXTERNAL) {
301 if (!compat_cb_init) {
302 ret = storage_set_changed_cb(STORAGE_TYPE_EXTERNAL, compat_cb, NULL);
303 if (ret == STORAGE_ERROR_NONE)
309 ccb_info = malloc(sizeof(struct compat_cb_info));
310 if (ccb_info == NULL)
311 return STORAGE_ERROR_OPERATION_FAILED;
312 ccb_info->user_cb = callback;
313 ccb_info->user_data = user_data;
314 DD_LIST_APPEND(compat_cb_list, ccb_info);
316 return STORAGE_ERROR_NONE;
319 /* Internal storage does not support registering changed callback */
320 DD_LIST_FOREACH(st_int_head, elem, st)
321 if (st->storage_id == storage_id)
322 return STORAGE_ERROR_NONE;
324 /* external storage */
325 info.id = storage_id;
326 info.state_cb = callback;
327 info.user_data = user_data;
329 ret = storage_ext_register_cb(STORAGE_CALLBACK_ID, &info);
331 _E("Failed to register callback : id(%d)", storage_id); //LCOV_EXCL_LINE
332 return STORAGE_ERROR_OPERATION_FAILED;
335 return STORAGE_ERROR_NONE;
338 API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback)
340 const struct storage_ops *st;
341 struct storage_cb_info info;
346 return STORAGE_ERROR_NOT_SUPPORTED;
349 _E("Invalid parameger");
350 return STORAGE_ERROR_INVALID_PARAMETER;
353 /* For backward compatability */
354 if (storage_id == STORAGE_TYPE_EXTERNAL) {
356 struct compat_cb_info* ccb_info;
358 DD_LIST_FOREACH_SAFE(compat_cb_list, elem, elem_n, ccb_info) {
359 if (ccb_info->user_cb == callback) {
360 DD_LIST_REMOVE(compat_cb_list, ccb_info);
362 return STORAGE_ERROR_NONE;
365 return STORAGE_ERROR_OPERATION_FAILED;
368 /* Internal storage does not support registering changed callback */
369 DD_LIST_FOREACH(st_int_head, elem, st)
370 if (st->storage_id == storage_id)
371 return STORAGE_ERROR_NONE;
373 /* external storage */
374 info.id = storage_id;
375 info.state_cb = callback;
377 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_ID, &info);
379 _E("Failed to unregister callback : id(%d)", storage_id); //LCOV_EXCL_LINE
380 return STORAGE_ERROR_OPERATION_FAILED;
383 return STORAGE_ERROR_NONE;
386 API int storage_get_total_space(int storage_id, unsigned long long *bytes)
388 const struct storage_ops *st;
389 unsigned long long total;
394 return STORAGE_ERROR_NOT_SUPPORTED;
397 _E("Invalid parameger");
398 return STORAGE_ERROR_INVALID_PARAMETER;
401 /* internal storage */
402 DD_LIST_FOREACH(st_int_head, elem, st) {
403 if (st->storage_id != storage_id)
405 ret = st->get_space(&total, NULL);
409 /* external storage */
410 ret = storage_ext_get_space(storage_id, &total, NULL);
414 _E("Failed to get total memory : id(%d)", storage_id); //LCOV_EXCL_LINE
416 return STORAGE_ERROR_NOT_SUPPORTED;
417 return STORAGE_ERROR_OPERATION_FAILED;
421 return STORAGE_ERROR_NONE;
424 API int storage_get_available_space(int storage_id, unsigned long long *bytes)
426 const struct storage_ops *st;
427 unsigned long long avail;
432 return STORAGE_ERROR_NOT_SUPPORTED;
435 _E("Invalid parameger");
436 return STORAGE_ERROR_INVALID_PARAMETER;
439 /* internal storage */
440 DD_LIST_FOREACH(st_int_head, elem, st) {
441 if (st->storage_id != storage_id)
443 ret = st->get_space(NULL, &avail);
447 /* external storage */
448 ret = storage_ext_get_space(storage_id, NULL, &avail);
452 _E("Failed to get available memory : id(%d)", storage_id); //LCOV_EXCL_LINE
454 return STORAGE_ERROR_NOT_SUPPORTED;
455 return STORAGE_ERROR_OPERATION_FAILED;
459 return STORAGE_ERROR_NONE;
462 API int storage_set_changed_cb(storage_type_e type, storage_changed_cb callback, void *user_data)
465 struct storage_cb_info info;
467 if (type == STORAGE_TYPE_INTERNAL) {
468 _E("Internal storage is not supported");
469 return STORAGE_ERROR_NOT_SUPPORTED;
472 if (type != STORAGE_TYPE_EXTERNAL) {
473 _E("Invalid type (%d)", type);
474 return STORAGE_ERROR_INVALID_PARAMETER;
478 _E("Callback is NULL");
479 return STORAGE_ERROR_INVALID_PARAMETER;
482 /* external storage */
484 info.type_cb = callback;
485 info.user_data = user_data;
487 ret = storage_ext_register_cb(STORAGE_CALLBACK_TYPE, &info);
489 _E("Failed to register storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
490 return STORAGE_ERROR_OPERATION_FAILED;
493 return STORAGE_ERROR_NONE;
496 API int storage_unset_changed_cb(storage_type_e type, storage_changed_cb callback)
498 struct storage_cb_info info;
501 if (type == STORAGE_TYPE_INTERNAL) {
502 _E("Internal storage is not supported");
503 return STORAGE_ERROR_NOT_SUPPORTED;
506 if (type != STORAGE_TYPE_EXTERNAL) {
507 _E("Invalid type (%d)", type);
508 return STORAGE_ERROR_INVALID_PARAMETER;
512 _E("Callback is NULL");
513 return STORAGE_ERROR_INVALID_PARAMETER;
516 /* external storage */
518 info.type_cb = callback;
520 ret = storage_ext_unregister_cb(STORAGE_CALLBACK_TYPE, &info);
522 _E("Failed to unregister storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
523 return STORAGE_ERROR_OPERATION_FAILED;
526 return STORAGE_ERROR_NONE;