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_ACTIVATION_METHOD "ACTIVATION_METHOD"
33 #define TAG_DEACTIVATION_METHOD "DEACTIVATION_METHOD"
35 #define TAG_TIMEOUT "TIMEOUT"
36 #define TAG_EXTRA "EXTRA"
37 #define TAG_EXTRA_ARRAY "EXTRA_ARRAY"
38 #define TAG_EXTRA_ARRAY_VAL "EXTRA_ARRAY_VAL"
39 #define TAG_ALTERNATIVE_LOADER "ALTERNATIVE_LOADER"
40 #define TAG_HW_ACC "HW_ACC"
41 #define TAG_CPU_THRESHOLD_MAX "CPU_THRESHOLD_MAX"
42 #define TAG_CPU_THRESHOLD_MIN "CPU_THRESHOLD_MIN"
43 #define TAG_ON_BOOT "ON_BOOT"
44 #define TAG_HYDRA "HYDRA"
45 #define TAG_APP_CHECK "APP_CHECK"
49 #define VAL_METHOD_TIMEOUT "TIMEOUT"
50 #define VAL_METHOD_DEMAND "DEMAND"
51 #define VAL_METHOD_VISIBILITY "VISIBILITY"
52 #define VAL_METHOD_REQUEST "REQUEST"
53 #define VAL_METHOD_AVAILABLE_MEMORY "AVAILABLE_MEMORY"
54 #define VAL_METHOD_TTL "TTL"
55 #define VAL_METHOD_OUT_OF_MEMORY "OUT_OF_MEMORY"
57 static int __comp_name(gconstpointer a, gconstpointer b);
58 static void __free_info(gpointer data);
60 static loader_info_t *__create_loader_info()
64 info = malloc(sizeof(loader_info_t));
73 info->app_types = NULL;
75 info->alternative_loaders = NULL;
76 info->detection_method = METHOD_TIMEOUT | METHOD_VISIBILITY |
78 info->timeout_val = 5000;
79 info->extra = bundle_create();
80 info->cpu_threshold_max = DEFAULT_CPU_THRESHOLD_MAX;
81 info->cpu_threshold_min = DEFAULT_CPU_THRESHOLD_MIN;
83 info->app_exists = false;
84 info->activation_method = 0;
85 info->deactivation_method = 0;
86 info->ttl = 600; /* 10 minutes */
87 info->is_hydra = false;
88 info->app_check = true;
93 static void __parse_detection_method(loader_info_t *info, char *line)
98 token = strtok_r(line, " |\t\r\n", &savedptr);
99 info->detection_method = 0;
101 if (!strcmp(token, VAL_METHOD_TIMEOUT))
102 info->detection_method |= METHOD_TIMEOUT;
103 else if (!strcmp(token, VAL_METHOD_VISIBILITY))
104 info->detection_method |= METHOD_VISIBILITY;
105 else if (!strcmp(token, VAL_METHOD_DEMAND))
106 info->detection_method |= METHOD_DEMAND;
108 token = strtok_r(NULL, " |\t\r\n", &savedptr);
111 info->detection_method |= METHOD_INSTALL;
112 _D("detection_method:%d", info->detection_method);
115 static void __parse_activation_method(loader_info_t *info, char *line)
120 token = strtok_r(line, " |\t\r\n", &savedptr);
121 info->activation_method = 0;
123 if (!strcmp(token, VAL_METHOD_REQUEST))
124 info->activation_method |= METHOD_REQUEST;
125 else if (!strcmp(token, VAL_METHOD_AVAILABLE_MEMORY))
126 info->activation_method |= METHOD_AVAILABLE_MEMORY;
128 token = strtok_r(NULL, " |\t\r\n", &savedptr);
131 _D("activation_method:%d", info->activation_method);
134 static void __parse_deactivation_method(loader_info_t *info, char *line)
139 token = strtok_r(line, " |\t\r\n", &savedptr);
140 info->deactivation_method = 0;
142 if (!strcmp(token, VAL_METHOD_TTL))
143 info->deactivation_method |= METHOD_TTL;
144 else if (!strcmp(token, VAL_METHOD_OUT_OF_MEMORY))
145 info->deactivation_method |= METHOD_OUT_OF_MEMORY;
147 token = strtok_r(NULL, " |\t\r\n", &savedptr);
150 _D("deactivation_method:%d", info->deactivation_method);
153 static void __parse_app_types(loader_info_t *info, char *line)
158 token = strtok_r(line, " |\t\r\n", &savedptr);
160 info->app_types = g_list_append(info->app_types, strdup(token));
161 token = strtok_r(NULL, " |\t\r\n", &savedptr);
165 static void __parse_extra(loader_info_t *info, char *line)
171 if (info->extra == NULL)
174 sscanf(line, "%ms %ms %ms", &tok1, &tok2, &tok3);
176 if (!tok1 || !tok2 || !tok3)
179 if (strlen(tok2) == 0 || strlen(tok3) == 0)
182 bundle_add_str(info->extra, tok2, tok3);
193 static void __add_extra_array_from_list(bundle *b, const char *key, GList *list)
200 if (b == NULL || key == NULL || list == NULL)
203 len = g_list_length(list);
204 array = malloc(sizeof(const char *) * len);
209 for (i = 0; i < len; i++) {
210 array[i] = cur->data;
211 cur = g_list_next(cur);
214 bundle_add_str_array(b, key, array, len);
218 static void __flush_extra_array(bundle *b, char *key, GList *list)
221 __add_extra_array_from_list(b, key, list);
222 g_list_free_full(list, free);
228 static GList *__parse_file(GList *list, const char *path)
234 loader_info_t *cur_info = NULL;
236 GList *extra_array = NULL;
238 fp = fopen(path, "rt");
242 while (fgets(buf, sizeof(buf), fp) != NULL) {
245 sscanf(buf, "%ms %ms", &tok1, &tok2);
246 if (tok1 && strcasecmp(TAG_LOADER, tok1) == 0) {
247 if (cur_info != NULL) {
248 __flush_extra_array(cur_info->extra, key,
252 list = g_list_append(list, cur_info);
254 cur_info = __create_loader_info();
260 if (!tok1 || !tok2 || !cur_info)
262 if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
265 if (strcasecmp(TAG_NAME, tok1) == 0) {
266 cur_info->name = strdup(tok2);
267 } else if (strcasecmp(TAG_EXE, tok1) == 0) {
268 cur_info->exe = strdup(tok2);
269 } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) {
270 __parse_app_types(cur_info, &buf[strlen(tok1)]);
271 } else if (strcasecmp(TAG_DETECTION_METHOD, tok1) == 0) {
272 __parse_detection_method(cur_info, &buf[strlen(tok1)]);
273 } else if (strcasecmp(TAG_ACTIVATION_METHOD, tok1) == 0) {
274 __parse_activation_method(cur_info,
276 } else if (strcasecmp(TAG_DEACTIVATION_METHOD, tok1) == 0) {
277 __parse_deactivation_method(cur_info,
279 } else if (strcasecmp(TAG_TTL, tok1) == 0) {
280 cur_info->ttl = strtoul(tok2, NULL, 10);
281 } else if (strcasecmp(TAG_TIMEOUT, tok1) == 0) {
282 cur_info->timeout_val = atoi(tok2);
283 } else if (strcasecmp(TAG_EXTRA, tok1) == 0) {
284 __parse_extra(cur_info, buf);
285 } else if (strcasecmp(TAG_EXTRA_ARRAY, tok1) == 0) {
286 __flush_extra_array(cur_info->extra, key, extra_array);
289 } else if (strcasecmp(TAG_EXTRA_ARRAY_VAL, tok1) == 0) {
290 extra_array = g_list_append(extra_array, strdup(tok2));
291 } else if (strcasecmp(TAG_HW_ACC, tok1) == 0) {
292 cur_info->hw_acc = strdup(tok2);
293 } else if (strcasecmp(TAG_ALTERNATIVE_LOADER, tok1) == 0) {
294 cur_info->alternative_loaders =
295 g_list_append(cur_info->alternative_loaders,
297 } else if (strcasecmp(TAG_CPU_THRESHOLD_MAX, tok1) == 0) {
298 cur_info->cpu_threshold_max = atoi(tok2);
299 } else if (strcasecmp(TAG_CPU_THRESHOLD_MIN, tok1) == 0) {
300 cur_info->cpu_threshold_min = atoi(tok2);
301 } else if (strcasecmp(TAG_ON_BOOT, tok1) == 0) {
302 if (tok2 && strcasecmp(VAL_OFF, tok2) == 0)
303 cur_info->on_boot = false;
304 } else if (strcasecmp(TAG_HYDRA, tok1) == 0) {
305 if (strcasecmp(VAL_ON, tok2) == 0) {
306 cur_info->is_hydra = 1;
308 cur_info->is_hydra = 0;
310 } else if (strcasecmp(TAG_APP_CHECK, tok1) == 0) {
311 if (tok2 && strcasecmp(VAL_OFF, tok2) == 0)
312 cur_info->app_check = false;
316 if (cur_info != NULL) {
317 __flush_extra_array(cur_info->extra, key, extra_array);
318 list = g_list_append(list, cur_info);
331 GList *_loader_info_load_dir(const char *path)
334 struct dirent *entry = NULL;
339 dir_info = opendir(path);
340 if (dir_info == NULL)
343 while ((entry = readdir(dir_info)) != NULL) {
344 if (entry->d_name[0] == '.')
346 ext = strrchr(entry->d_name, '.');
347 if (ext && !strcmp(ext, ".loader")) {
348 snprintf(buf, sizeof(buf), "%s/%s", path, entry->d_name);
349 list = __parse_file(list, buf);
357 GList *_loader_info_load_file(GList *list, const char *path)
359 return __parse_file(list, path);
362 GList *_loader_info_unload(GList *list, const char *loader_name)
367 cur = g_list_find_custom(list, loader_name, __comp_name);
373 list = g_list_remove(list, info);
379 const char* _loader_info_find_loader_path_by_loader_name(GList *list, const char *loader_name)
384 cur = g_list_find_custom(list, loader_name, __comp_name);
393 loader_info_t* _loader_info_find_loader_by_loader_name(GList *list, const char *loader_name)
398 cur = g_list_find_custom(list, loader_name, __comp_name);
407 static void __free_info(gpointer data)
414 info = (loader_info_t *)data;
419 g_list_free_full(info->app_types, free);
422 bundle_free(info->extra);
423 if (info->alternative_loaders)
424 g_list_free_full(info->alternative_loaders, free);
429 void _loader_info_dispose(GList *info)
431 g_list_free_full(info, __free_info);
434 static int __comp_str(gconstpointer a, gconstpointer b)
441 static int __comp_app_type_with_hw_acc(gconstpointer a, gconstpointer b)
443 loader_info_t *info = (loader_info_t *)a;
445 if (info == NULL || info->app_types == NULL || b == NULL)
448 if (g_list_find_custom(info->app_types, b, __comp_str) &&
449 (info->hw_acc == NULL || !strcasecmp(VAL_ON, info->hw_acc)))
455 static int __comp_app_type_with_sw_acc(gconstpointer a, gconstpointer b)
457 loader_info_t *info = (loader_info_t *)a;
459 if (info == NULL || info->app_types == NULL || b == NULL)
462 if (g_list_find_custom(info->app_types, b, __comp_str) &&
463 (info->hw_acc == NULL || !strcasecmp(VAL_OFF, info->hw_acc)))
469 static int __comp_name(gconstpointer a, gconstpointer b)
471 loader_info_t *info = (loader_info_t *)a;
473 if (info == NULL || info->name == NULL || b == NULL)
476 return strcmp(info->name, b);
479 int _loader_info_find_type(GList *info, const char *app_type, bool hwacc)
484 cur = g_list_find_custom(info, app_type,
485 __comp_app_type_with_hw_acc);
487 cur = g_list_find_custom(info, app_type,
488 __comp_app_type_with_sw_acc);
494 loader_info_t *cur_info = (loader_info_t *)cur->data;
496 return cur_info->type;
499 int _loader_info_find_type_by_loader_name(GList *info, const char *loader_name)
503 cur = g_list_find_custom(info, loader_name, __comp_name);
507 loader_info_t *cur_info = (loader_info_t *)cur->data;
509 return cur_info->type;
512 static int *__make_type_array(GList *info, GList *loaders, int *len)
521 l = g_list_length(loaders);
526 t = malloc(sizeof(int) * l);
534 c = g_list_find_custom(info, cur->data, __comp_name);
537 i = (loader_info_t *)c->data;
542 cur = g_list_next(cur);
548 int *_loader_get_alternative_types(GList *info, int type, int *len)
558 i = (loader_info_t *)cur->data;
559 if (i->type == type) {
560 if (!i->alternative_loaders)
563 return __make_type_array(info, i->alternative_loaders,
566 cur = g_list_next(cur);
572 int _loader_info_foreach(GList *info, loader_info_foreach_cb callback,
578 if (!info || !callback)
583 i = (loader_info_t *)cur->data;
585 cur = g_list_next(cur);
591 bool _loader_info_exist_app_type(loader_info_t *info, const char *app_type)
595 list = g_list_find_custom(info->app_types, app_type, __comp_str);