66765d866d439c1da15aa03c51092345ca54fa9c
[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 <aul.h>
25 #include <Elementary.h>
26 #include <stdbool.h>
27 #include <system_info.h>
28 #include <vconf.h>
29 #include <app_preference.h>
30 #include <system_settings.h>
31 #include <app_manager.h>
32
33 #include "conf.h"
34 #include "item.h"
35 #include "key.h"
36 #include "layout.h"
37 #include "mapbuf.h"
38 #include "menu_screen.h"
39 #include "mouse.h"
40 #include "page.h"
41 #include "page_scroller.h"
42 #include "pkgmgr.h"
43 #include "util.h"
44
45 #define MENU_SCREEN_ENGINE "file/private/org.tizen.menu-screen/engine"
46 #define LAYOUT_GROUP_NAME "layout"
47
48
49 // Define prototype of the "hidden API of AUL"
50 extern int aul_listen_app_dead_signal(int (*func)(int signal, void *data), void *data);
51 static struct {
52         int state;
53         int root_width;
54         int root_height;
55         Evas *evas;
56         Ecore_Evas *ee;
57         Evas_Object *win;
58         Elm_Theme *theme;
59         bool is_done;
60 } menu_screen_info = {
61         .state = APP_STATE_PAUSE,
62         .evas = NULL,
63         .ee = NULL,
64         .win = NULL,
65         .theme = NULL,
66         .is_done = false,
67 };
68
69
70
71 HAPI Evas *menu_screen_get_evas(void)
72 {
73         return menu_screen_info.evas;
74 }
75
76
77
78 HAPI int menu_screen_get_root_width(void)
79 {
80         return menu_screen_info.root_width;
81 }
82
83
84
85 HAPI int menu_screen_get_root_height(void)
86 {
87         return menu_screen_info.root_height;
88 }
89
90
91
92 HAPI Evas_Object *menu_screen_get_win(void)
93 {
94         return menu_screen_info.win;
95 }
96
97
98
99 HAPI Elm_Theme *menu_screen_get_theme(void)
100 {
101         return menu_screen_info.theme;
102 }
103
104
105
106 HAPI bool menu_screen_get_done(void)
107 {
108         return menu_screen_info.is_done;
109 }
110
111
112
113 HAPI void menu_screen_set_done(bool is_done)
114 {
115         menu_screen_info.is_done = is_done;
116 }
117
118
119
120 HAPI int menu_screen_get_state(void)
121 {
122         return menu_screen_info.state;
123 }
124
125
126
127 static bool _is_emulator_on(void)
128 {
129         int ret;
130         char *model = NULL;
131
132         ret = system_info_get_platform_string("tizen.org/system/model_name", &model);
133         if (SYSTEM_INFO_ERROR_NONE != ret) {
134                 if (model) {
135                         free(model);
136                 }
137                 return false;
138         }
139
140         if (!strncmp(model, "Emulator", strlen(model))) {
141                 _D("This model is on Emulator");
142                 free(model);
143                 return true;
144         }
145
146         _D("This model is NOT on Emulator");
147         free(model);
148         return false;
149 }
150
151
152
153 static menu_screen_error_e _create_canvas(char *name, char *title)
154 {
155         char *buf;
156
157         if (_is_emulator_on()) {
158                 _D("ELM_ENGINE is set as [software_x11]");
159                 elm_config_accel_preference_set("opengl");
160         } else {
161                 buf = vconf_get_str(MENU_SCREEN_ENGINE);
162                 if (buf) {
163                         _D("ELM_ENGINE is set as [%s]", buf);
164                         elm_config_accel_preference_set(buf);
165                         free(buf);
166                 } else {
167                         _D("ELM_ENGINE is set as [gl]");
168                         elm_config_accel_preference_set("gl");
169                 }
170         }
171
172         menu_screen_info.win = elm_win_util_standard_add(name, name);
173         retv_if(NULL == menu_screen_info.win, MENU_SCREEN_ERROR_FAIL);
174
175         if (title) {
176                 elm_win_title_set(menu_screen_info.win, title);
177         }
178         _D("elm_scale: %f", elm_app_base_scale_get());
179         _D("config_scale: %f", elm_config_scale_get());
180
181         elm_win_borderless_set(menu_screen_info.win, EINA_TRUE);
182         elm_win_screen_size_get(menu_screen_info.win, NULL, NULL, &menu_screen_info.root_width, &menu_screen_info.root_height);
183         _D("menu-screen window size:: width: %d, height: %d", menu_screen_info.root_width, menu_screen_info.root_height);
184
185         elm_win_role_set(menu_screen_info.win, "MENU_SCREEN");
186
187         menu_screen_info.evas = evas_object_evas_get(menu_screen_info.win);
188         if (!menu_screen_info.evas) {
189                 _E("[%s] Failed to get the evas object", __func__);
190         }
191
192         menu_screen_info.ee = ecore_evas_ecore_evas_get(menu_screen_info.evas);
193         if (!menu_screen_info.ee) {
194                 _E("[%s] Failed to get ecore_evas object", __func__);
195         }
196
197         evas_object_show(menu_screen_info.win);
198
199         return MENU_SCREEN_ERROR_OK;
200 }
201
202
203
204 static void _destroy_canvas(void)
205 {
206         evas_object_del(menu_screen_info.win);
207 }
208
209
210
211 static int _dead_cb(int pid, void *data)
212 {
213         return EXIT_SUCCESS;
214 }
215
216
217
218 static void _create_bg(void)
219 {
220         _D("Create BG");
221         char *buf = NULL;
222         Evas_Object *bg;
223         int width;
224         int height;
225
226         if (system_settings_get_value_string(SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN, &buf) < 0) {
227                 _E("Failed to get a wallpaper: %d\n", SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN);
228         }
229         _D("Menu-screen bg's image : %s", buf);
230
231         width = menu_screen_get_root_width();
232         height = menu_screen_get_root_height();
233         _D("width : %d, height : %d FOR BG", width, height);
234
235         bg = evas_object_data_get(menu_screen_get_win(), "bg");
236         if (!bg) {
237                 _D("BG is NULL, Create!!");
238                 Evas_Object *rect;
239
240                 rect = evas_object_rectangle_add(menu_screen_get_evas());
241                 if (NULL == rect) {
242                         free(buf);
243                         return;
244                 }
245                 evas_object_data_set(menu_screen_get_win(), "rect", rect);
246                 evas_object_color_set(rect, 0, 0, 0, 255);
247                 evas_object_size_hint_weight_set(rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
248                 evas_object_size_hint_min_set(rect, width, height);
249                 evas_object_size_hint_max_set(rect, width, height);
250                 elm_win_resize_object_add(menu_screen_get_win(), rect);
251                 evas_object_show(rect);
252
253                 bg = elm_image_add(menu_screen_get_win());
254                 if (NULL == bg) {
255                         free(buf);
256                         return;
257                 }
258                 evas_object_data_set(menu_screen_get_win(), "bg", bg);
259         }
260
261         elm_image_aspect_fixed_set(bg, EINA_TRUE);
262         elm_image_fill_outside_set(bg, EINA_TRUE);
263         elm_image_preload_disabled_set(bg, EINA_FALSE);
264
265         evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
266         evas_object_size_hint_min_set(bg, width, height);
267         evas_object_size_hint_max_set(bg, width, height);
268         if (buf == NULL || !elm_image_file_set(bg, buf, NULL)) {
269                 _E("Failed to set image file : %s", buf);
270                 if (!elm_image_file_set(bg, util_get_file_path(IMAGE_DIR"/home_001.png"), NULL)) {
271                         _E("Failed to set default image file: %s", util_get_file_path(IMAGE_DIR"/home_001.png"));
272                         return;
273                 }
274         }
275
276         elm_win_resize_object_add(menu_screen_get_win(), bg);
277         evas_object_show(bg);
278
279         free(buf);
280 }
281
282
283
284
285 static void _destroy_bg()
286 {
287         Evas_Object *rect;
288         Evas_Object *bg;
289
290         rect = evas_object_data_del(menu_screen_get_win(), "rect");
291         evas_object_del(rect);
292
293         bg = evas_object_data_del(menu_screen_get_win(), "bg");
294         evas_object_del(bg);
295 }
296
297
298
299 static void _change_bg_cb(system_settings_key_e key, void *data)
300 {
301         _D("Background image is changed.");
302         _create_bg();
303 }
304
305
306
307 static void _init_theme(void)
308 {
309         menu_screen_info.theme = elm_theme_new();
310         elm_theme_ref_set(menu_screen_info.theme, NULL);
311         elm_theme_extension_add(menu_screen_info.theme, util_get_file_path(EDJE_DIR"/index.edj"));
312 }
313
314
315
316 static void _fini_theme(void)
317 {
318         elm_theme_extension_del(menu_screen_info.theme, util_get_file_path(EDJE_DIR"/index.edj"));
319         elm_theme_free(menu_screen_info.theme);
320         menu_screen_info.theme = NULL;
321
322 }
323
324
325
326 static Evas_Object *_create_conformant(Evas_Object *win)
327 {
328         Evas_Object *conformant;
329         char *device_profile;
330
331         conformant = elm_conformant_add(win);
332         retv_if(NULL == conformant, NULL);
333
334         evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
335         device_profile = util_get_device_profile();
336         if (device_profile) {
337                 if (!strcmp(device_profile, "mobile")) {
338                         elm_win_indicator_mode_set(menu_screen_info.win, ELM_WIN_INDICATOR_SHOW);
339                         elm_win_indicator_opacity_set(menu_screen_info.win, ELM_WIN_INDICATOR_TRANSLUCENT);
340                 }
341         }
342         elm_object_signal_emit(conformant, "elm,state,indicator,overlap", "elm");
343         evas_object_data_set(conformant, "win", win);
344         evas_object_show(conformant);
345
346         elm_win_resize_object_add(win, conformant);
347         elm_win_conformant_set(win, EINA_TRUE);
348
349         if (device_profile)
350                 free(device_profile);
351
352         return conformant;
353 }
354
355
356
357 static void _destroy_conformant(Evas_Object *conformant)
358 {
359         evas_object_data_del(conformant, "win");
360         evas_object_del(conformant);
361 }
362
363
364
365 static bool _create_cb(void *data)
366 {
367         Evas_Object *conformant;
368
369         _init_theme();
370         retv_if(MENU_SCREEN_ERROR_FAIL == _create_canvas(PACKAGE, PACKAGE), false);
371
372         if (system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN, _change_bg_cb, NULL) < 0) {
373                 _E("Failed to register a settings change cb for %d\n", SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN);
374         }
375         _create_bg();
376
377         conformant = _create_conformant(menu_screen_info.win);
378         retv_if(NULL == conformant, false);
379         evas_object_data_set(menu_screen_info.win, "conformant", conformant);
380
381         Evas_Object *layout;
382         layout = layout_create(conformant, util_get_file_path(EDJE_DIR"/layout_portrait.edj"), LAYOUT_GROUP_NAME, MENU_SCREEN_ROTATE_PORTRAIT);
383         if (NULL == layout) {
384                 _E("Failed to load an edje object");
385                 evas_object_del(menu_screen_info.win);
386                 return false;
387         }
388         evas_object_data_set(menu_screen_info.win, "layout", layout);
389
390         elm_object_content_set(conformant, layout);
391
392         mouse_register();
393         aul_listen_app_dead_signal(_dead_cb, NULL);
394         key_register();
395
396         // FIXME : This will be enabled after rebuilding the routine for appid <-> pkgid.
397         pkgmgr_init();
398
399         return true;
400 }
401
402
403
404 static void _terminate_cb(void *data)
405 {
406         Evas_Object *conformant;
407         Evas_Object *layout;
408
409         // FIXME : This will be enabled after rebuilding the routine for appid <-> pkgid.
410
411         if (system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN) < 0) {
412                 _E("Failed to remove bgset [%s]\n", SYSTEM_SETTINGS_KEY_WALLPAPER_HOME_SCREEN);
413         }
414
415         evas_object_hide(menu_screen_info.win);
416
417         key_unregister();
418         mouse_unregister();
419
420         layout = evas_object_data_del(menu_screen_info.win, "layout");
421         if (layout) layout_destroy(layout);
422
423         conformant = evas_object_data_del(menu_screen_info.win, "conformant");
424         if (conformant) _destroy_conformant(conformant);
425
426         _destroy_bg();
427         _destroy_canvas();
428         _fini_theme();
429         evas_object_del(menu_screen_info.win);
430 }
431
432
433
434 static void _pause_cb(void *data)
435 {
436         _D("Pause start");
437
438         menu_screen_info.state = APP_STATE_PAUSE;
439 }
440
441
442
443 static void _resume_cb(void *data)
444 {
445         _D("START RESUME");
446
447         do { // Focus
448                 Evas_Object *layout = evas_object_data_get(menu_screen_info.win, "layout");
449                 break_if(NULL == layout);
450
451                 Evas_Object *all_apps = evas_object_data_get(layout, "all_apps");
452                 break_if(NULL == all_apps);
453
454                 Evas_Object *scroller = elm_object_part_content_get(all_apps, "content");
455                 break_if(NULL == scroller);
456
457                 page_scroller_focus(scroller);
458         } while (0);
459
460         menu_screen_info.state = APP_STATE_RESUME;
461 }
462
463
464
465 static void _app_control_cb(app_control_h service, void *data)
466 {
467         _D("START RESET : %d", menu_screen_info.state);
468
469         do { // Focus
470                 Evas_Object *layout = evas_object_data_get(menu_screen_info.win, "layout");
471                 break_if(NULL == layout);
472
473                 Evas_Object *all_apps = evas_object_data_get(layout, "all_apps");
474                 break_if(NULL == all_apps);
475
476                 Evas_Object *scroller = elm_object_part_content_get(all_apps, "content");
477                 break_if(NULL == scroller);
478
479                 page_scroller_focus(scroller);
480         } while (0);
481 }
482
483
484
485 static void _language_changed_cb(app_event_info_h event_info, void *data)
486 {
487         register unsigned int i;
488         register unsigned int j;
489         unsigned int count;
490         Evas_Object *layout;
491         Evas_Object *all_apps;
492         Evas_Object *scroller;
493         Evas_Object *page;
494         Evas_Object *item;
495         unsigned int page_max_app;
496
497         _D("Language is changed");
498
499         if (false == menu_screen_info.is_done) {
500                 elm_exit();
501         }
502
503         layout = evas_object_data_get(menu_screen_info.win, "layout");
504         ret_if(NULL == layout);
505         all_apps = evas_object_data_get(layout, "all_apps");
506         ret_if(NULL == all_apps);
507         scroller = elm_object_part_content_get(all_apps, "content");
508         ret_if(NULL == scroller);
509
510         count = page_scroller_count_page(scroller);
511         page_max_app = (unsigned int) evas_object_data_get(scroller, "page_max_app");
512         for (i = 0; i < count; i++) {
513                 page = page_scroller_get_page_at(scroller, i);
514                 if (!page) continue;
515                 if (mapbuf_is_enabled(page)) {
516                         mapbuf_disable(page, 1);
517                 }
518
519                 for (j = 0; j < page_max_app; j++) {
520                         app_info_h app_info = NULL;
521                         char *name;
522                         int ret;
523                         char *package;
524
525                         item = page_get_item_at(page, j);
526                         if (!item) continue;
527
528                         package = item_get_package(item);
529                         if (!package) continue;
530
531                         ret = app_manager_get_app_info(package, &app_info);
532                         if (ret != APP_MANAGER_ERROR_NONE || !app_info) {
533                                 _E("Failed to get app info");
534                                 continue;
535                         }
536                         ret = app_info_get_label(app_info, &name);
537                         if (APP_MANAGER_ERROR_NONE != ret) {
538                                 _E("Failed to get label from : %s", item_get_package(item));
539                                 continue;
540                         }
541                         _D("Changed Language name: %s", name);
542                         
543
544                         item_set_name(item, name, 0);
545                 }
546
547                 mapbuf_enable(page, 1);
548         }
549 }
550
551
552
553 static void _init(ui_app_lifecycle_callback_s *lifecycle_callback, app_event_handler_h *event_handlers)
554 {
555         lifecycle_callback->create = _create_cb;
556         lifecycle_callback->terminate = _terminate_cb;
557         lifecycle_callback->pause = _pause_cb;
558         lifecycle_callback->resume = _resume_cb;
559         lifecycle_callback->app_control = _app_control_cb;
560
561         ui_app_add_event_handler(&event_handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, NULL, NULL);
562         ui_app_add_event_handler(&event_handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, NULL, NULL);
563         ui_app_add_event_handler(&event_handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, NULL, NULL);
564         ui_app_add_event_handler(&event_handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, _language_changed_cb, NULL);
565         ui_app_add_event_handler(&event_handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, NULL, NULL);
566
567 }
568
569
570
571 static void _fini(app_event_handler_h *event_handlers)
572 {
573         ui_app_remove_event_handler(event_handlers[APP_EVENT_LOW_BATTERY]);
574         ui_app_remove_event_handler(event_handlers[APP_EVENT_LOW_MEMORY]);
575         ui_app_remove_event_handler(event_handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED]);
576         ui_app_remove_event_handler(event_handlers[APP_EVENT_LANGUAGE_CHANGED]);
577         ui_app_remove_event_handler(event_handlers[APP_EVENT_REGION_FORMAT_CHANGED]);
578
579 }
580
581
582
583 int main(int argc, char *argv[])
584 {
585         ui_app_lifecycle_callback_s lifecycle_callback = {0, };
586         app_event_handler_h event_handlers[5] = {NULL, };
587
588         _init(&lifecycle_callback, event_handlers);
589         ui_app_main(argc, argv, &lifecycle_callback, NULL);
590         _fini(event_handlers);
591
592         return EXIT_SUCCESS;
593 }
594
595
596
597 // End of a file