Add changelog for new release
[profile/ivi/org.tizen.browser.git] / src / browser-main.cpp
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 extern "C" {
19 #include <ITapiSat.h>
20 #include <TapiUtility.h>
21 }
22
23 #include <app.h>
24 #include "browser-config.h"
25 #include "browser-class.h"
26
27 struct browser_data {
28         Evas_Object *main_win;
29         Evas_Object *bg;
30         Evas_Object *main_layout;
31         Evas_Object *navi_bar;
32         Elm_Theme *browser_theme;
33
34         Browser_Class *browser_instance;
35
36         Eina_Bool is_paused;
37 };
38
39 static void __br_set_env(void)
40 {
41 #if !defined(TIZEN_PUBLIC)
42         /* manual enabling of CoreGL fastpath */        
43         setenv("COREGL_FASTPATH", "1", 1);
44 #endif
45
46         /* set image cache suze */
47         if (setenv("ELM_IMAGE_CACHE", "0", 1))
48                 BROWSER_LOGD("ELM_IMAGE_CACHE is set to 1MB");
49
50         /* This is because of showing navigation bar more quickly. */
51         if (setenv("ELM_BRING_IN_SCROLL_FRICTION", "0.2", 1))
52                 BROWSER_LOGD("ELM_BRING_IN_SCROLL_FRICTION is set");
53
54         if (setenv("ELM_PAGE_SCROLL_FRICTION", "0.4", 1))
55                 BROWSER_LOGD("ELM_PAGE_SCROLL_FRICTION is set");
56
57         if (setenv("ELM_THUMBSCROLL_BOUNCE_FRICTION", "0.2", 1))
58                 BROWSER_LOGD("ELM_THUMBSCROLL_BOUNCE_FRICTION is set");
59 }
60
61 static void __br_destroy(void *data)
62 {
63         BROWSER_LOGD("[%s]", __func__);
64         elm_exit();
65 }
66
67 static void __main_win_del_cb(void *data, Evas_Object *obj, void *event)
68 {
69         BROWSER_LOGD("[Browser-Launching time measure]<< window delete callback >>");
70 }
71
72 static bool __init_preference()
73 {
74         BROWSER_LOGD("[%s]", __func__);
75
76         if (!br_preference_create_bool(SHOW_MY_SITES_GUIDE, true))
77                 return false;
78         if (!br_preference_create_str(LAST_VISITED_URL_KEY, ""))
79                 return false;
80 #if defined(FEATURE_MOST_VISITED_SITES)
81         if (!br_preference_create_str(HOMEPAGE_KEY, MOST_VISITED_SITES))
82                 return false;
83 #else
84         if (!br_preference_create_str(HOMEPAGE_KEY, USER_HOMEPAGE))
85                 return false;
86 #endif
87         if (!br_preference_create_str(USER_HOMEPAGE_KEY, BROWSER_DEFAULT_USER_HOMEPAGE))
88                 return false;
89         if (!br_preference_create_str(SEARCHURL_KEY, "http://search.yahoo.com/search?p="))
90                 return false;
91         if (!br_preference_create_str(DEFAULT_VIEW_LEVEL_KEY, READABLE))
92                 return false;
93         if (!br_preference_create_bool(RUN_JAVASCRIPT_KEY, true))
94                 return false;
95         if (!br_preference_create_bool(DISPLAY_IMAGES_KEY, true))
96                 return false;
97         if (!br_preference_create_bool(BLOCK_POPUP_KEY, true))
98                 return false;
99         if (!br_preference_create_bool(SHOW_SECURITY_WARNINGS_KEY, true))
100                 return false;
101         if (!br_preference_create_bool(ACCEPT_COOKIES_KEY, true))
102                 return false;
103         if (!br_preference_create_bool(ENABLE_LOCATION_KEY, true))
104                 return false;
105 #ifdef ZOOM_BUTTON
106         if (!br_preference_create_bool(ZOOM_BUTTON_KEY, true))
107                 return false;
108 #endif
109         return true;
110 }
111
112 static Evas_Object *__create_main_win(void *app_data)
113 {
114         Evas_Object *window = elm_win_add(NULL, BROWSER_PACKAGE_NAME, ELM_WIN_BASIC);
115         if (window) {
116                 int w;
117                 int h;
118                 elm_win_title_set(window, BROWSER_PACKAGE_NAME);
119                 elm_win_borderless_set(window, EINA_TRUE);
120                 elm_win_conformant_set(window, EINA_TRUE);
121                 evas_object_smart_callback_add(window, "delete,request",
122                                                 __main_win_del_cb, app_data);
123                 ecore_x_window_size_get(ecore_x_window_root_first_get(),
124                                         &w, &h);
125                 evas_object_resize(window, w, h);
126                 elm_win_indicator_mode_set(window, ELM_WIN_INDICATOR_SHOW);
127                 evas_object_show(window);
128         }
129
130         return window;
131 }
132
133 static Evas_Object *__create_bg(Evas_Object *win)
134 {
135         Evas_Object *bg;
136         bg = elm_bg_add(win);
137         if (!bg)
138                 return NULL;
139
140         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
141         elm_win_resize_object_add(win, bg);
142         evas_object_show(bg);
143
144         return bg;
145 }
146
147 static Evas_Object *__create_main_layout(Evas_Object *win)
148 {
149         Evas_Object *layout;
150         layout = elm_layout_add(win);
151         if (!layout)
152                 return NULL;
153
154         if (!elm_layout_theme_set(layout, "layout", "application", "default"))
155                 BROWSER_LOGE("elm_layout_theme_set is failed.\n");
156
157         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
158         elm_win_resize_object_add(win, layout);
159         edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,show,indicator", "elm");
160         evas_object_show(layout);
161
162         return layout;
163 }
164
165 static Evas_Object *__create_navi_bar(void *app_data)
166 {
167         BROWSER_LOGD("[%s]", __func__);
168         Evas_Object *navi_bar;
169         struct browser_data *ad = (struct browser_data *)app_data;
170         navi_bar = elm_naviframe_add(ad->main_layout);
171         if (navi_bar) {
172                 elm_object_theme_set(navi_bar, ad->browser_theme);
173                 elm_object_style_set(navi_bar, "browser");
174                 elm_object_part_content_set(ad->main_layout, "elm.swallow.content", navi_bar);
175                 evas_object_show(navi_bar);
176         }
177
178         return navi_bar;
179 }
180
181 static Eina_Bool __process_app_service(service_h service, void *app_data)
182 {
183         BROWSER_LOGD("[%s]", __func__);
184         struct browser_data *ad = (struct browser_data *)app_data;
185
186         char *operation = NULL;
187         char *request_uri = NULL;
188         char *request_mime_type = NULL;
189
190         if (service_get_operation(service, &operation) != SERVICE_ERROR_NONE) {
191                 BROWSER_LOGD("get service operation failed");
192                 return EINA_FALSE;
193         }
194
195         if (service_get_uri(service, &request_uri) != SERVICE_ERROR_NONE) {
196                 BROWSER_LOGD("get service uri failed");
197         }
198
199         if (service_get_mime(service, &request_mime_type) != SERVICE_ERROR_NONE) {
200                 BROWSER_LOGD("get service mime failed");
201         }
202
203         if (!operation && !request_uri && !request_mime_type) {
204                 BROWSER_LOGD("Not app svc");
205                 return EINA_FALSE;
206         }
207
208         BROWSER_LOGD("operation[%s], request_uri[%s], request_mime_type[%s]", operation, request_uri, request_mime_type);
209
210         std::string full_path;
211
212         if (request_mime_type) {
213                 if (!strncmp(request_mime_type, "application/x-shockwave-flash", strlen("application/x-shockwave-flash"))
214                         || !strncmp(request_mime_type, "image/svg+xml", strlen("image/svg+xml"))
215                         || !strncmp(request_mime_type, "text/html", strlen("text/html"))
216                         || !strncmp(request_mime_type, "application/xml", strlen("application/xml"))) {
217                         if (request_uri)
218                                 full_path = std::string(request_uri);
219                 } else {
220                         BROWSER_LOGD("Not allowed mime type : [%s]", request_mime_type);
221                         return EINA_FALSE;
222                 }
223         } else if (request_uri) {
224                 full_path = std::string(request_uri);
225         }
226
227         BROWSER_LOGD("url=[%s]", full_path.c_str());
228
229         if (ad->main_win)
230                 elm_win_activate(ad->main_win);
231
232         ad->browser_instance->launch(full_path.c_str(), EINA_TRUE);
233
234         return EINA_TRUE;
235 }
236
237 static void __br_load_url(service_h service, void *app_data)
238 {
239         BROWSER_LOGD("[%s]", __func__);
240         struct browser_data *ad = (struct browser_data *)app_data;
241
242         if (__process_app_service(service, app_data)) {
243                 BROWSER_LOGD("app service");
244                 return;
245         }
246
247         std::string full_path;
248         char *mime_type = NULL;
249         char *search_keyword = NULL;
250         char *goto_url = NULL;
251         char *url = NULL;
252
253         if (service_get_uri(service, &url) != SERVICE_ERROR_NONE) {
254                 BROWSER_LOGD("get service uri failed");
255         }
256
257         if (service_get_mime(service, &mime_type) != SERVICE_ERROR_NONE) {
258                 BROWSER_LOGD("get service mime failed");
259         }
260
261         if (service_get_extra_data(service, "search_keyword", &search_keyword) != SERVICE_ERROR_NONE) {
262                 BROWSER_LOGD("get service extra data(search keyword) failed");
263         }
264
265         if (service_get_extra_data(service, "goto_url", &search_keyword) != SERVICE_ERROR_NONE) {
266                 BROWSER_LOGD("get service extra data(search keyword) failed");
267         }
268
269         if (mime_type && url) {
270                 BROWSER_LOGD("mime type=[%s], url=[%s]", mime_type, url);
271                 if (!strcmp(mime_type, "application/x-shockwave-flash")
272                         || !strcmp(mime_type, "image/svg+xml")
273                         || !strcmp(mime_type, "text/html")
274                         || !strcmp(mime_type, "application/xml")) {
275                         full_path = std::string(url);
276                 }
277         } else if (search_keyword) {
278                 BROWSER_LOGD("search_keyword=[%s]", search_keyword);
279                 if (search_keyword) {
280                         char *search_url = NULL;
281                         if (br_preference_get_str(SEARCHURL_KEY, &search_url) == false) {
282                                 BROWSER_LOGE("failed to get %s preference\n", SEARCHURL_KEY);
283                                 return;
284                         }
285                         if (search_url) {
286                                 full_path = std::string(search_url) + std::string(search_keyword);
287                                 free(search_url);
288                         }
289                 }
290         } else if (goto_url || url) {
291                 BROWSER_LOGD("goto_url=[%s], url=[%s]", goto_url, url);
292                 if (goto_url)
293                         full_path = goto_url;
294                 else
295                         full_path = url;
296         }
297         BROWSER_LOGD("url=[%s]", full_path.c_str());
298
299         if (ad->main_win)
300                 elm_win_activate(ad->main_win);
301
302         ad->browser_instance->launch(full_path.c_str(), EINA_TRUE);
303 }
304
305 static Eina_Bool __br_keydown_event(void *data, int type, void *event)
306 {
307         BROWSER_LOGD("[%s]", __func__);
308         Ecore_Event_Key *ev = (Ecore_Event_Key *)event;
309
310         if (!strcmp(ev->keyname, KEY_END)) {
311                 __br_destroy(data);
312         }
313
314         return EXIT_FAILURE;
315 }
316
317 #if defined(HORIZONTAL_UI)
318 static void __br_rotate_cb(app_device_orientation_e mode, void *data)
319 {
320         BROWSER_LOGD("[%s] rotation mode = %d", __func__, mode);
321         struct browser_data *ad = (struct browser_data *)data;
322         int rotation_value;
323
324         switch (mode) {
325         case APP_DEVICE_ORIENTATION_0:
326                 rotation_value = 0;
327                 ug_send_event(UG_EVENT_ROTATE_PORTRAIT);
328                 break;
329         case APP_DEVICE_ORIENTATION_90:
330                 rotation_value = 90;
331                 ug_send_event(UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN);
332                 break;
333         case APP_DEVICE_ORIENTATION_180:
334                 rotation_value = 180;
335                 ug_send_event(UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN);
336                 break;
337         case APP_DEVICE_ORIENTATION_270:
338                 rotation_value = 270;
339                 ug_send_event(UG_EVENT_ROTATE_LANDSCAPE);
340                 break;
341         default:
342                 rotation_value = -1;
343                 break;
344         }
345
346         if (rotation_value >= 0 && ad->browser_instance) {
347                 if (ad->browser_instance->is_available_to_rotate()) {
348                         elm_win_rotation_with_resize_set(ad->main_win, rotation_value);
349                         ad->browser_instance->rotate(rotation_value);
350                 }
351         }
352 }
353 #endif
354
355 static void __br_low_memory_cb(void* data)
356 {
357         BROWSER_LOGD("[%s]", __func__);
358         /* To do */
359         struct browser_data *ad = (struct browser_data *)data;
360
361         if (ad && ad->browser_instance)
362                 ad->browser_instance->clean_up_windows();
363 }
364
365 static void __br_low_battery_cb(void* data)
366 {
367         BROWSER_LOGD("[%s]", __func__);
368         /* To do */
369         return;
370 }
371
372 static void __br_lang_changed_cb(void *data)
373 {
374         BROWSER_LOGD("[%s]", __func__);
375         /* To do */
376         return;
377 }
378
379 static void __br_region_changed_cb(void *data)
380 {
381         BROWSER_LOGD("[%s]", __func__);
382         /* To do */
383         return;
384 }
385
386 static void __br_register_system_event(void *app_data)
387 {
388         /* To do */
389         struct browser_data *ad = (struct browser_data *)app_data;
390 }
391
392 static int __browser_set_i18n(const char *domain, const char *dir)
393 {
394     char *r = NULL;
395
396     if (domain == NULL) {
397                 BROWSER_LOGE("domain is NULL");
398         return -1;
399     }
400
401     r = setlocale(LC_ALL, "");
402
403     /* if locale is not set properly, try again to set as language base */
404     if (r == NULL) {
405         char *lang_set = vconf_get_str(VCONFKEY_LANGSET);
406         if (!lang_set && strlen(lang_set) > 0)
407             r = setlocale(LC_ALL, lang_set);
408
409         BROWSER_LOGE("setlocale as [%s]", r);
410         if (lang_set)
411             free(lang_set);
412     }
413
414     if (r == NULL) {
415                 BROWSER_LOGE("setlocale failed");
416         return -1;
417     }
418
419     r = bindtextdomain(domain, dir);
420     if (r == NULL) {
421                 BROWSER_LOGE("bindtextdomain failed");
422         return -1;
423     }
424
425     r = textdomain(domain);
426     if (r == NULL) {
427                 BROWSER_LOGE("textdomain failed");
428         return -1;
429     }
430
431     return 0;
432 }
433
434 static bool __br_app_create(void *app_data)
435 {
436         BROWSER_LOGD("[Browser-Launching time measure] << theme extenstion >>");
437         struct browser_data *ad = (struct browser_data *)app_data;
438
439         elm_config_preferred_engine_set("opengl_x11");
440
441         if(!__init_preference())
442                 return false;
443
444         ad->browser_theme = elm_theme_new();
445         elm_theme_ref_set(ad->browser_theme, NULL);
446         elm_theme_extension_add(ad->browser_theme, BROWSER_NAVIFRAME_THEME);
447         elm_theme_extension_add(ad->browser_theme, BROWSER_CONTROLBAR_THEME);
448         elm_theme_extension_add(ad->browser_theme, BROWSER_BUTTON_THEME);
449         elm_theme_extension_add(ad->browser_theme, BROWSER_PROGRESSBAR_THEME);
450         elm_theme_extension_add(ad->browser_theme, BROWSER_URL_LAYOUT_THEME);
451         elm_theme_extension_add(ad->browser_theme, BROWSER_PREDICTIVE_HISTORY_THEME);
452         elm_theme_extension_add(ad->browser_theme, BROWSER_SETTINGS_THEME);
453         elm_theme_extension_add(ad->browser_theme, BROWSER_BOOKMARK_THEME);
454         elm_theme_extension_add(ad->browser_theme, BROWSER_FIND_WORD_LAYOUT_THEME);
455
456         BROWSER_LOGD("[Browser-Launching time measure] << create main window >>");
457         ad->main_win = __create_main_win(ad);
458         if (!ad->main_win) {
459                 BROWSER_LOGE("fail to create window");
460                 return false;
461         }
462
463         BROWSER_LOGD("[Browser-Launching time measure] << create background >>");
464         ad->bg = __create_bg(ad->main_win);
465         if (!ad->bg) {
466                 BROWSER_LOGE("fail to create bg");
467                 return false;
468         }
469
470         BROWSER_LOGD("[Browser-Launching time measure] << create layout main >>");
471         ad->main_layout = __create_main_layout(ad->main_win);
472         if (!ad->main_layout) {
473                 BROWSER_LOGE("fail to create main layout");
474                 return false;
475         }
476
477         ad->navi_bar = __create_navi_bar(ad);
478         if (!ad->navi_bar) {
479                 BROWSER_LOGE("fail to create navi bar");
480                 return false;
481         }
482
483         /* create browser instance & init */
484         ad->browser_instance = new(nothrow) Browser_Class(ad->main_win, ad->navi_bar, ad->bg);
485         if (!ad->browser_instance) {
486                 BROWSER_LOGE("fail to Browser_Class");
487                 return false;
488         }
489         if (ad->browser_instance->init() == EINA_FALSE) {
490                 BROWSER_LOGE("fail to browser init");
491                 return false;
492         }
493
494         /* init internationalization */
495         int ret = __browser_set_i18n(BROWSER_PACKAGE_NAME, BROWSER_LOCALE_DIR);
496         if (ret) {
497                 BROWSER_LOGE("fail to __browser_set_i18n");
498                 return false;
499         }
500
501 #if defined(HORIZONTAL_UI)
502         app_device_orientation_e rotation_value = app_get_device_orientation();
503
504         if (rotation_value != APP_DEVICE_ORIENTATION_0) {
505                 elm_win_rotation_with_resize_set(ad->main_win, rotation_value);
506                 ad->browser_instance->rotate(rotation_value);
507         }
508 #endif
509
510         return true;
511 }
512
513 /* GCF test requirement */
514 static void __send_termination_event_to_tapi(void)
515 {
516         BROWSER_LOGD("[%s]", __func__);
517         int ret = TAPI_API_SUCCESS;
518         int request_id = -1;
519         TelSatEventDownloadReqInfo_t event_data;
520         event_data.eventDownloadType = TAPI_EVENT_SAT_DW_TYPE_BROWSER_TERMINATION;
521         event_data.u.browserTerminationEventReqInfo.browserTerminationCause = TAPI_SAT_BROWSER_TERMINATED_BY_USER;
522
523         TapiHandle *handle = NULL;
524         handle = tel_init(NULL);
525
526         ret = tel_download_sat_event(handle, &event_data, NULL, NULL);
527         if(ret != TAPI_API_SUCCESS && ret != TAPI_API_SAT_EVENT_NOT_REQUIRED_BY_USIM)
528                 BROWSER_LOGE("failed to tel_download_sat_event");
529
530         tel_deinit(handle);
531 }
532
533 static void __br_app_terminate(void *app_data)
534 {
535         BROWSER_LOGD("[%s]", __func__);
536         struct browser_data *ad = (struct browser_data *)app_data;
537
538         elm_theme_extension_del(ad->browser_theme, BROWSER_NAVIFRAME_THEME);
539         elm_theme_extension_del(ad->browser_theme, BROWSER_CONTROLBAR_THEME);
540         elm_theme_extension_del(ad->browser_theme, BROWSER_BUTTON_THEME);
541         elm_theme_extension_del(ad->browser_theme, BROWSER_URL_LAYOUT_THEME);
542         elm_theme_extension_del(ad->browser_theme, BROWSER_PROGRESSBAR_THEME);
543         elm_theme_extension_del(ad->browser_theme, BROWSER_PREDICTIVE_HISTORY_THEME);
544         elm_theme_extension_del(ad->browser_theme, BROWSER_SETTINGS_THEME);
545         elm_theme_extension_del(ad->browser_theme, BROWSER_BOOKMARK_THEME);
546         elm_theme_extension_del(ad->browser_theme, BROWSER_FIND_WORD_LAYOUT_THEME);
547         elm_theme_free(ad->browser_theme);
548
549         /* GCF test requirement */
550         __send_termination_event_to_tapi();
551
552         if (ad->main_win);
553                 evas_object_del(ad->main_win);
554
555         if (ad->browser_instance)
556                 delete ad->browser_instance;
557
558         BROWSER_LOGD("[Browser-Launching time measure] << __br_app_terminate ends >>");
559 }
560
561 static void __br_app_pause(void *app_data)
562 {
563         BROWSER_LOGD("[%s]", __func__);
564         struct browser_data *ad = (struct browser_data *)app_data;
565
566         if (!ad || !ad->browser_instance)
567                 return;
568
569         ad->browser_instance->pause();
570
571         ad->is_paused = EINA_TRUE;
572 }
573
574 static void __br_app_resume(void *app_data)
575 {
576         BROWSER_LOGD("[%s]", __func__);
577         struct browser_data *ad = (struct browser_data *)app_data;
578
579         if (!ad || !ad->browser_instance)
580                 return;
581
582         ad->browser_instance->resume();
583
584         ad->is_paused = EINA_FALSE;
585 }
586
587 static void __br_app_reset(service_h service, void *app_data)
588 {
589         struct browser_data *ad = (struct browser_data *)app_data;
590         BROWSER_LOGD("[%s]", __func__);
591
592         ad->browser_instance->reset();
593
594         __br_load_url(service, app_data);
595
596         ad->is_paused = EINA_FALSE;
597 }
598
599 int main(int argc, char *argv[])
600 {
601         __br_set_env();
602
603         app_event_callback_s ops;
604         memset(&ops, 0x0, sizeof(app_event_callback_s));
605
606         ops.create = __br_app_create;
607         ops.terminate = __br_app_terminate;
608         ops.pause = __br_app_pause;
609         ops.resume = __br_app_resume;
610         ops.service = __br_app_reset;
611         ops.low_memory = __br_low_memory_cb;
612         ops.low_battery = __br_low_battery_cb;
613 #if defined(HORIZONTAL_UI)
614         ops.device_orientation = __br_rotate_cb;
615 #endif
616         ops.language_changed = __br_lang_changed_cb;
617         ops.region_format_changed = __br_region_changed_cb;
618
619         struct browser_data ad;
620         memset(&ad, 0x0, sizeof(struct browser_data));
621
622         int ret = app_efl_main(&argc, &argv, &ops, &ad);
623
624         return ret;
625 }
626