apply FSL(Flora Software License)
[apps/core/preloaded/settings.git] / setting-common / src / setting-cfg.c
1 /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   *
4   * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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
19 #include <setting-cfg.h>
20 #include <setting-debug.h>
21 #include <stdio.h>
22 #include <Elementary.h>
23 #include <setting-common-general-func.h>
24
25 #include <vconf-keys.h>
26
27 #define CFG_FILE_DIR_PATH       "/opt/data/setting/"
28 #define CFG_FILE_PATH           CFG_FILE_DIR_PATH"setting.cfg"
29
30 JsonParser* parser;
31 JsonNode*   root; /* category_list */
32
33 int setting_cfg_file_write( JsonNode * node );
34
35 #define __create_an_item(item_name, icon_path, ug_args, defaultPos, is_resetable)\
36 {\
37         menu_item = json_node_new(JSON_NODE_OBJECT); \
38         object = json_object_new(); \
39         json_node_take_object(menu_item, object); \
40         json_object_set_string_member(object, "key_name", item_name); \
41         json_object_set_string_member(object, "icon_path", icon_path); \
42         json_object_set_string_member(object, "ug_args", ug_args); \
43         json_object_set_int_member(object, "pos", defaultPos); \
44         json_object_set_int_member(object, "click_times", 0); \
45         json_object_set_int_member(object, "is_resetable", is_resetable); \
46         json_array_add_element(menu, menu_item); \
47 }
48
49 #define __create_an_item_by_pkg(item_name, pkg_name, ug_args, defaultPos, is_resetable)\
50 {\
51         menu_item = json_node_new(JSON_NODE_OBJECT); \
52         object = json_object_new(); \
53         char* __temp_##item_name = get_icon_path(pkg_name); \
54         json_node_take_object(menu_item, object); \
55         json_object_set_string_member(object, "key_name", item_name); \
56         json_object_set_string_member(object, "icon_path", __temp_##item_name); \
57         json_object_set_string_member(object, "ug_args", ug_args); \
58         json_object_set_int_member(object, "pos", defaultPos); \
59         json_object_set_int_member(object, "click_times", 0); \
60         json_object_set_int_member(object, "is_resetable", is_resetable); \
61         json_array_add_element(menu, menu_item); \
62         free(__temp_##item_name); __temp_##item_name = NULL; \
63 }
64
65
66 #define __create_a_menu(menu_name)\
67 {\
68         category = json_node_new( JSON_NODE_OBJECT );\
69         object = json_object_new();\
70         json_node_take_object ( category, object );\
71         json_object_set_string_member( object, "name", menu_name );\
72         menu = json_array_new();\
73         json_object_set_array_member( object, "menu", menu );\
74         json_array_add_element( json_node_get_array( category_list ), category );\
75 }
76
77 void setting_cfg_print( void )
78 {
79         JsonNode * node = root;
80
81         JsonGenerator *generator = json_generator_new ();
82         g_object_set( generator, "pretty", TRUE, NULL );
83         json_generator_set_root ( generator, node );
84         gchar *data = json_generator_to_data ( generator, NULL );
85         SETTING_TRACE( "%s", (char *)data );
86
87         g_free(data);
88         g_object_unref(generator);
89 }
90
91 /* create config file from scratch */
92 int setting_cfg_create(void)
93 {
94         JsonNode *category_list, *category, *menu_item;
95         JsonArray *menu;
96         JsonObject *object;
97
98         int ret = 0;
99         int support_nfc = 0;
100
101         /* Category list */
102         category_list = json_node_new (JSON_NODE_ARRAY);
103         json_node_take_array ( category_list, json_array_new () );
104
105         /* Connectivity */
106         __create_a_menu(KeyStr_Connectivity);
107         __create_an_item(KeyStr_WiFi, IMG_WiFi, "wifi-efl-UG", Cfg_Item_Pos_Level0, Cfg_Item_Resetable);
108
109         ret = vconf_get_bool(VCONFKEY_NFC_FEATURE, &support_nfc);
110         if((ret != -1) && (support_nfc == 1))
111                 __create_an_item(KeyStr_NFC, IMG_NFC, "setting-nfc-efl", Cfg_Item_Pos_Level1, Cfg_Item_unResetable);
112
113         __create_an_item(KeyStr_Location, IMG_Location, "setting-location-efl", Cfg_Item_Pos_Level0, Cfg_Item_Resetable);
114         __create_an_item(KeyStr_DataRoaming, IMG_DataRoaming, NULL, Cfg_Item_Pos_Level1, Cfg_Item_Resetable);
115         if(!isEmulBin()) {
116                 __create_an_item(KeyStr_WiFiDirect, IMG_WiFiDirect, "setting-wifidirect-efl", Cfg_Item_Pos_Level1, Cfg_Item_Resetable);
117         }
118         __create_an_item(KeyStr_USBconnection, IMG_USBconnection, "setting-connectivity-efl|viewtype:usb", Cfg_Item_Pos_Level1, Cfg_Item_Resetable);
119
120         /* System */
121         __create_a_menu(KeyStr_System);
122         /* a new group..        */
123
124         __create_an_item(KeyStr_Sounds, IMG_Sounds, "setting-profile-efl", Cfg_Item_Pos_Level0, Cfg_Item_Resetable);
125         /* kinds of wallpaper version.. */
126         __create_an_item(KeyStr_Wallpaper, IMG_Wallpaper, "setting-display-efl|viewtype:wallpaper", Cfg_Item_Pos_Level0, Cfg_Item_Resetable);
127
128
129         __create_an_item(KeyStr_Display, IMG_Dispaly, "setting-display-efl|viewtype:main", Cfg_Item_Pos_Level0, Cfg_Item_Resetable);
130
131         /* a new group.. */
132         __create_an_item(KeyStr_DateTime, IMG_DateTime, "setting-time-efl", Cfg_Item_Pos_Level1, Cfg_Item_Resetable);
133
134         /* a new group.. */
135         __create_an_item(KeyStr_LanguageRegion, IMG_DisplayLanguage, "setting-phone-efl|viewtype:language", Cfg_Item_Pos_Level1, Cfg_Item_Resetable);
136         __create_an_item(KeyStr_KeyboradLanguage, IMG_KeyboradLanguage, "isfsetting-efl", Cfg_Item_Pos_Level1, Cfg_Item_Resetable);
137
138         __create_an_item(KeyStr_EventsNotifications, IMG_EventsNotifications, "setting-phone-efl|viewtype:notification", Cfg_Item_Pos_Level1, Cfg_Item_Resetable);
139         __create_an_item(KeyStr_Memory, IMG_Memory, "setting-memory-efl", Cfg_Item_Pos_Level1, Cfg_Item_Resetable);
140         __create_an_item(KeyStr_Reset, IMG_Reset, "setting-reset-efl", Cfg_Item_Pos_Level1, Cfg_Item_unResetable);
141         __create_an_item(KeyStr_AboutPhone, IMG_AboutPhone, "setting-about-efl", Cfg_Item_Pos_Level1, Cfg_Item_Resetable);
142
143         /* Applications */
144         __create_a_menu(KeyStr_Applications);
145
146         __create_an_item_by_pkg(KeyStr_Call, "org.tizen.phone", "setting-call-efl", Cfg_Item_Pos_Level0, Cfg_Item_unResetable);
147         __create_an_item_by_pkg(KeyStr_Messages, "org.tizen.message", "msg-setting-efl", Cfg_Item_Pos_Level0, Cfg_Item_unResetable);
148         __create_an_item_by_pkg(KeyStr_Contacts, "org.tizen.contacts", "contacts-settings-efl|request_type:71", Cfg_Item_Pos_Level1, Cfg_Item_unResetable);
149
150         __create_an_item_by_pkg(KeyStr_Calendar, "org.tizen.efl-calendar", "calendar-settings-efl", Cfg_Item_Pos_Level1, Cfg_Item_unResetable);
151
152         __create_an_item_by_pkg(KeyStr_Gallery, "org.tizen.gallery", "setting-gallery-efl", Cfg_Item_Pos_Level1, Cfg_Item_unResetable);
153
154
155         /* Downloaded App */
156         __create_a_menu(KeyStr_DownloadedAPPs);
157
158         __create_an_item(KeyStr_ManageApps, IMG_MANAGE_APPS, "setting-manage-applications-efl|viewtype:manage-applications", Cfg_Item_Pos_Level1,
159                             Cfg_Item_Resetable);
160
161
162         /* write to file */
163         ret = setting_cfg_file_write( category_list );
164
165         json_node_free( category_list );
166
167         return ret;
168 }
169
170
171 /* load file */
172 int setting_cfg_file_read( void )
173 {
174         parser = json_parser_new (); /* to be freed on exit */
175
176         /* file -> parser */
177         GError *error = NULL;
178         gboolean ret = json_parser_load_from_file( parser, CFG_FILE_PATH, &error );
179
180         if( FALSE == ret )
181         {
182                 SETTING_TRACE_ERROR("error->message:%s", (char*)(error->message));
183
184         /* The file is existing and can be accessed normally, but it was
185          * loaded failed as a json script, it means setting.cfg is
186          * damaged(not the normal formatting ), we need to remove
187          * the file and recreate in next running time*/
188                 SETTING_TRACE_ERROR("The file[%s] is existing and can be accessed "\
189                             "normally, but it was loaded failed as a json "\
190                             "script, it means setting.cfg is damaged (the "\
191                             "formatting ia abnormal), we need to remove the"\
192                             " file and recreate in next running time!",
193                             CFG_FILE_PATH);
194
195         SETTING_TRACE("Trying to removing the damaged file.");
196         if (remove(CFG_FILE_PATH) != 0)
197         {
198             SETTING_TRACE_ERROR("Error to remove the damaged file");
199             return FALSE;
200         }
201
202         if( FALSE == setting_cfg_create() )
203         {
204             SETTING_TRACE_ERROR("Error to create a new config file");
205             return FALSE;
206         }
207         /*if the failed is  caused by reading the file recursively invoking */
208         return setting_cfg_file_read();
209
210         }
211
212         /* parser -> root */
213         root = json_parser_get_root( parser ); /* to be freed on exit*/
214         return TRUE;
215 }
216
217 /**
218 * @brief dump JSON to file
219 */
220 int setting_cfg_file_write( JsonNode * node )
221 {
222         GError *error = NULL;
223         JsonGenerator *generator = json_generator_new ();
224         json_generator_set_root ( generator, node );
225         g_object_set( generator, "pretty", TRUE, NULL ); //write file in indent format
226         gboolean ret = json_generator_to_file( generator, CFG_FILE_PATH, &error );
227         g_object_unref(generator);
228
229         /* ***BEGIN***  DAC black screen SAMSUNG 2010/8/9 add
230          *add read permission
231          *chown -R inhouse:inhouse /home/inhouse/setting.cfg
232          */
233         if( FALSE == ret )
234         {
235                 SETTING_TRACE_ERROR("Error writing file %s!", CFG_FILE_PATH );
236                 return FALSE;
237         }
238         return TRUE;
239 }
240
241 /*   public functions  */
242 int setting_cfg_init( void )
243 {
244         g_type_init ();
245
246         struct stat st;
247         //int ret = -1;
248
249         if (access( CFG_FILE_DIR_PATH, R_OK|W_OK|F_OK ) !=0 )
250     {
251                 SETTING_TRACE_ERROR("dir [%s] not legal, need to check your file-system.[%s:%d]\n", CFG_FILE_DIR_PATH, __FILE__, __LINE__);
252         return Cfg_Error_Type_DirPermissionDenied;
253     }
254         if( stat(CFG_FILE_DIR_PATH, &st) != 0)/* to make more stable */
255         {
256                 /* if (0 != system("sudo mkdir /opt/data/setting/")); */
257                 /* if (EINA_TRUE != ecore_file_mkpath(CFG_FILE_DIR_PATH)); */
258                 if (EINA_TRUE != ecore_file_mkdir(CFG_FILE_DIR_PATH));
259                 {
260                         perror("mkdir");
261                         return Cfg_Error_Type_Mkdir_Failed;
262                 }
263         }
264
265         if( stat(CFG_FILE_PATH, &st) != 0)
266         {
267                 SETTING_TRACE_ERROR("Config file doesn't exist. Create it!");
268                 if(     FALSE == setting_cfg_create() )
269                 {
270                         /* perror("setting_cfg_create"); */
271                         return Cfg_Error_Type_CreateCfg_Failed;
272                 }
273                 stat(CFG_FILE_PATH, &st);
274         }
275         /* ***BEGIN***  error handle(caused by unstable file system) SAMSUNG 2010/9/10 add*/
276         else if (0 == st.st_size ||
277              0 != access( CFG_FILE_PATH, R_OK|F_OK ))
278         {
279                 SETTING_TRACE("the %s is 0 Byte, we need to recreate it.", CFG_FILE_PATH);
280                 /* delete the file */
281                 if (remove(CFG_FILE_PATH) != 0)
282                 {
283                         perror("remove");
284                         return Cfg_Error_Type_RemoveCfg_Failed;
285                 }
286                 if(     FALSE == setting_cfg_create() )
287                 {
288                         /* perror("setting_cfg_create"); */
289                         return Cfg_Error_Type_CreateCfg_Failed;
290                 }
291
292         }
293         /* ****END****  error handle(caused by unstable  file system) SAMSUNG 2010/9/10 add
294          * cfg file exists but invalid -> re-create
295          * load file into parser
296          */
297         if( FALSE == setting_cfg_file_read() )
298         {
299                 /* remove current setting file */
300                 if (remove(CFG_FILE_PATH) != 0)
301                 {
302                         /* perror("remove"); */
303                         return Cfg_Error_Type_RemoveCfg_Failed;
304                 }
305                 return Cfg_Error_Type_ReadCfg_Failed;
306         }
307
308         return Cfg_Error_Type_Sucess;
309 }
310
311 void setting_cfg_exit( void )
312 {
313         json_node_free(root);
314         g_object_unref (parser);
315 }
316
317 int setting_cfg_file_update( void )
318 {
319         if (access( CFG_FILE_PATH, W_OK|F_OK ) !=0 )
320         {
321                 return FALSE;
322         }
323         return setting_cfg_file_write( root );
324 }
325
326 int setting_cfg_get_category_length( void )
327 {
328         return json_array_get_length( json_node_get_array( root ) );
329 }
330
331 char* setting_cfg_get_category_name( int category_index )
332 {
333         JsonObject * category_obj = json_array_get_object_element( json_node_get_array( root ), category_index );
334         return (char*)json_object_get_string_member( category_obj, "name" );
335 }
336
337 int setting_cfg_get_menu_length( int category_index )
338 {
339         JsonObject * category_obj = json_array_get_object_element( json_node_get_array( root ), category_index );
340         JsonArray * menu = json_object_get_array_member( category_obj, "menu" );
341         return json_array_get_length( menu );
342 }
343
344 char * setting_cfg_get_keyname_idx( int category_index, int menu_index )
345 {
346         JsonObject * category_obj = json_array_get_object_element( json_node_get_array( root ), category_index );
347         JsonArray * menu = json_object_get_array_member( category_obj, "menu" );
348         JsonObject * menu_item = json_array_get_object_element( menu, menu_index );
349         return (char*)json_object_get_string_member( menu_item, "key_name" );
350 }
351
352 char * setting_cfg_get_string_field_idx( int category_index, int menu_index, char *field_name)
353 {
354         JsonObject * category_obj = json_array_get_object_element( json_node_get_array( root ), category_index );
355         JsonArray * menu = json_object_get_array_member( category_obj, "menu" );
356         JsonObject * menu_item = json_array_get_object_element( menu, menu_index );
357
358         char *data = (char *)json_object_get_string_member( menu_item, field_name );
359         if (!safeStrCmp(data, "(null)"))/* pass NULL to ug_args when create setting.cfg. */
360         {
361                 return NULL;
362         }
363         return data;
364 }
365
366 int setting_cfg_get_int_field_idx( int category_index, int menu_index , char *field_name)
367 {
368         JsonObject * category_obj = json_array_get_object_element( json_node_get_array( root ), category_index );
369         JsonArray * menu = json_object_get_array_member( category_obj, "menu" );
370         JsonObject * menu_item = json_array_get_object_element( menu, menu_index );
371         return json_object_get_int_member( menu_item, field_name );
372 }
373
374 char * setting_cfg_get_icon_path_idx( int category_index, int menu_index )
375 {
376         return setting_cfg_get_string_field_idx(category_index, menu_index, "icon_path");
377 }
378
379 char * setting_cfg_get_ug_args_idx( int category_index, int menu_index )
380 {
381         return setting_cfg_get_string_field_idx(category_index, menu_index, "ug_args");
382 }
383
384 char * setting_cfg_get_ugpath_idx( int category_index, int menu_index )
385 {
386         return setting_cfg_get_string_field_idx(category_index, menu_index, "ug_path");
387 }
388
389 char * setting_cfg_get_ugpath( char * keyname )
390 {
391         int i, j;
392         for( i = 0; i < setting_cfg_get_category_length(); i++ )
393         {
394                 for( j = 0; j < setting_cfg_get_menu_length( i ); j++ )
395                 {
396                         if( safeStrCmp( setting_cfg_get_keyname_idx( i, j ), keyname ) == 0 )
397                                 return setting_cfg_get_ugpath_idx( i, j );
398                 }
399         }
400         return NULL;
401 }
402
403 int setting_cfg_get_pos_idx( int category_index, int menu_index )
404 {
405         return setting_cfg_get_int_field_idx(category_index, menu_index, "pos");
406 }
407
408 int setting_cfg_get_pos( char * keyname )
409 {
410         int i, j;
411         for( i = 0; i < setting_cfg_get_category_length(); i++ )
412         {
413                 for( j = 0; j < setting_cfg_get_menu_length( i ); j++ )
414                 {
415                         if( safeStrCmp( setting_cfg_get_keyname_idx( i, j ), keyname ) == 0 )
416                                 return setting_cfg_get_pos_idx( i, j );
417                 }
418         }
419         return 0;
420 }
421
422 void setting_cfg_set_pos_idx( int category_index, int menu_index, int pos )
423 {
424         JsonObject * category_obj = json_array_get_object_element( json_node_get_array( root ), category_index );
425         JsonArray * menu = json_object_get_array_member( category_obj, "menu" );
426         JsonObject * menu_item = json_array_get_object_element( menu, menu_index );
427         json_object_remove_member( menu_item, "pos" );
428         json_object_set_int_member( menu_item, "pos", pos );
429 }
430
431 void setting_cfg_set_pos( char * keyname, int pos )
432 {
433         int i, j;
434         for( i = 0; i < setting_cfg_get_category_length(); i++ )
435         {
436                 for( j = 0; j < setting_cfg_get_menu_length( i ); j++ )
437                 {
438                         if( safeStrCmp( setting_cfg_get_keyname_idx( i, j ), keyname ) == 0 )
439                         {
440                                 setting_cfg_set_pos_idx( i, j, pos );
441                                 return ;
442                         }
443                 }
444         }
445
446 }
447
448 int setting_cfg_get_click_times_idx( int category_index, int menu_index )
449 {
450         return setting_cfg_get_int_field_idx(category_index, menu_index, "click_times");
451 }
452
453 int setting_cfg_get_click_times( char * keyname )
454 {
455         int i, j;
456         for( i = 0; i < setting_cfg_get_category_length(); i++ )
457         {
458                 for( j = 0; j < setting_cfg_get_menu_length( i ); j++ )
459                 {
460                         if( safeStrCmp( setting_cfg_get_keyname_idx( i, j ), keyname ) == 0 )
461                                 return setting_cfg_get_click_times_idx( i, j );
462                 }
463         }
464         return 0;
465 }
466
467 void setting_cfg_set_click_times_idx( int category_index, int menu_index, int click_times )
468 {
469         JsonObject * category_obj = json_array_get_object_element( json_node_get_array( root ), category_index );
470         JsonArray * menu = json_object_get_array_member( category_obj, "menu" );
471         JsonObject * menu_item = json_array_get_object_element( menu, menu_index );
472         json_object_remove_member( menu_item, "click_times" );
473         json_object_set_int_member( menu_item, "click_times", click_times );
474 }
475
476 void setting_cfg_set_click_times( char * keyname, int click_times )
477 {
478         int i, j;
479         for( i = 0; i < setting_cfg_get_category_length(); i++ )
480         {
481                 for( j = 0; j < setting_cfg_get_menu_length( i ); j++ )
482                 {
483                         if( safeStrCmp( setting_cfg_get_keyname_idx( i, j ), keyname ) == 0 )
484                         {
485                                 setting_cfg_set_click_times_idx( i, j, click_times );
486                                 return ;
487                         }
488                 }
489         }
490
491 }
492
493 int setting_cfg_get_resetable_flag_idx(int category_index, int menu_index)
494 {
495         return setting_cfg_get_int_field_idx(category_index, menu_index,
496                                              "is_resetable");
497 }
498
499 void setting_cfg_add_downloaded_app( char *keyname, char *icon_path, char *ug_args, int pos)
500 {
501         int i;
502         JsonNode *menu_item;
503         JsonObject *object;
504         JsonArray *menu;
505
506         for( i=0; i<setting_cfg_get_category_length(); i++ )
507         {
508                 if( safeStrCmp( setting_cfg_get_category_name(i), "Downloaded App" ) == 0 )
509                 {
510                         menu_item = json_node_new( JSON_NODE_OBJECT );
511                         object = json_object_new();
512                         json_node_take_object ( menu_item, object );
513                         json_object_set_string_member( object, "key_name", keyname );
514                         json_object_set_string_member( object, "icon_path", icon_path );
515                         json_object_set_string_member( object, "ug_args", ug_args );
516                         json_object_set_int_member( object, "pos", pos );
517
518                         object = json_array_get_object_element( json_node_get_array( root ), i );
519                         menu = json_object_get_array_member( object, "menu" );
520                         json_array_add_element( menu, menu_item );
521                 }
522         }
523 }
524
525 void setting_cfg_remove_downloaded_app( char * keyname )
526 {
527         int i, j;
528         JsonObject *object;
529         JsonArray *menu;
530
531         for( i = 0; i < setting_cfg_get_category_length(); i++ )
532         {
533                 if( safeStrCmp( setting_cfg_get_category_name(i), "Downloaded App" ) == 0 )
534                 {
535                         for( j = 0; j < setting_cfg_get_menu_length( i ); j++ )
536                         {
537                                 if( safeStrCmp( setting_cfg_get_keyname_idx( i, j ), keyname ) == 0 )
538                                 {
539                                         object = json_array_get_object_element( json_node_get_array( root ), i );
540                                         menu = json_object_get_array_member( object, "menu" );
541                                         json_array_remove_element( menu, j );
542                                         return ;
543                                 }
544                         }
545                 }
546         }
547 }
548
549 /*other relative function*/
550 char *get_ug_path_from_ug_args(void *data)
551 {
552         /*SETTING_TRACE_BEGIN;*/
553         char *p = (char *)data;
554         if (NULL == p || '\0' == p[0]) {
555                 return NULL;
556         }
557
558         char *q = strchr(p, '|');
559         char *path = NULL;
560
561         if (q) {                /* copy out the content before '|'; eg, ab|cd */
562                 path = (char *)calloc(1, q - p + 1);
563                 setting_retvm_if(!path, NULL, "calloc failed");
564                 safeCopyStr(path, p, q - p);
565                 /* redundant handle */
566                 path[q - p] = '\0';
567         } else {                /* copy out all the content. eg.abb */
568
569                 path = (char *)calloc(1, safeStrLen(p) + 1);
570                 setting_retvm_if(!path, NULL, "calloc failed");
571                 safeCopyStr(path, p, safeStrLen(p));
572         }
573         /*SETTING_TRACE("get the ug['%s']", path);*/
574         return path;
575 }
576
577 bundle *get_bundle_from_ug_args(void *data)
578 {
579         /*SETTING_TRACE_BEGIN;*/
580         char *p = (char *)data;
581         if (NULL == p || '\0' == p[0]) {
582                 return NULL;
583         }
584         char *m = NULL;
585         char *q = strchr(p, '|');
586         if (q) {                /* (key, value) pairs exit. eg: ug_args = "sevenemail-setting-efl|caller:setting; cmd:main option" */
587                 /* alloc data */
588                 bundle *b = bundle_create();
589                 if (!b)
590                         return NULL;
591                 int str_len = safeStrLen(p) + 1;
592                 char *v_key = (char *)calloc(1, str_len);
593                 if (!v_key) {
594                         bundle_free(b);
595                         return NULL;
596                 }
597
598                 char *v_value = (char *)calloc(1, str_len);
599                 if (!v_value) {
600                         bundle_free(b);
601                         FREE(v_key);
602                         return NULL;
603                 }
604
605                 p = ++q;
606                 while (p) {
607                         q = strchr(p, ';');
608                         if (q) {        /* not the last field */
609                                 m = strchr(p, ':');     /* ziduannei */
610                                 if (m) {
611                                         safeCopyStr(v_key, p, m - p);
612
613                                         ++m;
614                                         safeCopyStr(v_value, m, q - m);
615                                         SETTING_TRACE
616                                             ("To add ('%s', '%s') to bundle data",
617                                              v_key, v_value);
618                                         bundle_add(b, v_key, v_value);
619                                 } else {
620                                         SETTING_TRACE_ERROR
621                                             ("invalid key-value format!!\n");
622                                         break;  /* end the whole while */
623                                 }
624                         } else {        /* the last field */
625
626                                 m = strchr(p, ':');     /* ziduannei */
627                                 if (m) {
628                                         safeCopyStr(v_key, p, m - p);
629                                         ++m;
630                                         safeCopyStr(v_value, m, safeStrLen(m));
631                                         /*SETTING_TRACE
632                                             ("To add ('%s', '%s') to bundle data",
633                                              v_key, v_value);
634                                         */
635                                         bundle_add(b, v_key, v_value);
636                                 } else {
637                                         SETTING_TRACE_ERROR
638                                             ("invalid key-value format!!\n");
639                                 }
640                                 break;  /* end the whole while */
641                         }
642
643                         memset(v_key, '\0', str_len);
644                         memset(v_value, '\0', str_len);
645                         p = ++q;
646                 }
647
648                 FREE(v_key);
649                 FREE(v_value);
650                 return b;
651         } else {                /* eg: ug_args = "setting-browser-efl" */
652
653                 /*SETTING_TRACE("(key, value) pairs not exit");*/
654                 return NULL;
655         }
656
657 }
658