Add evas object show for all apps layout & fix transparent layout
[apps/native/menu-screen.git] / src / menu_screen.c
1 /*
2  * MENU-SCREEN
3  *
4  * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
5  *
6  * Contact: Jin Yoon <jinny.yoon@samsung.com>
7  *          Junkyu Han <junkyu.han@samsung.com>
8
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <app.h>
24 #include <appcore-efl.h>
25 #include <aul.h>
26 #include <Elementary.h>
27 #include <stdbool.h>
28 #include <system_info.h>
29 #include <vconf.h>
30 #include <app_preference.h>
31 #include <system_settings.h>
32 #include <pkgmgr-info.h>
33
34 #include "conf.h"
35 #include "item.h"
36 #include "key.h"
37 #include "layout.h"
38 #include "mapbuf.h"
39 #include "menu_screen.h"
40 #include "mouse.h"
41 #include "page.h"
42 #include "page_scroller.h"
43 #include "pkgmgr.h"
44 #include "util.h"
45
46 #define MENU_SCREEN_ENGINE "file/private/org.tizen.menu-screen/engine"
47
48 #define LAYOUT_EDJE_PORTRAIT EDJEDIR"/layout_portrait.edj"
49 #define LAYOUT_GROUP_NAME "layout"
50
51
52
53 // Define prototype of the "hidden API of AUL"
54 extern int aul_listen_app_dead_signal(int (*func)(int signal, void *data), void *data);
55 static struct {
56         int state;
57         int root_width;
58         int root_height;
59         int is_tts;
60         int booting_state;
61         Evas *evas;
62         Ecore_Evas *ee;
63         Evas_Object *win;
64         Elm_Theme *theme;
65         bool is_done;
66 } menu_screen_info = {
67         .state = APP_STATE_PAUSE,
68         .is_tts = false,
69         .booting_state = 0,
70         .evas = NULL,
71         .ee = NULL,
72         .win = NULL,
73         .theme = NULL,
74         .is_done = false,
75 };
76
77
78
79 HAPI Evas *menu_screen_get_evas(void)
80 {
81         return menu_screen_info.evas;
82 }
83
84
85
86 HAPI int menu_screen_get_root_width(void)
87 {
88         return menu_screen_info.root_width;
89 }
90
91
92
93 HAPI int menu_screen_get_root_height(void)
94 {
95         return menu_screen_info.root_height;
96 }
97
98
99
100 HAPI Evas_Object *menu_screen_get_win(void)
101 {
102         return menu_screen_info.win;
103 }
104
105
106
107 HAPI Elm_Theme *menu_screen_get_theme(void)
108 {
109         return menu_screen_info.theme;
110 }
111
112
113
114 HAPI bool menu_screen_get_done(void)
115 {
116         return menu_screen_info.is_done;
117 }
118
119
120
121 HAPI void menu_screen_set_done(bool is_done)
122 {
123         menu_screen_info.is_done = is_done;
124 }
125
126
127
128 HAPI int menu_screen_get_state(void)
129 {
130         return menu_screen_info.state;
131 }
132
133
134
135 HAPI int menu_screen_is_tts(void)
136 {
137         return menu_screen_info.is_tts;
138 }
139
140
141 static Eina_Bool _appcore_flush_cb(void *data)
142 {
143         if (APP_STATE_PAUSE != menu_screen_info.state) return ECORE_CALLBACK_CANCEL;
144         if (0 != appcore_flush_memory()) _E("Cannot flush memory");
145         return ECORE_CALLBACK_CANCEL;
146 }
147
148
149
150 HAPI void menu_screen_inc_booting_state(void)
151 {
152         menu_screen_info.booting_state++;
153         if (BOOTING_STATE_DONE > menu_screen_info.booting_state) return;
154
155         menu_screen_error_e ret = MENU_SCREEN_ERROR_OK;
156         do {
157                 ret = pkgmgr_reserve_list_pop_request();
158         } while (MENU_SCREEN_ERROR_OK == ret);
159
160         /*  Cache memory is cleared when the application paused (every time, after 5 seconds (in appcore)),
161         *  but after running in a minimized mode (HIDE_LAUNCH) application have status AS_RUNNING.
162         *  Application have status AS_PAUSED only after change of visibility to hidden condition by user (on hiding window)
163         *  Cleaning must be performed only once after application loading in hidden condition
164         *  (and stay in a hidden condition at time of cleaning).
165         */
166         if (APP_STATE_PAUSE == menu_screen_info.state)
167                 ecore_timer_add(5, _appcore_flush_cb, NULL);
168 }
169
170
171
172 HAPI void menu_screen_dec_booting_state(void)
173 {
174         menu_screen_info.booting_state --;
175 }
176
177
178
179 HAPI int menu_screen_get_booting_state(void)
180 {
181         return menu_screen_info.booting_state;
182 }
183
184
185
186 static bool _is_emulator_on(void)
187 {
188         int ret;
189         char *model = NULL;
190
191         ret = system_info_get_platform_string("tizen.org/system/model_name", &model);
192         if (SYSTEM_INFO_ERROR_NONE != ret) {
193                 if (model) {
194                         free(model);
195                 }
196                 return false;
197         }
198
199         if (!strncmp(model, "Emulator", strlen(model))) {
200                 _D("This model is on Emulator");
201                 free(model);
202                 return true;
203         }
204
205         _D("This model is NOT on Emulator");
206         free(model);
207         return false;
208 }
209
210
211
212 static menu_screen_error_e _create_canvas(char *name, char *title)
213 {
214         char *buf;
215
216         if (_is_emulator_on()) {
217                 _D("ELM_ENGINE is set as [software_x11]");
218                 elm_config_accel_preference_set("opengl");
219         } else {
220                 buf = vconf_get_str(MENU_SCREEN_ENGINE);
221                 if (buf) {
222                         _D("ELM_ENGINE is set as [%s]", buf);
223                         elm_config_accel_preference_set(buf);
224                         free(buf);
225                 } else {
226                         _D("ELM_ENGINE is set as [gl]");
227                         elm_config_accel_preference_set("gl");
228                 }
229         }
230
231         menu_screen_info.win = elm_win_util_standard_add(name, name);
232         retv_if(NULL == menu_screen_info.win, MENU_SCREEN_ERROR_FAIL);
233
234         if (title) {
235                 elm_win_title_set(menu_screen_info.win, title);
236         }
237         _D("elm_scale: %f", elm_app_base_scale_get());
238         _D("config_scale: %f", elm_config_scale_get());
239
240         elm_win_borderless_set(menu_screen_info.win, EINA_TRUE);
241         elm_win_screen_size_get(menu_screen_info.win, NULL, NULL, &menu_screen_info.root_width, &menu_screen_info.root_height);
242         _D("menu-screen window size:: width: %d, height: %d", menu_screen_info.root_width, menu_screen_info.root_height);
243
244 #if 0
245         ecore_x_icccm_name_class_set(elm_win_xwindow_get(menu_screen_info.win), "MENU_SCREEN", "MENU_SCREEN");
246         ATOM_WM_WINDOW_ROLE = ecore_x_atom_get("WM_WINDOW_ROLE");
247         if (ATOM_WM_WINDOW_ROLE) {
248                 ecore_x_window_prop_string_set(elm_win_xwindow_get(menu_screen_info.win), ATOM_WM_WINDOW_ROLE, "MENU_SCREEN");
249         } else {
250                 _D("Failed to set the window role as MENU_SCREEN");
251         }
252 #endif
253
254         elm_win_role_set(menu_screen_info.win, "MENU_SCREEN");
255
256         menu_screen_info.evas = evas_object_evas_get(menu_screen_info.win);
257         if (!menu_screen_info.evas) {
258                 _E("[%s] Failed to get the evas object", __func__);
259         }
260
261         menu_screen_info.ee = ecore_evas_ecore_evas_get(menu_screen_info.evas);
262         if (!menu_screen_info.ee) {
263                 _E("[%s] Failed to get ecore_evas object", __func__);
264         }
265
266         evas_object_show(menu_screen_info.win);
267
268         return MENU_SCREEN_ERROR_OK;
269 }
270
271
272
273 static void _destroy_canvas(void)
274 {
275         evas_object_del(menu_screen_info.win);
276 }
277
278
279
280 static int _dead_cb(int pid, void *data)
281 {
282         return EXIT_SUCCESS;
283 }
284
285
286
287 static void _create_bg(void)
288 {
289         _D("Create BG");
290         char *buf = NULL;
291         Evas_Object *bg;
292         int width;
293         int height;
294
295         if (system_settings_get_value_string(SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN, &buf) < 0) {
296                 _E("Failed to get a wallpaper: %d\n", SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN);
297         }
298         _D("Menu-screen bg's image : %s", buf);
299
300         width = menu_screen_get_root_width();
301         height = menu_screen_get_root_height();
302         _D("width : %d, height : %d FOR BG", width, height);
303
304         bg = evas_object_data_get(menu_screen_get_win(), "bg");
305         if (!bg) {
306                 _D("BG is NULL, Create!!");
307                 Evas_Object *rect;
308
309                 rect = evas_object_rectangle_add(menu_screen_get_evas());
310                 if (NULL == rect) {
311                         free(buf);
312                         return;
313                 }
314                 evas_object_data_set(menu_screen_get_win(), "rect", rect);
315                 evas_object_color_set(rect, 0, 0, 0, 255);
316                 evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
317                 evas_object_size_hint_min_set(rect, width, height);
318                 evas_object_size_hint_max_set(rect, width, height);
319                 elm_win_resize_object_add(menu_screen_get_win(), rect);
320                 evas_object_show(rect);
321
322                 bg = elm_image_add(menu_screen_get_win());
323                 if (NULL == bg) {
324                         free(buf);
325                         return;
326                 }
327                 evas_object_data_set(menu_screen_get_win(), "bg", bg);
328         }
329
330         elm_image_aspect_fixed_set(bg, EINA_TRUE);
331         elm_image_fill_outside_set(bg, EINA_TRUE);
332         elm_image_preload_disabled_set(bg, EINA_FALSE);
333
334         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
335         evas_object_size_hint_min_set(bg, width, height);
336         evas_object_size_hint_max_set(bg, width, height);
337         if (!elm_image_file_set(bg, buf, NULL)) {
338                 _E("Failed to set image file : %s", buf);
339         }
340
341         elm_win_resize_object_add(menu_screen_get_win(), bg);
342         evas_object_show(bg);
343
344         free(buf);
345 }
346
347
348
349
350 static void _destroy_bg()
351 {
352         Evas_Object *rect;
353         Evas_Object *bg;
354
355         rect = evas_object_data_del(menu_screen_get_win(), "rect");
356         evas_object_del(rect);
357
358         bg = evas_object_data_del(menu_screen_get_win(), "bg");
359         evas_object_del(bg);
360 }
361
362
363
364 static void _change_bg_cb(system_settings_key_e key, void *data)
365 {
366         _D("Background image is changed.");
367         _create_bg();
368 }
369
370
371
372 static void _init_theme(void)
373 {
374         menu_screen_info.theme = elm_theme_new();
375         elm_theme_ref_set(menu_screen_info.theme, NULL);
376         elm_theme_extension_add(menu_screen_info.theme, EDJEDIR"/index.edj");
377 }
378
379
380
381 static void _fini_theme(void)
382 {
383         elm_theme_extension_del(menu_screen_info.theme, EDJEDIR"/index.edj");
384         elm_theme_free(menu_screen_info.theme);
385         menu_screen_info.theme = NULL;
386
387 }
388
389
390
391 static Evas_Object *_create_conformant(Evas_Object *win)
392 {
393         Evas_Object *conformant;
394
395         conformant = elm_conformant_add(win);
396         retv_if(NULL == conformant, NULL);
397
398         evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
399         elm_win_indicator_mode_set(menu_screen_info.win, ELM_WIN_INDICATOR_SHOW);
400         elm_object_signal_emit(conformant, "elm,state,indicator,overlap", "elm");
401         evas_object_data_set(conformant, "win", win);
402         evas_object_show(conformant);
403
404         elm_win_resize_object_add(win, conformant);
405         elm_win_conformant_set(win, EINA_TRUE);
406
407         return conformant;
408 }
409
410
411
412 static void _destroy_conformant(Evas_Object *conformant)
413 {
414         evas_object_data_del(conformant, "win");
415         evas_object_del(conformant);
416 }
417
418
419
420 static bool _create_cb(void *data)
421 {
422         Evas_Object *conformant;
423
424         _init_theme();
425         retv_if(MENU_SCREEN_ERROR_FAIL == _create_canvas(PACKAGE, PACKAGE), false);
426
427         if (system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN, _change_bg_cb, NULL) < 0) {
428                 _E("Failed to register a settings change cb for %d\n", SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN);
429         }
430         _create_bg();
431
432         conformant = _create_conformant(menu_screen_info.win);
433         retv_if(NULL == conformant, false);
434         evas_object_data_set(menu_screen_info.win, "conformant", conformant);
435
436         Evas_Object *layout;
437         layout = layout_create(conformant, LAYOUT_EDJE_PORTRAIT,
438                                 LAYOUT_GROUP_NAME, MENU_SCREEN_ROTATE_PORTRAIT);
439         if (NULL == layout) {
440                 _E("Failed to load an edje object");
441                 evas_object_del(menu_screen_info.win);
442                 return false;
443         }
444         evas_object_data_set(menu_screen_info.win, "layout", layout);
445
446         elm_object_content_set(conformant, layout);
447
448         mouse_register();
449         aul_listen_app_dead_signal(_dead_cb, NULL);
450         key_register();
451
452         // FIXME : This will be enabled after rebuilding the routine for appid <-> pkgid.
453         pkgmgr_init();
454
455         return true;
456 }
457
458
459
460 static void _terminate_cb(void *data)
461 {
462         Evas_Object *conformant;
463         Evas_Object *layout;
464
465         // FIXME : This will be enabled after rebuilding the routine for appid <-> pkgid.
466         pkgmgr_fini();
467
468         if (system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN) < 0) {
469                 _E("Failed to remove bgset [%s]\n", SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN);
470         }
471
472         evas_object_hide(menu_screen_info.win);
473
474         key_unregister();
475         mouse_unregister();
476
477         layout = evas_object_data_del(menu_screen_info.win, "layout");
478         if (layout) layout_destroy(layout);
479
480         conformant = evas_object_data_del(menu_screen_info.win, "conformant");
481         if (conformant) _destroy_conformant(conformant);
482
483         _destroy_bg();
484         _destroy_canvas();
485         _fini_theme();
486         evas_object_del(menu_screen_info.win);
487 }
488
489
490
491 static void _pause_cb(void *data)
492 {
493         _D("Pause start");
494
495         menu_screen_info.state = APP_STATE_PAUSE;
496 }
497
498
499
500 static void _resume_cb(void *data)
501 {
502         _D("START RESUME");
503
504         do { // Focus
505                 Evas_Object *layout = evas_object_data_get(menu_screen_info.win, "layout");
506                 break_if(NULL == layout);
507
508                 Evas_Object *all_apps = evas_object_data_get(layout, "all_apps");
509                 break_if(NULL == all_apps);
510
511                 Evas_Object *scroller = elm_object_part_content_get(all_apps, "content");
512                 break_if(NULL == scroller);
513
514                 page_scroller_focus(scroller);
515         } while (0);
516
517         menu_screen_info.state = APP_STATE_RESUME;
518 }
519
520
521
522 static void _app_control_cb(app_control_h service, void *data)
523 {
524         _D("START RESET : %d", menu_screen_info.state);
525
526         do { // Focus
527                 Evas_Object *layout = evas_object_data_get(menu_screen_info.win, "layout");
528                 break_if(NULL == layout);
529
530                 Evas_Object *all_apps = evas_object_data_get(layout, "all_apps");
531                 break_if(NULL == all_apps);
532
533                 Evas_Object *scroller = elm_object_part_content_get(all_apps, "content");
534                 break_if(NULL == scroller);
535
536                 page_scroller_focus(scroller);
537         } while (0);
538 }
539
540
541
542 static void _language_changed_cb(app_event_info_h event_info, void *data)
543 {
544         register unsigned int i;
545         register unsigned int j;
546         unsigned int count;
547         Evas_Object *layout;
548         Evas_Object *all_apps;
549         Evas_Object *scroller;
550         Evas_Object *page;
551         Evas_Object *item;
552         unsigned int page_max_app;
553
554         _D("Language is changed");
555
556         if (false == menu_screen_info.is_done) {
557                 elm_exit();
558         }
559
560         layout = evas_object_data_get(menu_screen_info.win, "layout");
561         ret_if(NULL == layout);
562         all_apps = evas_object_data_get(layout, "all_apps");
563         ret_if(NULL == all_apps);
564         scroller = elm_object_part_content_get(all_apps, "content");
565         ret_if(NULL == scroller);
566
567         count = page_scroller_count_page(scroller);
568         page_max_app = (unsigned int) evas_object_data_get(scroller, "page_max_app");
569         for (i = 0; i < count; i ++) {
570                 page = page_scroller_get_page_at(scroller, i);
571                 if (!page) continue;
572                 if (mapbuf_is_enabled(page)) {
573                         mapbuf_disable(page, 1);
574                 }
575
576                 for (j = 0; j < page_max_app; j ++) {
577                         pkgmgrinfo_appinfo_h appinfo_h = NULL;
578                         char *name;
579
580                         item = page_get_item_at(page, j);
581                         if (!item) continue;
582
583                         if (pkgmgrinfo_appinfo_get_usr_appinfo(item_get_package(item), getuid(), &appinfo_h) < 0) {
584                                 pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h);
585                                 continue;
586                         }
587                         if (pkgmgrinfo_appinfo_get_label(appinfo_h, &name) < 0) {
588                                 pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h);
589                                 continue;
590                         }
591
592                         if (!name) {
593                                 _D("Failed to get name for %s", item_get_package(item));
594                                 pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h);
595                                 continue;
596                         }
597
598                         item_set_name(item, name, 0);
599                         pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h);
600                 }
601
602                 mapbuf_enable(page, 1);
603         }
604 }
605
606
607
608 static void _init(ui_app_lifecycle_callback_s *lifecycle_callback, app_event_handler_h *event_handlers)
609 {
610         lifecycle_callback->create = _create_cb;
611         lifecycle_callback->terminate = _terminate_cb;
612         lifecycle_callback->pause = _pause_cb;
613         lifecycle_callback->resume = _resume_cb;
614         lifecycle_callback->app_control = _app_control_cb;
615
616         ui_app_add_event_handler(&event_handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, NULL, NULL);
617         ui_app_add_event_handler(&event_handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, NULL, NULL);
618         ui_app_add_event_handler(&event_handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, NULL, NULL);
619         ui_app_add_event_handler(&event_handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, _language_changed_cb, NULL);
620         ui_app_add_event_handler(&event_handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, NULL, NULL);
621
622 }
623
624
625
626 static void _fini(app_event_handler_h *event_handlers)
627 {
628         ui_app_remove_event_handler(event_handlers[APP_EVENT_LOW_BATTERY]);
629         ui_app_remove_event_handler(event_handlers[APP_EVENT_LOW_MEMORY]);
630         ui_app_remove_event_handler(event_handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED]);
631         ui_app_remove_event_handler(event_handlers[APP_EVENT_LANGUAGE_CHANGED]);
632         ui_app_remove_event_handler(event_handlers[APP_EVENT_REGION_FORMAT_CHANGED]);
633
634 }
635
636
637
638 int main(int argc, char *argv[])
639 {
640         ui_app_lifecycle_callback_s lifecycle_callback = {0, };
641         app_event_handler_h event_handlers[5] = {NULL, };
642
643         _init(&lifecycle_callback, event_handlers);
644         ui_app_main(argc, argv, &lifecycle_callback, NULL);
645         _fini(event_handlers);
646
647         return EXIT_SUCCESS;
648 }
649
650
651
652 // End of a file