2 * Copyright (c) 2016 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.
24 #include "loader_info.h"
25 #include "launchpad_common.h"
27 #define TAG_LOADER "[LOADER]"
28 #define TAG_NAME "NAME"
30 #define TAG_APP_TYPE "APP_TYPE"
31 #define TAG_DETECTION_METHOD "DETECTION_METHOD"
32 #define TAG_TIMEOUT "TIMEOUT"
33 #define TAG_EXTRA "EXTRA"
34 #define TAG_EXTRA_ARRAY "EXTRA_ARRAY"
35 #define TAG_EXTRA_ARRAY_VAL "EXTRA_ARRAY_VAL"
36 #define TAG_ALTERNATIVE_LOADER "ALTERNATIVE_LOADER"
37 #define TAG_HW_ACC "HW_ACC"
40 #define VAL_METHOD_TIMEOUT "TIMEOUT"
41 #define VAL_METHOD_DEMAND "DEMAND"
42 #define VAL_METHOD_VISIBILITY "VISIBILITY"
45 static loader_info_t *__create_loader_info()
47 loader_info_t *info = malloc(sizeof(loader_info_t));
52 info->app_types = NULL;
54 info->alternative_loaders = NULL;
55 info->detection_method = METHOD_TIMEOUT | METHOD_VISIBILITY;
56 info->timeout_val = 5000;
57 info->extra = bundle_create();
62 static void __parse_detection_method(loader_info_t *info, char *line)
67 token = strtok_r(line, " |\t\r\n", &savedptr);
68 info->detection_method = 0;
70 if (!strcmp(token, VAL_METHOD_TIMEOUT))
71 info->detection_method |= METHOD_TIMEOUT;
72 else if (!strcmp(token, VAL_METHOD_VISIBILITY))
73 info->detection_method |= METHOD_VISIBILITY;
74 else if (!strcmp(token, VAL_METHOD_DEMAND))
75 info->detection_method |= METHOD_DEMAND;
77 token = strtok_r(NULL, " |\t\r\n", &savedptr);
80 _D("detection_method:%d", info->detection_method);
83 static void __parse_app_types(loader_info_t *info, char *line)
88 token = strtok_r(line, " |\t\r\n", &savedptr);
90 info->app_types = g_list_append(info->app_types, strdup(token));
91 token = strtok_r(NULL, " |\t\r\n", &savedptr);
95 static void __parse_extra(loader_info_t *info, char *line)
101 if (info->extra == NULL)
104 sscanf(line, "%ms %ms %ms", &tok1, &tok2, &tok3);
106 if (!tok1 || !tok2 || !tok3)
109 if (strlen(tok2) == 0 || strlen(tok3) == 0)
112 bundle_add_str(info->extra, tok2, tok3);
123 static void __add_extra_array_from_list(bundle *b, const char *key, GList *list)
130 if (b == NULL || key == NULL || list == NULL)
133 len = g_list_length(list);
134 array = malloc(sizeof(const char *) * len);
137 for (i = 0; i < len; i++) {
138 array[i] = cur->data;
139 cur = g_list_next(cur);
142 bundle_add_str_array(b, key, array, len);
146 static void __flush_extra_array(bundle *b, char *key, GList *list)
149 __add_extra_array_from_list(b, key, list);
150 g_list_free_full(list, free);
156 static GList *__parse_file(GList *list, const char *path)
162 loader_info_t *cur_info = NULL;
164 GList *extra_array = NULL;
166 fp = fopen(path, "rt");
170 while (fgets(buf, sizeof(buf), fp) != NULL) {
173 sscanf(buf, "%ms %ms", &tok1, &tok2);
174 if (tok1 && strcasecmp(TAG_LOADER, tok1) == 0) {
175 if (cur_info != NULL) {
176 __flush_extra_array(cur_info->extra, key,
180 list = g_list_append(list, cur_info);
182 cur_info = __create_loader_info();
188 if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
191 if (strcasecmp(TAG_NAME, tok1) == 0) {
192 cur_info->name = strdup(tok2);
193 } else if (strcasecmp(TAG_EXE, tok1) == 0) {
194 cur_info->exe = strdup(tok2);
195 } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) {
196 __parse_app_types(cur_info, &buf[strlen(tok1)]);
197 } else if (strcasecmp(TAG_DETECTION_METHOD, tok1) == 0) {
198 __parse_detection_method(cur_info, &buf[strlen(tok1)]);
199 } else if (strcasecmp(TAG_TIMEOUT, tok1) == 0) {
200 cur_info->timeout_val = atoi(tok2);
201 } else if (strcasecmp(TAG_EXTRA, tok1) == 0) {
202 __parse_extra(cur_info, buf);
203 } else if (strcasecmp(TAG_EXTRA_ARRAY, tok1) == 0) {
204 __flush_extra_array(cur_info->extra, key, extra_array);
207 } else if (strcasecmp(TAG_EXTRA_ARRAY_VAL, tok1) == 0) {
208 extra_array = g_list_append(extra_array, strdup(tok2));
209 } else if (strcasecmp(TAG_HW_ACC, tok1) == 0) {
210 cur_info->hw_acc = strdup(tok2);
211 } else if (strcasecmp(TAG_ALTERNATIVE_LOADER, tok1) == 0) {
212 cur_info->alternative_loaders =
213 g_list_append(cur_info->alternative_loaders,
218 if (cur_info != NULL) {
219 __flush_extra_array(cur_info->extra, key, extra_array);
220 list = g_list_append(list, cur_info);
233 GList *_loader_info_load(const char *path)
236 struct dirent *entry = NULL;
241 dir_info = opendir(path);
242 if (dir_info == NULL)
245 while ((entry = readdir(dir_info)) != NULL) {
246 if (entry->d_name[0] == '.')
248 ext = strrchr(entry->d_name, '.');
249 if (ext && !strcmp(ext, ".loader")) {
250 snprintf(buf, sizeof(buf), "%s/%s", path, entry->d_name);
251 list = __parse_file(list, buf);
259 static void __free_info(gpointer data)
266 info = (loader_info_t *)data;
271 g_list_free_full(info->app_types, free);
274 bundle_free(info->extra);
275 if (info->alternative_loaders)
276 g_list_free_full(info->alternative_loaders, free);
281 void _loader_info_dispose(GList *info)
283 g_list_free_full(info, __free_info);
286 static int __comp_str(gconstpointer a, gconstpointer b)
293 static int __comp_app_type_with_hw_acc(gconstpointer a, gconstpointer b)
295 loader_info_t *info = (loader_info_t *)a;
297 if (info == NULL || info->app_types == NULL || b == NULL)
300 if (g_list_find_custom(info->app_types, b, __comp_str) &&
301 (info->hw_acc == NULL || !strcasecmp(VAL_ON, info->hw_acc)))
307 static int __comp_app_type_with_sw_acc(gconstpointer a, gconstpointer b)
309 loader_info_t *info = (loader_info_t *)a;
311 if (info == NULL || info->app_types == NULL || b == NULL)
314 if (g_list_find_custom(info->app_types, b, __comp_str) &&
315 (info->hw_acc == NULL || !strcasecmp(VAL_OFF, info->hw_acc)))
321 static int __comp_name(gconstpointer a, gconstpointer b)
323 loader_info_t *info = (loader_info_t *)a;
325 if (info == NULL || info->name == NULL || b == NULL)
328 return strcmp(info->name, b);
331 int _loader_info_find_type(GList *info, const char *app_type, bool hwacc)
336 cur = g_list_find_custom(info, app_type,
337 __comp_app_type_with_hw_acc);
339 cur = g_list_find_custom(info, app_type,
340 __comp_app_type_with_sw_acc);
346 loader_info_t *cur_info = (loader_info_t *)cur->data;
348 return cur_info->type;
351 int _loader_info_find_type_by_loader_name(GList *info, const char *loader_name)
355 cur = g_list_find_custom(info, loader_name, __comp_name);
359 loader_info_t *cur_info = (loader_info_t *)cur->data;
361 return cur_info->type;
364 static int *__make_type_array(GList *info, GList *loaders, int *len)
373 l = g_list_length(loaders);
378 t = malloc(sizeof(int) * l);
386 c = g_list_find_custom(info, cur->data, __comp_name);
389 i = (loader_info_t *)c->data;
394 cur = g_list_next(cur);
400 int *_loader_get_alternative_types(GList *info, int type, int *len)
410 i = (loader_info_t *)cur->data;
411 if (i->type == type) {
412 if (!i->alternative_loaders)
415 return __make_type_array(info, i->alternative_loaders,
418 cur = g_list_next(cur);