Tizen 2.4.0 rev3 SDK Public Release
[apps/home/settings.git] / src / setting.c
1 /*
2  * setting
3  * * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
4  *
5  * Contact: MyoungJune Park <mj2004.park@samsung.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20 #include <setting.h>
21 #include <app.h>
22 #include <sound_manager.h>
23
24 #include <appcore-common.h>
25 #include <Ecore_X.h>
26 #include <sensor.h>
27 #include <aul.h>
28 #include <app_preference.h>
29
30 #include "setting-helper.h"
31 #include "setting-main.h"
32 #include <setting-cfg.h>
33
34 #include <setting-common-search.h>
35 #include <elm_object.h>
36 #include <appsvc.h>
37 /*#include <nfc.h> */
38 #include <signal.h>
39 #include <system_settings.h>
40 #include <bundle_internal.h>
41
42 /*#define SUPPORT_UG_MESSAGE */
43
44
45 #define SETTING_SOUND_VOL_MAX 15
46 #define SETTING_DEFAULT_RINGTONE_VOL_INT        11
47 #define SETTING_DEFAULT_NOTI_VOL_INT            11
48 #define SETTING_DEFAULT_MEDIA_VOL_INT           9
49
50 int g_geometry_x, g_geometry_y, g_geometry_w, g_geometry_h;
51 extern int aul_listen_app_dead_signal(int (*func)(int signal, void *data), void *data);
52
53 /* This API is defined in <app_service_private.h>. But, cannot include and it is not a managed API.
54         The way to resolve : 1. Add extern.
55                                                  2. Use bundle pointer originally
56         At first, choose No.1 */
57 extern int app_control_create_request(bundle *data, app_control_h *service);
58
59 setting_main_appdata *g_main_ad;
60
61 void termination_handler(int signum)
62 {
63         SETTING_TRACE_BEGIN;
64         /* do something for signal handling */
65         /*SETTING_TRACE_DEBUG(">>>>>>>>>>>>>>>>> SIGTERM >>>>>>>>>>>>>>> SETTING "); */
66
67         elm_exit();
68 }
69
70
71 #if LOW_BATTERY_DO_NOTHING
72
73 /*  in case of low battery, don't terminate itself.*/
74
75 /**
76 * The event process when battery becomes low.
77 */
78 static void setting_main_low_battery_cb(app_event_info_h event_info, void *data)
79 {
80         SETTING_TRACE_BEGIN;
81         retm_if(!data, "Invalid argument: data is NULL");
82         setting_main_appdata *ad = data;
83
84         if (ad->ug) {
85                 ug_send_event(UG_EVENT_LOW_BATTERY);
86         }
87 }
88 #endif
89
90
91 #if SUPPORT_APP_ROATION
92 static void _rot_changed_cb(void *data, Evas_Object *obj, void *event_info)
93 {
94         SETTING_TRACE_BEGIN;
95         setting_main_appdata *ad = (setting_main_appdata *)data;
96         if (ad == NULL || ad->win_main == NULL) {
97                 return;
98         }
99         int change_ang = elm_win_rotation_get(ad->win_main);
100         SETTING_TRACE_DEBUG("....change_ang:%d", change_ang);
101         SETTING_TRACE_DEBUG("current_rotation:%d", ad->current_rotation);
102         /*Send the rotation event to UGs.. */
103         enum ug_event event = UG_EVENT_ROTATE_PORTRAIT;
104         switch (change_ang) {
105                 case APP_DEVICE_ORIENTATION_0:
106                         event = UG_EVENT_ROTATE_PORTRAIT;
107                         break;
108                 case APP_DEVICE_ORIENTATION_180:
109                         event = UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN;
110                         break;
111                 case APP_DEVICE_ORIENTATION_270:
112                         event = UG_EVENT_ROTATE_LANDSCAPE;
113                         break;
114                 case APP_DEVICE_ORIENTATION_90:
115                         event = UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN;
116                         break;
117                 default:
118                         return;
119         }
120         SETTING_TRACE_DEBUG("diff:%d", elm_win_rotation_get(ad->win_main) - ad->current_rotation);
121
122         if (change_ang != ad->current_rotation) {
123                 int diff = change_ang - ad->current_rotation;
124                 if (diff < 0) {
125                         diff = -diff;
126                 }
127                 /**
128                 * @todo if app didn't launch UG, is the call required to invoke?
129                 */
130                 ug_send_event(event);
131                 if (diff == 180) {
132                         /* do nothing */
133                 }
134                 ad->current_rotation = change_ang;
135         }
136 }
137 #endif
138
139
140 /**
141 * The event process when region is changes.
142 */
143 static void setting_main_region_changed_cb(app_event_info_h event_info, void *data)
144 {
145         retm_if(!data, "Invalid argument: data is NULL");
146         setting_main_appdata *ad = data;
147
148         if (ad->ug) {
149                 ug_send_event(UG_EVENT_REGION_CHANGE);
150         }
151 }
152
153 /**
154 * The event process when win object is destroyed
155 */
156 static void setting_main_del_win(void *data, Evas_Object *obj, void *event)
157 {
158         elm_exit();
159 }
160
161 /**
162 * To create a win object, the win is shared between the App and all its UGs
163 */
164 static Evas_Object *setting_main_create_win(const char *name)
165 {
166         SETTING_TRACE_BEGIN;
167         LAUNCH_SETTING_IN();
168         Evas_Object *eo;
169         int w, h;
170
171         eo = (Evas_Object *) elm_win_add(NULL, name, ELM_WIN_BASIC);
172         if (!eo)
173                 eo = elm_win_util_standard_add(name, name);
174         else {
175                 /* elm_win_util_standard_add creates bg inside */
176                 Evas_Object *bg;
177
178                 bg = elm_bg_add(eo);
179
180                 if (!bg) {
181                         evas_object_del(eo);
182                         return NULL;
183                 }
184                 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
185                 elm_win_resize_object_add(eo, bg);
186                 evas_object_show(bg);
187         }
188         if (eo) {
189                 elm_win_title_set(eo, name);
190                 evas_object_smart_callback_add(eo, "delete,request", setting_main_del_win, NULL);
191                 ecore_x_window_size_get(ecore_x_window_root_first_get(),
192                                         &w, &h);
193                 evas_object_resize(eo, w, h);
194         }
195         LAUNCH_SETTING_OUT();
196         return eo;
197 }
198
199
200 /**
201 * exceptional process, reset the env vars by Setting vconf VCONFKEY_LANGSET
202 */
203 static void setting_main_lang_changed_cb(app_event_info_h event_info, void *data)
204 {
205         SETTING_TRACE_BEGIN;
206         retm_if(!data, "Invalid argument: data is NULL");
207         /*FIX the crash when switch from Portrait mode to landscape mode, */
208         /*It is so strange the data is no longer correct */
209         /*and ....why it is invoked */
210         /*setting_main_appdata *ad = data; */
211         setting_main_appdata *ad = g_main_ad;
212
213         char *tab_str[] = {
214                 Keystr_Connection,
215                 KeyStr_Device,
216                 KeyStr_MotionControl,
217                 "IDS_ST_BODY_GENERAL",
218                 KeyStr_DownloadedAPPs
219         };
220         int i = 0;
221
222         elm_object_item_part_text_set(ad->navibar_main_it, "elm.text.title", _("IDS_ST_OPT_SETTINGS"));
223         setting_navi_items_update(ad->navibar_main);
224
225         if (ad->isInUGMode && ad->ug) {
226                 Evas_Object *layout = (Evas_Object *)ug_get_layout(ad->ug);
227                 if (layout) {
228                         Evas_Object *navi_bar = NULL;
229                         navi_bar = elm_object_part_content_get(layout, "elm.swallow.content");
230                         setting_navi_items_update(navi_bar);
231                 }
232                 ug_send_event(UG_EVENT_LANG_CHANGE);
233         }
234
235 }
236
237 /**
238 * the event process when other VCONFS changes
239 */
240 static void setting_other_vconf_change_cb(keynode_t *key, void *data)
241 {
242         setting_main_appdata *ad = data;
243         retm_if(!data, "Invalid argument: data is NULL");
244
245         Setting_GenGroupItem_Data *item_to_update = NULL;
246         char *vconf_name = vconf_keynode_get_name(key);
247         SETTING_TRACE("the value of [ %s ] just changed", vconf_name);
248         int i = 0;
249
250         if (!safeStrCmp(vconf_name, VCONFKEY_SETAPPL_DEVELOPER_OPTION_STATE)) {
251 #ifndef BINARY_RELEASE_TYPE_ENG
252                 /*for user binary: need to check develop_option_state vconf value*/
253                 if (ad->sub_view[SETTING_TAB_VIEW_GENERAL]) {
254                         SETTING_TRACE("redraw Gernel Tab");
255                         evas_object_del(ad->sub_view[SETTING_TAB_VIEW_GENERAL]);
256                         ad->sub_view[SETTING_TAB_VIEW_GENERAL] = NULL;
257                 }
258                 setting_search_genlist_update(ad);
259 #endif
260         }
261 }
262
263 /**
264 * the event process when int VCONFS changes
265 * @todo code clean - it has big if-else structure
266 */
267 static void setting_int_vconf_change_cb(keynode_t *key, void *data)
268 {
269         setting_main_appdata *ad = data;
270         retm_if(!data, "Invalid argument: data is NULL");
271
272         int status = vconf_keynode_get_int(key);
273         char *vconf_name = vconf_keynode_get_name(key);
274         SETTING_TRACE("Enter %s(%s=%d)", __FUNCTION__, vconf_name, status);
275         return;
276 }
277
278
279 /**
280 * the event process when string VCONFS changes
281 */
282 static void setting_string_vconf_change_cb(keynode_t *key, void *data)
283 {
284         setting_main_appdata *ad = data;
285         retm_if(!data, "Invalid argument: data is NULL");
286
287         char *value = vconf_keynode_get_str(key);
288         char *vconf_name = vconf_keynode_get_name(key);
289         SETTING_TRACE("Enter %s(%s=%s)", __FUNCTION__, vconf_name, value);
290
291 }
292
293 /**
294 * The function is called to create Setting view widgets
295 */
296 static bool setting_main_app_create(void *data)
297 {
298         SETTING_TRACE_BEGIN;
299         LAUNCH_SETTING_IN();
300         SETTING_TRACE_DEBUG("[TIME] 3. it taked %d msec from main to setting_main_app_create ", appcore_measure_time());
301         appcore_measure_start();
302
303         /*elm_config_accel_preference_set("3d"); */
304         ug_create_cb(setting_ug_create_cb, NULL);
305
306 #if SUPPORT_DRI
307         setenv("EVAS_DRI_SWAPBUF", "1", 1);
308 #endif
309
310         setting_main_appdata *ad = data;
311         /* regitering sigterm */
312         if (signal(SIGTERM, termination_handler) == SIG_IGN) {
313                 signal(SIGTERM, SIG_IGN);
314         }
315
316         app_event_handler_h handlers[5] = {NULL, };
317 #if LOW_BATTERY_DO_NOTHING
318         ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, setting_main_low_battery_cb, ad);
319 #endif
320         ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, setting_main_lang_changed_cb, ad);
321         ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, setting_main_region_changed_cb, ad);
322         ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, NULL, NULL);    /* no callback */
323
324
325 #if 0
326         app_control_h svc;
327         app_control_create(&svc);
328         /*app_control_create_request(b, &svc); */
329         /*ad->is_searchmode = setting_main_sfinder_handler(svc, ad, NULL); */
330         app_control_destroy(svc);
331         svc = NULL;
332 #endif
333         /*--------------------------------------------------------------------------------------------- */
334
335         elm_app_base_scale_set(2.4);
336
337         /* create window */
338         ad->win_main = setting_main_create_win(SETTING_PACKAGE);
339         setting_retvm_if(ad->win_main == NULL, SETTING_RETURN_FAIL, "window is null");
340         UG_INIT_EFL(ad->win_main, UG_OPT_INDICATOR_ENABLE);
341         ad->evas = evas_object_evas_get(ad->win_main);
342         ad->current_rotation = elm_win_rotation_get(ad->win_main);
343         SETTING_TRACE_DEBUG("ad->current_rotation:%d", ad->current_rotation);
344         if (elm_win_wm_rotation_supported_get(ad->win_main)) {
345                 int rots[4] = { 0, 90, 180, 270 };  /* rotation value that app may want */
346                 elm_win_wm_rotation_available_rotations_set(ad->win_main, rots, 4);
347         }
348         evas_object_smart_callback_add(ad->win_main, "wm,rotation,changed", _rot_changed_cb, ad);
349
350         /* load config file */
351         int cfg_operation_ret = setting_cfg_init();
352         /*PLUGIN_INIT(ad); */
353         /*if ( ! ad->is_searchmode) */
354         /*{ */
355         elm_theme_extension_add(NULL, SETTING_THEME_EDJ_NAME);
356         elm_theme_extension_add(NULL, SETTING_NEWUX_EDJ_NAME);
357         elm_theme_extension_add(NULL, SETTING_GENLIST_EDJ_NAME);
358         elm_theme_extension_add(NULL, SETTING_NEW_GENLIST_EDJ_NAME);
359         elm_theme_extension_add(NULL, SETTING_SLIDER_EDJ_NAME);
360         /*} */
361
362         elm_win_indicator_mode_set(ad->win_main, ELM_WIN_INDICATOR_SHOW);
363         elm_win_indicator_opacity_set(ad->win_main, ELM_WIN_INDICATOR_OPAQUE);
364
365         evas_object_show(ad->win_main);
366
367         g_main_ad = ad;
368         setting_view_create(&setting_view_main, ad);
369
370         /* error handling */
371         if (Cfg_Error_Type_Sucess != cfg_operation_ret) {
372                 SETTING_TRACE_ERROR("cfg_operation_ret: %d", cfg_operation_ret);
373                 const char *notifyStr = NULL;
374                 switch (cfg_operation_ret) {
375
376                         case Cfg_Error_Type_CreateCfg_Failed: {
377                                         notifyStr = _("failed to create config file, <br>re-install org.tizen.setting please");
378                                         break;
379                                 }
380                         case Cfg_Error_Type_Mkdir_Failed: {
381                                         notifyStr = _("file system missed<br>/opt/usr/data/setting, <br>re-install org.tizen.setting please");
382                                         break;
383                                 }
384                         case Cfg_Error_Type_RemoveCfg_Failed: {
385                                         notifyStr = _("config file size 0 byte<br>and failed to re-create it.<br>try to startup the app again");
386                                         break;
387                                 }
388                         case Cfg_Error_Type_ReadCfg_Failed: {
389                                         notifyStr = _("failed to read config file, <br>try to startup the app again");
390                                         break;
391                                 }
392                         case Cfg_Error_Type_DirPermissionDenied: {
393                                         notifyStr =
394                                             _("the dir of config file permission denied");
395                                         break;
396                                 }
397                         case Cfg_Error_Type_FilePermissionDenied: {
398                                         notifyStr = _("config file permission denied");
399                                         break;
400                                 }
401                         default: {
402                                         notifyStr = _("Invalid Result, try to startup the app again");
403                                         break;
404                                 }
405                 }
406                 setting_create_popup(ad, ad->win_main, NULL, (char *)notifyStr, NULL, 10, FALSE, FALSE, 0);
407                 return SETTING_RETURN_FAIL;
408         }
409
410
411         SETTING_TRACE_DEBUG("[TIME] 4. setting_main_app_create taked %d msec ", appcore_measure_time());
412         appcore_measure_start();
413         LAUNCH_SETTING_OUT();
414         return true;
415 }
416
417 /**
418 * The function is called when Setting is terminated
419 */
420 static void setting_main_app_terminate(void *data)
421 {
422         SETTING_TRACE_BEGIN;
423         setting_main_appdata *ad = data;
424         vconf_set_bool(VCONFKEY_SETAPPL_ROTATE_HOLD_BOOL, FALSE);
425         evas_object_smart_callback_del(ad->win_main, "wm,rotation,changed", _rot_changed_cb);
426
427         /*PLUGIN_FINI; */
428         setting_cfg_exit();
429         clear_system_service_data();
430
431         ug_destroy_all();
432         ad->ug = NULL;
433
434         ug_create_cb(NULL , NULL);
435
436         SETTING_TRACE_DEBUG("%s*** SETTING APPLICATION CLOSED ***%s", SETTING_FONT_BGREEN, SETTING_FONT_BLACK);
437         DEREGISTER_VCONFS(ad->listened_list);
438
439
440         setting_view_destroy(&setting_view_main, ad);
441
442         SETTING_TRACE_DEBUG("!!! After setting_view_destroy");
443         if (ad->win_main) {
444                 evas_object_del(ad->win_main);
445                 ad->win_main = NULL;
446         }
447
448         if (ad->b) {
449                 bundle_free(ad->b);
450                 ad->b = NULL;
451         }
452
453         SETTING_TRACE_END;
454         return;
455 }
456
457 /**
458 * The function is called when Setting begins run in background from forground
459 */
460 static void setting_main_app_pause(void *data)
461 {
462         SETTING_TRACE_BEGIN;
463         setting_main_appdata *ad = data;
464         if (ad->ug) {
465                 ug_pause();
466         }
467 }
468
469 /**
470 * The function is called when Setting begins run in forground from background
471 */
472 static void setting_main_app_resume(void *data)
473 {
474         SETTING_TRACE_BEGIN;
475         setting_main_appdata *ad = data;
476
477         _rot_changed_cb(ad, ad->win_main, NULL);/*to fix P131121-02103 */
478
479         if (ad->is_searchmode % 10 == Cfg_Item_AppLauncher_Node) {
480                 /* app-launching exit */
481                 elm_exit();
482         }
483
484         if (!(ad->isInUGMode && ad->ug)) {      /* top-level view is not on UG */
485                 SETTING_TRACE("update main genlist in resuming app without UG");
486                 Eina_Bool is_freezed = evas_object_freeze_events_get(ad->navibar_main);
487                 SETTING_TRACE_DEBUG("is_freezed : %d", is_freezed);
488                 if (is_freezed) {
489                         evas_object_freeze_events_set(ad->navibar_main, EINA_FALSE);
490                 }
491
492         } else if (ad->ug) {
493                 ug_resume();
494         }
495 }
496
497 /**
498  * The function is called by app-fwk after app_create. It always do the process which cost much time.
499  */
500 static void setting_main_app_reset(app_control_h service, void *data)
501 {
502         SETTING_TRACE_BEGIN;
503         setting_main_appdata *ad = data;
504
505         if (is_searchmode_app(ad->is_searchmode)) {
506                 evas_object_hide(ad->view_layout);
507         } else {
508                 evas_object_show(ad->view_layout);
509         }
510         vconf_callback_fn cb = NULL;
511
512         cb = setting_int_vconf_change_cb;
513         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_BT_STATUS, cb, data);
514         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_WIFI_STATE, cb, ad);
515
516         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, cb, data);
517         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_SETAPPL_LCD_TIMEOUT_NORMAL, cb, data);
518         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, cb, data);
519         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_SYSMAN_BATTERY_CAPACITY, cb, data);
520
521         cb = setting_string_vconf_change_cb;
522         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_WIFI_CONNECTED_AP_NAME, cb, ad);
523         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_SETAPPL_SCREENMODE_SELNAME, cb, ad);
524         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_BGSET, cb, ad);
525         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_IDLE_LOCK_BGSET, cb, ad);
526
527         cb = setting_other_vconf_change_cb;
528         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_SETAPPL_USB_MODE_INT, cb, ad);
529         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, cb, ad);
530         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_TELEPHONY_FLIGHT_MODE, cb, ad);
531         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, cb, ad);
532         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, cb, ad);
533 #ifndef BINARY_RELEASE_TYPE_ENG
534         REGISTER_VCONF_NODE(ad->listened_list, VCONFKEY_SETAPPL_DEVELOPER_OPTION_STATE, cb, ad);
535 #endif
536
537         /*---------------------------------------------------------------------------------- */
538
539         /*---------------------------------------------------------------------------------- */
540
541         if (ad->win_main) {
542                 elm_win_activate(ad->win_main);
543         }
544
545         /* Disable data_network if flight mode is ON */
546         int flight_mode = 0;
547         vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &flight_mode);
548         if (flight_mode) {
549                 if (ad->data_network) setting_disable_genlist_item(ad->data_network->item);
550         }
551 }
552
553 EXPORT_PUBLIC
554 int main(int argc, char *argv[])
555 {
556         int r = 0;
557         setting_main_appdata ad;
558
559         SETTING_TRACE_DEBUG("[TIME] 1. aul_launch -> main :: Setting main : %d msec ", appcore_measure_time_from("APP_START_TIME"));
560         appcore_measure_start();
561
562
563         ui_app_lifecycle_callback_s ops = {
564                 .create = setting_main_app_create,
565                 .terminate = setting_main_app_terminate,
566                 .pause = setting_main_app_pause,
567                 .resume = setting_main_app_resume,
568                 .app_control = setting_main_app_reset,
569         };
570         memset(&ad, 0x00, sizeof(setting_main_appdata));
571
572         bundle *b = NULL;
573         b = bundle_import_from_argv(argc, argv);
574         ad.b = b;
575
576         SETTING_TRACE_DEBUG("[TIME] 2. main : %d msec ", appcore_measure_time());
577         appcore_measure_start();
578         r = ui_app_main(argc, argv, &ops, &ad);
579         retv_if(r == -1, -1);
580
581         return 0;
582 }