2 * Copyright (c) 2015 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 <glib/gstdio.h>
24 #include <bundle_internal.h>
28 #include <system_info.h>
29 #include <pkgmgr-info.h>
30 #include <pkgmgrinfo_resource.h>
34 #include "aul_rsc_mgr.h"
40 #define LOG_TAG "AUL_RESOURCE_MANAGER"
42 #define WEIGHT_SCREEN_DPI 10000
43 #define WEIGHT_SCREEN_DPI_RANGE 10000
44 #define WEIGHT_SCREEN_BPP 1000
45 #define WEIGHT_SCREEN_WIDTH_RANGE 100
46 #define WEIGHT_SCREEN_LARGE 10
47 #define WEIGHT_PLATFORM_VERSION 1000000
48 #define WEIGHT_LANGUAGE 100000
50 #define THRESHOLD_TO_CLEAN 50 /* app_resource_manager_trim_cache */
52 #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
56 resource_data_t *data;
64 } resource_cache_context_t;
67 const char *bundle_attr_key;
68 unsigned int bundle_attr_value;
69 } resource_node_attr_t;
74 } resource_node_list_t;
79 NODE_ATTR_SCREEN_DPI_RANGE,
80 NODE_ATTR_SCREEN_WIDTH_RANGE,
81 NODE_ATTR_SCREEN_LARGE,
83 NODE_ATTR_PLATFORM_VER,
88 static resource_manager_t *resource_handle = NULL;
90 static resource_node_attr_t map[] = {
91 { RSC_NODE_ATTR_SCREEN_DPI, NODE_ATTR_SCREEN_DPI },
92 { RSC_NODE_ATTR_SCREEN_DPI_RANGE, NODE_ATTR_SCREEN_DPI_RANGE },
93 { RSC_NODE_ATTR_SCREEN_WIDTH_RANGE, NODE_ATTR_SCREEN_WIDTH_RANGE },
94 { RSC_NODE_ATTR_SCREEN_LARGE, NODE_ATTR_SCREEN_LARGE },
95 { RSC_NODE_ATTR_SCREEN_BPP, NODE_ATTR_SCREEN_BPP },
96 { RSC_NODE_ATTR_PLATFORM_VER, NODE_ATTR_PLATFORM_VER },
97 { RSC_NODE_ATTR_LANGUAGE, NODE_ATTR_LANGUAGE },
100 static GHashTable *attr_key = NULL;
101 static const char *res_path = NULL;
102 static char *cur_language = NULL;
103 static bool is_slice = FALSE;
105 static GHashTable *valid_path_list = NULL;
106 static GHashTable *supported_lang_list = NULL;
107 static GHashTable *id_list = NULL;
108 static GList *all_node_list = NULL;
109 static bundle *given_attr_list = NULL;
111 static gint __resource_manager_comp(gconstpointer a, gconstpointer b)
113 resource_group_t *rsc_group = (resource_group_t *) a;
115 return strcmp(rsc_group->type, b);
118 static gint __compare_path(gconstpointer a, gconstpointer b)
120 char tmp_path[MAX_PATH] = {0, };
121 resource_node_list_t *tmp_node_info= (resource_node_list_t *)a;
123 snprintf(tmp_path, MAX_PATH - 1, "%s%s", res_path, tmp_node_info->folder);
124 return strncmp(tmp_path, (char *)b, strlen(tmp_path));
128 static int __get_dpi(void)
133 bundle_get_str(given_attr_list, RSC_NODE_ATTR_SCREEN_DPI, &tmp);
135 LOGE("Failed to retrieve DPI");
140 system_info_get_platform_int("http://tizen.org/feature/screen.dpi", &dpi);
145 static int __get_screen_width(void)
147 int screen_width = 0;
151 bundle_get_str(given_attr_list, RSC_NODE_ATTR_SCREEN_WIDTH_RANGE, &tmp);
153 LOGE("Failed to retrieve screen width");
156 screen_width = atoi(tmp);
158 system_info_get_platform_int("http://tizen.org/feature/screen.width", &screen_width);
163 static bool __get_screen_large(void)
165 bool screen_large = true;
169 bundle_get_str(given_attr_list, RSC_NODE_ATTR_SCREEN_LARGE, &tmp);
171 LOGE("Failed to retrieve screen large");
172 screen_large = false;
174 screen_large = atoi(tmp);
176 if (system_info_get_platform_bool("http://tizen.org/feature/screen.size.large", &screen_large) != SYSTEM_INFO_ERROR_NONE) {
177 LOGE("Failed to get info of screen.size.large");
178 screen_large = false;
185 static int __get_screen_bpp(void)
191 bundle_get_str(given_attr_list, RSC_NODE_ATTR_SCREEN_BPP, &tmp);
193 LOGE("Failed to retrieve screen bpp");
196 screen_bpp = atoi(tmp);
198 system_info_get_platform_int("http://tizen.org/feature/screen.bpp", &screen_bpp);
203 static char *__get_platform_version(void)
205 char *version = NULL;
207 bundle_get_str(given_attr_list, RSC_NODE_ATTR_PLATFORM_VER, &version);
209 system_info_get_platform_string("http://tizen.org/feature/platform.version", &version);
214 static void __bundle_iterator_get_valid_nodes(const char *key, const int type,
215 const bundle_keyval_t *kv, void *data)
217 unsigned int node_attr;
218 bool *invalid = (bool *) data;
219 bool ret_bool = true;
221 char from[5] = { 0, };
226 static int screen_dpi = -1;
227 static int screen_width = -1;
228 static int screen_size_large = -1;
229 static char *version = NULL;
230 static int screen_bpp = -1;
235 bundle_keyval_get_basic_val((bundle_keyval_t *) kv, (void**) &val, &size);
237 node_attr = (guint) g_hash_table_lookup(attr_key, key);
238 if (node_attr <= NODE_ATTR_MIN || node_attr >= NODE_ATTR_MAX) {
239 LOGE("INVALID_PARAMETER(0x%08x), node_attr(%d)",
240 AUL_RESOURCE_ERROR_INVALID_PARAMETER, node_attr);
246 case NODE_ATTR_SCREEN_DPI:
247 if (screen_dpi == -1)
248 screen_dpi =__get_dpi();
249 if (screen_dpi != atoi(val))
253 case NODE_ATTR_SCREEN_DPI_RANGE:
254 sscanf(val, "%s %d %s %d", from, &min, to, &max);
255 if (screen_dpi == -1)
256 screen_dpi =__get_dpi();
257 if (!(min <= screen_dpi && screen_dpi <= max))
261 case NODE_ATTR_SCREEN_WIDTH_RANGE:
262 sscanf(val, "%s %d %s %d", from, &min, to, &max);
263 if (screen_width == -1)
264 screen_width = __get_screen_width();
265 if (!(min <= screen_width && screen_width <= max))
269 case NODE_ATTR_SCREEN_LARGE:
270 if (!(strcmp(val, "true")))
274 if (screen_size_large == -1) {
275 ret_bool = __get_screen_large();
277 screen_size_large = 1;
279 screen_size_large = 0;
281 if (((bool)screen_size_large) != t_val)
285 case NODE_ATTR_SCREEN_BPP:
286 if (screen_bpp == -1)
287 screen_bpp = __get_screen_bpp();
288 if (screen_bpp != atoi(val))
292 case NODE_ATTR_PLATFORM_VER:
294 version = __get_platform_version();
295 if (strcmp(version, val))
299 case NODE_ATTR_LANGUAGE:
300 if (cur_language == NULL)
301 cur_language = vconf_get_str(VCONFKEY_LANGSET);
303 if (strncmp(cur_language, val, strlen(val)))
309 static void __bundle_iterator_get_best_node(const char *key, const char *val,
312 unsigned int node_attr;
313 unsigned int *weight = (unsigned int *) data;
315 node_attr = (guint) g_hash_table_lookup(attr_key, key);
316 if (node_attr <= NODE_ATTR_MIN || node_attr >= NODE_ATTR_MAX) {
317 LOGE("INVALID_PARAMETER(0x%08x), node_attr(%d)",
318 AUL_RESOURCE_ERROR_INVALID_PARAMETER, node_attr);
323 case NODE_ATTR_SCREEN_DPI:
324 *weight += WEIGHT_SCREEN_DPI;
327 case NODE_ATTR_SCREEN_DPI_RANGE:
328 *weight += WEIGHT_SCREEN_DPI_RANGE;
331 case NODE_ATTR_SCREEN_WIDTH_RANGE:
332 *weight += WEIGHT_SCREEN_WIDTH_RANGE;
335 case NODE_ATTR_SCREEN_LARGE:
336 *weight += WEIGHT_SCREEN_LARGE;
339 case NODE_ATTR_SCREEN_BPP:
340 *weight += WEIGHT_SCREEN_BPP;
343 case NODE_ATTR_PLATFORM_VER:
344 *weight += WEIGHT_PLATFORM_VERSION;
347 case NODE_ATTR_LANGUAGE:
348 *weight += WEIGHT_LANGUAGE;
353 static const char *__get_cache(aul_resource_e type,
356 unsigned int total_len = 0;
359 resource_cache_context_t *resource_cache = NULL;
361 if (is_slice == TRUE)
365 LOGE("INVALID_PARAMETER(0x%08x), id",
366 AUL_RESOURCE_ERROR_INVALID_PARAMETER);
370 if (type < AUL_RESOURCE_TYPE_MIN || type > AUL_RESOURCE_TYPE_MAX) {
371 LOGE("INVALID_PARAMETER(0x%08x), type(%d)",
372 AUL_RESOURCE_ERROR_INVALID_PARAMETER, type);
376 case AUL_RESOURCE_TYPE_IMAGE:
377 rsc_type = RSC_GROUP_TYPE_IMAGE;
380 case AUL_RESOURCE_TYPE_LAYOUT:
381 rsc_type = RSC_GROUP_TYPE_LAYOUT;
384 case AUL_RESOURCE_TYPE_SOUND:
385 rsc_type = RSC_GROUP_TYPE_SOUND;
388 case AUL_RESOURCE_TYPE_BIN:
389 rsc_type = RSC_GROUP_TYPE_BIN;
394 if (resource_handle->cache == NULL) {
395 LOGE("INVALID_PARAMETER(0x%08x), hashtable",
396 AUL_RESOURCE_ERROR_INVALID_PARAMETER);
399 total_len = strlen(rsc_type) + strlen(id) + 2;
401 key = (char *) calloc(1, total_len);
403 LOGE("failed to create a resource_cache(0x%08x)",
404 AUL_RESOURCE_ERROR_OUT_OF_MEMORY);
405 free(resource_cache);
409 snprintf(key, total_len, "%s:%s", rsc_type, id);
410 LOGD("key : %s", key);
412 resource_cache = g_hash_table_lookup(resource_handle->cache, key);
414 if (resource_cache == NULL) {
415 LOGE("IO_ERROR(0x%08x), find list resource_cache",
416 AUL_RESOURCE_ERROR_IO_ERROR);
420 resource_cache->hit_cnt++;
423 return resource_cache->output;
426 static gint __cache_hit_compare(gconstpointer a, gconstpointer b)
428 const resource_cache_context_t *lhs = (const resource_cache_context_t *) a;
429 const resource_cache_context_t *rhs = (const resource_cache_context_t *) b;
431 return lhs->hit_cnt - rhs->hit_cnt;
434 static gboolean __cache_remove(gpointer key, gpointer value, gpointer user_data)
436 resource_cache_context_t *c = (resource_cache_context_t *) (value);
448 static void __trim_cache(void)
450 GList *values = g_hash_table_get_values(resource_handle->cache);
451 values = g_list_sort(values, __cache_hit_compare);
454 GList *iter_list = values;
455 while (iter_list != NULL) {
456 if (i >= (THRESHOLD_TO_CLEAN / 2))
459 resource_cache_context_t *c =
460 (resource_cache_context_t *) (iter_list->data);
462 iter_list = g_list_next(iter_list);
467 g_hash_table_foreach_remove(resource_handle->cache, __cache_remove, NULL);
471 static void __put_cache(aul_resource_e type, const char *id,
474 unsigned int total_len = 0;
477 resource_cache_context_t *resource_cache;
479 if (is_slice == TRUE)
482 /* To remove chache from the low frequency of use. */
484 LOGE("INVALID_PARAMETER(0x%08x), fname",
485 AUL_RESOURCE_ERROR_INVALID_PARAMETER);
490 LOGE("INVALID_PARAMETER(0x%08x), id",
491 AUL_RESOURCE_ERROR_INVALID_PARAMETER);
495 if (type < AUL_RESOURCE_TYPE_MIN || type > AUL_RESOURCE_TYPE_MAX) {
496 LOGE("INVALID_PARAMETER(0x%08x), type(%d)",
497 AUL_RESOURCE_ERROR_INVALID_PARAMETER, type);
501 case AUL_RESOURCE_TYPE_IMAGE:
502 rsc_type = RSC_GROUP_TYPE_IMAGE;
505 case AUL_RESOURCE_TYPE_LAYOUT:
506 rsc_type = RSC_GROUP_TYPE_LAYOUT;
509 case AUL_RESOURCE_TYPE_SOUND:
510 rsc_type = RSC_GROUP_TYPE_SOUND;
513 case AUL_RESOURCE_TYPE_BIN:
514 rsc_type = RSC_GROUP_TYPE_BIN;
519 if (g_hash_table_size(resource_handle->cache) > THRESHOLD_TO_CLEAN)
522 resource_cache = (resource_cache_context_t *) calloc(1,
523 sizeof(resource_cache_context_t));
524 if (resource_cache == NULL) {
525 LOGE("failed to create a resource_group(0x%08x)",
526 AUL_RESOURCE_ERROR_OUT_OF_MEMORY);
530 total_len = strlen(rsc_type) + strlen(id) + 2;
532 key = (char *) calloc(1, total_len);
534 LOGE("failed to create a resource_cache(0x%08x)",
535 AUL_RESOURCE_ERROR_OUT_OF_MEMORY);
536 free(resource_cache);
540 snprintf(key, total_len, "%s:%s", rsc_type, id);
541 LOGD("key : %s", key);
543 resource_cache->output = strdup(val);
544 resource_cache->hit_cnt = 0;
545 resource_cache->remove = false;
547 g_hash_table_insert(resource_handle->cache, key, resource_cache);
550 static resource_group_t *__find_group(resource_data_t *data,
553 resource_group_t *rsc_group = NULL;
557 LOGE("INVALID_PARAMETER(0x%08x), resource_data_t",
558 AUL_RESOURCE_ERROR_INVALID_PARAMETER);
562 if (type < AUL_RESOURCE_TYPE_MIN || type > AUL_RESOURCE_TYPE_MAX) {
563 LOGE("INVALID_PARAMETER(0x%08x), type(%d)",
564 AUL_RESOURCE_ERROR_INVALID_PARAMETER, type);
568 case AUL_RESOURCE_TYPE_IMAGE:
569 rsc_type = RSC_GROUP_TYPE_IMAGE;
572 case AUL_RESOURCE_TYPE_LAYOUT:
573 rsc_type = RSC_GROUP_TYPE_LAYOUT;
576 case AUL_RESOURCE_TYPE_SOUND:
577 rsc_type = RSC_GROUP_TYPE_SOUND;
580 case AUL_RESOURCE_TYPE_BIN:
581 rsc_type = RSC_GROUP_TYPE_BIN;
586 GList* found = g_list_find_custom(data->group_list, rsc_type,
587 __resource_manager_comp);
589 LOGE("IO_ERROR(0x%08x), find list resource_group %s",
590 AUL_RESOURCE_ERROR_IO_ERROR, rsc_type);
594 rsc_group = (resource_group_t *) (found->data);
599 static GList *__get_valid_nodes(resource_group_t *group,
603 GList *valid_list = NULL;
604 resource_node_t *valid_node = NULL;
605 resource_node_t *rsc_node = NULL;
607 if (group->node_list == NULL) {
608 LOGE("INVALID_PARAMETER(0x%08x), resource_group",
609 AUL_RESOURCE_ERROR_INVALID_PARAMETER);
613 list = g_list_first(group->node_list);
615 char path_buf[MAX_PATH] = { 0, };
617 bool invalid = false;
618 rsc_node = (resource_node_t *) list->data;
620 snprintf(path_buf, MAX_PATH - 1, "%s%s/%s", res_path,
621 rsc_node->folder, id);
622 if (access(path_buf, R_OK) == 0) {
623 bundle_foreach(rsc_node->attr, __bundle_iterator_get_valid_nodes,
627 valid_node = (resource_node_t *) list->data;
628 valid_list = g_list_append(valid_list, valid_node);
632 list = g_list_next(list);
638 static resource_node_t *__get_best_node(GList *nodes)
640 unsigned int weight_tmp = 0;
641 resource_node_t *best_node = NULL;
645 LOGE("INVALID_PARAMETER(0x%08x), resource_node lists",
646 AUL_RESOURCE_ERROR_INVALID_PARAMETER);
650 list = g_list_first(nodes);
652 while (list != NULL) {
653 unsigned int weight = 0;
654 resource_node_t *res_node = (resource_node_t *) (list->data);
656 bundle_iterate(res_node->attr, __bundle_iterator_get_best_node, &weight);
657 if (weight > weight_tmp) {
658 best_node = res_node;
661 list = g_list_next(list);
667 static int __open(resource_manager_t **handle)
669 int retval = AUL_RESOURCE_ERROR_NONE;
670 resource_manager_t *rsc_manager = NULL;
671 char buf[MAX_PATH] = { 0, };
673 rsc_manager = (resource_manager_t *) calloc(1, sizeof(resource_manager_t));
675 LOGE("failed to create a resource_manager(0x%08x)",
676 AUL_RESOURCE_ERROR_OUT_OF_MEMORY);
677 return AUL_RESOURCE_ERROR_OUT_OF_MEMORY;
680 snprintf(buf, MAX_PATH - 1, "%sres.xml", res_path);
681 retval = pkgmgrinfo_resource_open(buf, &(rsc_manager->data));
682 if (retval != PMINFO_R_OK) {
683 LOGE("IO_ERROR(0x%08x), failed to get db for resource manager",
684 AUL_RESOURCE_ERROR_IO_ERROR);
686 return AUL_RESOURCE_ERROR_IO_ERROR;
689 rsc_manager->cache = g_hash_table_new(g_str_hash, g_str_equal);
690 *handle = rsc_manager;
692 return AUL_RESOURCE_ERROR_NONE;
695 static void __invalidate_cache()
697 if (resource_handle != NULL) {
698 if (resource_handle->cache != NULL) {
702 g_hash_table_iter_init(&iter, resource_handle->cache);
703 while (g_hash_table_iter_next(&iter, &key, &value)) {
705 resource_cache_context_t *c = (resource_cache_context_t *) value;
709 g_hash_table_remove_all(resource_handle->cache);
718 static int __close(resource_manager_t *handle)
720 if (handle == NULL) {
721 LOGE("INVALID_PARAMETER(0x%08x), resource_manager",
722 AUL_RESOURCE_ERROR_INVALID_PARAMETER);
723 return AUL_RESOURCE_ERROR_INVALID_PARAMETER;
726 __invalidate_cache();
727 if (handle->cache != NULL) {
728 g_hash_table_destroy(handle->cache);
731 if (handle->data != NULL) {
732 pkgmgrinfo_resource_close(handle->data);
737 return AUL_RESOURCE_ERROR_NONE;
740 static void __vconf_cb(keynode_t *key, void *data)
742 __invalidate_cache();
745 static const char *_get_app_resource_path(const char *rsc_folder_path)
747 if (is_slice == FALSE)
748 return aul_get_app_resource_path();
750 if (rsc_folder_path == NULL)
753 return rsc_folder_path;
756 static void path_callback(char *path)
758 char orig_path[MAX_PATH] = {0, };
759 char *path_ptr = NULL;
761 GList *tmp_list = g_list_find_custom(all_node_list, path, __compare_path);
763 resource_node_list_t *tmp_node_info = NULL;
764 if (tmp_list == NULL)
765 g_hash_table_add(valid_path_list, strdup(path));
767 tmp_node_info = (resource_node_list_t *)tmp_list->data;
768 path_len = strlen(path);
769 if (path_len >= MAX_PATH) {
770 LOGE("path[%s] is too long", path);
773 strncpy(orig_path, path, path_len);
774 path_ptr = &orig_path[strlen(res_path) + strlen(tmp_node_info->folder)];
775 g_hash_table_insert(id_list, strdup(path_ptr), strdup(tmp_node_info->type));
779 static void __scan_dir(const char *path, void (*func)(char *))
781 struct dirent **items;
784 char abs_path[MAX_PATH] = {0, };
785 char cwd[MAX_PATH] = {0, };
788 if (chdir(path) < 0) {
789 LOGE("failed to chdir[%s]", path);
793 tmp = getcwd(cwd, MAX_PATH - 1);
795 LOGE("failed to get cwd");
798 nitems = scandir("./", &items, NULL, alphasort);
800 for (i = 0; i < nitems; i++) {
801 if (items[i]->d_name[0] == '.')
804 snprintf(abs_path, MAX_PATH - 1, "%s/%s", cwd, items[i]->d_name);
806 if (g_lstat(abs_path, &fstat) != 0) {
807 LOGE("failed to retrieve info[%s]", abs_path);
810 if ((fstat.st_mode & S_IFDIR) == S_IFDIR)
811 __scan_dir(abs_path, path_callback);
818 static aul_resource_e __get_resource_type(char *type)
823 if (strcmp(type, RSC_GROUP_TYPE_IMAGE) == 0)
824 return AUL_RESOURCE_TYPE_IMAGE;
825 else if(strcmp(type, RSC_GROUP_TYPE_LAYOUT) == 0)
826 return AUL_RESOURCE_TYPE_LAYOUT;
827 else if(strcmp(type, RSC_GROUP_TYPE_SOUND) == 0)
828 return AUL_RESOURCE_TYPE_SOUND;
829 else if(strcmp(type, RSC_GROUP_TYPE_BIN) == 0)
830 return AUL_RESOURCE_TYPE_BIN;
835 static int __set_valid_filelist(bundle *b)
837 if (b == NULL || supported_lang_list == NULL) {
838 LOGE("INVALID_PARAMETER(0x%08x), bundle",
839 AUL_RESOURCE_ERROR_INVALID_PARAMETER);
840 return AUL_RESOURCE_ERROR_INVALID_PARAMETER;
843 int retval = AUL_RESOURCE_ERROR_NONE;
845 GHashTableIter id_list_iter;
846 GHashTableIter lang_list_iter;
847 gpointer id_key, lang_key, id_type;
848 aul_resource_e rsc_type = AUL_RESOURCE_TYPE_MIN;
851 g_hash_table_iter_init(&id_list_iter, id_list);
853 while (g_hash_table_iter_next(&id_list_iter, &id_key, &id_type)) {
854 rsc_type = __get_resource_type((char *)id_type);
855 if (rsc_type == -1) {
856 LOGE("failed to get resource type[%s]", (char *)id_type);
857 return AUL_RESOURCE_ERROR_IO_ERROR;
860 g_hash_table_iter_init(&lang_list_iter, supported_lang_list);
861 while (g_hash_table_iter_next(&lang_list_iter, &lang_key, NULL)) {
862 cur_language = strdup(lang_key);
863 if (cur_language == NULL) {
864 LOGE("failed to strdup");
865 return AUL_RESOURCE_ERROR_OUT_OF_MEMORY;
868 retval = aul_resource_manager_get(rsc_type, id_key, &path);
869 if (retval == AUL_RESOURCE_ERROR_NONE)
870 g_hash_table_add(valid_path_list, path);
872 LOGE("failed to get value with given type[%d], key[%s]", rsc_type, id_key);
880 return AUL_RESOURCE_ERROR_NONE;
883 static int __make_list(void)
885 resource_group_t *tmp_group = NULL;
886 resource_node_t *tmp_node = NULL;
887 resource_node_list_t *tmp_node_struct = NULL;
888 char *group_type = NULL;
889 char folder[MAX_PATH] = {0 ,};
890 char *node_lang = NULL;
891 GList *group_list = NULL;
892 GList *node_list = NULL;
896 /* make node folder list */
897 group_list = resource_handle->data->group_list;
898 if (group_list == NULL)
899 return AUL_RESOURCE_ERROR_IO_ERROR;
901 while (group_list != NULL) {
902 tmp_group = (resource_group_t *)group_list->data;
903 if (tmp_group == NULL)
904 return AUL_RESOURCE_ERROR_IO_ERROR;
906 group_type = tmp_group->type;
907 node_list = tmp_group->node_list;
908 memset(folder, '\0', MAX_PATH);
909 snprintf(folder, MAX_PATH - 1, "%s/",tmp_group->folder);
911 /*make struct and put it into all node list*/
912 tmp_node_struct = (resource_node_list_t *)calloc(1, sizeof(resource_node_list_t));
913 if (tmp_node_struct == NULL) {
914 LOGE("calloc failed");
915 return AUL_RESOURCE_ERROR_OUT_OF_MEMORY;
918 tmp_node_struct->folder = strdup(folder);
919 tmp_node_struct->type = strdup(group_type);
920 all_node_list = g_list_append(all_node_list, tmp_node_struct);
922 while (node_list != NULL) {
923 tmp_node = (resource_node_t *)node_list->data;
924 if (tmp_node == NULL)
925 return AUL_RESOURCE_ERROR_IO_ERROR;
927 /*retrieve language value from each node*/
930 return AUL_RESOURCE_ERROR_IO_ERROR;
931 bundle_get_str(b, RSC_NODE_ATTR_LANGUAGE, &node_lang);
932 if (node_lang != NULL)
933 g_hash_table_add(supported_lang_list, strdup(node_lang));
935 memset(folder, '\0', MAX_PATH);
936 snprintf(folder, MAX_PATH - 1, "%s/",tmp_node->folder);
938 /*make struct and put it into all node list*/
939 tmp_node_struct = (resource_node_list_t *)calloc(1, sizeof(resource_node_list_t));
940 if (tmp_node_struct == NULL) {
941 LOGE("calloc failed");
942 return AUL_RESOURCE_ERROR_OUT_OF_MEMORY;
945 tmp_node_struct->folder = strdup(folder);
946 tmp_node_struct->type = strdup(group_type);
947 all_node_list = g_list_prepend(all_node_list, tmp_node_struct);
949 node_list = g_list_next(node_list);
951 group_list = g_list_next(group_list);
954 __scan_dir(res_path, path_callback);
956 /* add language which is not existed to find default resources */
957 g_hash_table_add(supported_lang_list, strdup("NoLang"));
958 return AUL_RESOURCE_ERROR_NONE;
961 static void __free_str(gpointer data)
966 char *char_data = (char *)data;
971 static int __init(const char *rsc_folder_path, bundle *b)
973 if (rsc_folder_path != NULL && b != NULL)
978 if (resource_handle != NULL)
979 return AUL_RESOURCE_ERROR_NONE;
981 int retval = AUL_RESOURCE_ERROR_NONE;
983 res_path = _get_app_resource_path(rsc_folder_path);
984 if (res_path == NULL) {
985 LOGE("IO_ERROR(0x%08x), failed to get resource path",
986 AUL_RESOURCE_ERROR_IO_ERROR);
987 return AUL_RESOURCE_ERROR_IO_ERROR;
990 retval = __open(&resource_handle);
991 if (retval != AUL_RESOURCE_ERROR_NONE) {
992 LOGE("IO_ERROR(0x%08x), failed to get resource_handle(%d)",
993 AUL_RESOURCE_ERROR_IO_ERROR, retval);
994 return AUL_RESOURCE_ERROR_IO_ERROR;
997 if (attr_key == NULL) {
998 attr_key = g_hash_table_new(g_str_hash, g_str_equal);
1000 if (attr_key == NULL)
1001 return AUL_RESOURCE_ERROR_OUT_OF_MEMORY;
1004 for (i = 0; i < ARRAY_SIZE(map); i++) {
1005 g_hash_table_insert(attr_key, (char *) map[i].bundle_attr_key,
1006 (gpointer) (map[i].bundle_attr_value));
1010 if (is_slice == FALSE) {
1011 int r = vconf_notify_key_changed(VCONFKEY_LANGSET, __vconf_cb, NULL);
1014 LOGE("IO_ERROR(0x%08x), failed to register vconf(%d)",
1015 AUL_RESOURCE_ERROR_IO_ERROR, r);
1016 return AUL_RESOURCE_ERROR_IO_ERROR;
1020 if (id_list == NULL)
1021 id_list = g_hash_table_new_full(g_str_hash, g_str_equal, __free_str, __free_str);
1023 if (supported_lang_list == NULL)
1024 supported_lang_list = g_hash_table_new_full(g_str_hash, g_str_equal, __free_str, NULL);
1026 if (valid_path_list == NULL)
1027 valid_path_list = g_hash_table_new_full(g_str_hash, g_str_equal, __free_str, NULL);
1029 retval = __make_list();
1031 LOGE("Failed to initialize filelist");
1032 return AUL_RESOURCE_ERROR_IO_ERROR;
1035 retval = __set_valid_filelist(b);
1037 LOGE("Failed to get valid filelist");
1038 return AUL_RESOURCE_ERROR_IO_ERROR;
1043 return AUL_RESOURCE_ERROR_NONE;
1046 SLPAPI int aul_resource_manager_init(void)
1048 return __init(NULL, NULL);
1051 SLPAPI int aul_resource_manager_init_slice(const char *rsc_folder_path, bundle *b)
1053 if (rsc_folder_path == NULL || b == NULL)
1054 return AUL_RESOURCE_ERROR_INVALID_PARAMETER;
1056 return __init(rsc_folder_path, b);
1060 SLPAPI int aul_resource_manager_get_path_list(GHashTable **list)
1062 if (is_slice == FALSE)
1063 return AUL_RESOURCE_ERROR_IO_ERROR;
1065 if (valid_path_list != NULL)
1066 *list = valid_path_list;
1068 return AUL_RESOURCE_ERROR_IO_ERROR;
1070 return AUL_RESOURCE_ERROR_NONE;
1073 SLPAPI int aul_resource_manager_get(aul_resource_e type, const char *id, char **path)
1075 int retval = AUL_RESOURCE_ERROR_NONE;
1076 char *put_fname = NULL;
1077 const char *cached_path = NULL;
1079 resource_group_t *resource_group = NULL;
1080 resource_node_t *resource_node = NULL;
1085 LOGE("INVALID_PARAMETER(0x%08x), resource_data_t",
1086 AUL_RESOURCE_ERROR_INVALID_PARAMETER);
1087 return AUL_RESOURCE_ERROR_INVALID_PARAMETER;
1090 if (type < AUL_RESOURCE_TYPE_MIN || type > AUL_RESOURCE_TYPE_MAX) {
1091 LOGE("INVALID_PARAMETER(0x%08x), type(%d)",
1092 AUL_RESOURCE_ERROR_INVALID_PARAMETER, type);
1093 return AUL_RESOURCE_ERROR_INVALID_PARAMETER;
1096 if (is_slice == FALSE) {
1097 if (resource_handle == NULL) {
1098 retval = aul_resource_manager_init();
1099 if (retval != AUL_RESOURCE_ERROR_NONE)
1103 /* To get fname from cache */
1104 cached_path = __get_cache(type, id);
1105 if (cached_path != NULL) {
1106 *path = strdup(cached_path);
1107 return AUL_RESOURCE_ERROR_NONE;
1111 if (resource_handle == NULL)
1112 return AUL_RESOURCE_ERROR_IO_ERROR;
1114 resource_group = __find_group(resource_handle->data, type);
1115 if (resource_group == NULL) {
1116 LOGE("IO_ERROR(0x%08x), failed to get resource_group",
1117 AUL_RESOURCE_ERROR_IO_ERROR);
1118 retval = AUL_RESOURCE_ERROR_IO_ERROR;
1122 list = __get_valid_nodes(resource_group, id);
1124 retval = AUL_RESOURCE_ERROR_IO_ERROR;
1128 resource_node = __get_best_node(list);
1129 if (resource_node == NULL) {
1130 retval = AUL_RESOURCE_ERROR_IO_ERROR;
1133 unsigned int total_len = strlen(res_path)
1134 + strlen(resource_node->folder) + strlen(id) + 3;
1135 put_fname = (char *) calloc(1, total_len);
1139 return AUL_RESOURCE_ERROR_OUT_OF_MEMORY;
1141 snprintf(put_fname, total_len, "%s%s/%s", res_path,
1142 resource_node->folder, id);
1143 *path = strdup(put_fname);
1146 __put_cache(type, id, put_fname);
1153 if (put_fname == NULL && resource_group != NULL) {
1154 char path_buf[MAX_PATH] = { 0, };
1155 char group_path_buf[MAX_PATH] = { 0, };
1157 snprintf(path_buf, MAX_PATH - 1, "%s%s/%s", res_path,
1158 resource_group->folder, id);
1159 snprintf(group_path_buf, MAX_PATH - 1, "%s/%s", resource_group->folder, id);
1161 list = g_list_first(resource_group->node_list);
1163 resource_node = (resource_node_t *) list->data;
1164 if (strncmp(group_path_buf, resource_node->folder, strlen(resource_node->folder)) == 0) {
1166 return AUL_RESOURCE_ERROR_IO_ERROR;
1168 list = g_list_next(list);
1171 if (access(path_buf, R_OK) == 0) {
1172 __put_cache(type, id, path_buf);
1173 *path = strdup(path_buf);
1174 retval = AUL_RESOURCE_ERROR_NONE;
1178 if (put_fname != NULL)
1184 static void __free_node_folder_list(gpointer data)
1186 resource_node_list_t *node_data = (resource_node_list_t *)data;
1187 if (node_data == NULL)
1190 if (node_data->folder != NULL) {
1191 free(node_data->folder);
1192 node_data->folder = NULL;
1195 if (node_data->type != NULL) {
1196 free(node_data->type);
1197 node_data->type = NULL;
1203 SLPAPI int aul_resource_manager_release(void)
1205 if (resource_handle != NULL) {
1206 __close(resource_handle);
1207 resource_handle = NULL;
1210 if (attr_key != NULL) {
1211 g_hash_table_destroy(attr_key);
1217 cur_language = NULL;
1220 if (is_slice == FALSE)
1221 vconf_ignore_key_changed(VCONFKEY_LANGSET, __vconf_cb);
1223 if (valid_path_list != NULL) {
1224 g_hash_table_destroy(valid_path_list);
1225 valid_path_list = NULL;
1228 if (supported_lang_list != NULL) {
1229 g_hash_table_destroy(supported_lang_list);
1230 supported_lang_list = NULL;
1233 if (id_list != NULL) {
1234 g_hash_table_destroy(id_list);
1238 if (all_node_list != NULL) {
1239 g_list_free_full(all_node_list, __free_node_folder_list);
1240 all_node_list = NULL;
1243 return AUL_RESOURCE_ERROR_NONE;