Make boot-animation window as TOP to blocking the sudden appearence of the other app
[apps/native/boot-animation.git] / src / animation.c
1 /*
2  * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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 #include <vconf.h>
19 #include <efl_util.h>
20
21 #include "boot.h"
22 #include "animation.h"
23 #include "app_log.h"
24
25 static struct animation {
26         Evas_Object *win;
27         Evas_Object *layout;
28         Evas_Object *display_block;
29         Evas_Coord win_w;
30         Evas_Coord win_h;
31         int animation_type;
32 } s_animation = {
33         .win = NULL,
34         .layout = NULL,
35         .display_block = NULL,
36         .win_w = 0,
37         .win_h = 0,
38         .animation_type = 0,
39 };
40
41 static void __visibility_changed_cb(void *data, Evas_Object *obj, void *event)
42 {
43         __D("Visibility changed");
44         int visibility = (int)(void *)event;
45
46         if (!visibility)
47                 boot_exit();
48 }
49
50
51 static void __win_del_cb(void *data, Evas_Object * obj, void *event_info)
52 {
53         __D("Window delete event received");
54         elm_exit();
55 }
56
57 static Evas_Object *__create_window(void)
58 {
59         __D("Create Window");
60
61         Evas_Object *win;
62
63         win = elm_win_add(NULL, "BOOT_ANIMATION", ELM_WIN_NOTIFICATION);
64         if (!win) {
65                 __E("Failed to create a new window");
66                 return NULL;
67         }
68         elm_win_role_set(win, "alert");
69         efl_util_set_notification_window_level(win, EFL_UTIL_NOTIFICATION_LEVEL_TOP);
70         evas_object_smart_callback_add(s_animation.win, "visibility,changed", __visibility_changed_cb, NULL);
71         elm_win_aux_hint_add(win, "wm.comp.win.always.selective.mode", "0");
72         evas_object_smart_callback_add(win, "delete-request", __win_del_cb, NULL);
73
74         elm_win_screen_size_get(win, NULL, NULL, &s_animation.win_w, &s_animation.win_h);
75         elm_win_borderless_set(win, EINA_TRUE);
76         elm_win_indicator_mode_set(win, ELM_WIN_INDICATOR_HIDE);
77         evas_object_move(win, 0, 0);
78         evas_object_show(win);
79
80         return win;
81 }
82
83 static void __block_display(void)
84 {
85         Evas_Object *display_block = NULL;
86         display_block = evas_object_rectangle_add(evas_object_evas_get(s_animation.win));
87         elm_win_resize_object_add(s_animation.win, display_block);
88         evas_object_color_set(display_block, 0, 0, 0, 255);
89         evas_object_show(display_block);
90
91         s_animation.display_block = display_block;
92 }
93
94 static Eina_Bool __end_cb(void *data)
95 {
96         int type = (int) data;
97
98         if (type == TYPE_OFF) {
99                 __D("EXIT on SHUTDOWN");
100                 /* Delete Previous Layout */
101                 if (s_animation.layout) {
102                         evas_object_del(s_animation.layout);
103                         s_animation.layout = NULL;
104                 }
105
106                 /* boot-animation do not terminate on shutdown, so flush log now */
107                 fflush(stdout);
108                 close(1);
109
110                 __block_display();
111         } else {
112                 __D("EXIT on BOOTING");
113                 boot_exit();
114         }
115         return ECORE_CALLBACK_CANCEL;
116 }
117
118 static void __animation_finished_cb(void *d, Evas_Object * obj, const char *e, const char *s)
119 {
120         if (s_animation.animation_type == TYPE_OFF) {
121                 __D("TYPE OFF");
122                 ecore_timer_add(1, __end_cb, (void *)TYPE_OFF);
123         } else {
124                 __D("TYPE_ON");
125                 efl_util_set_notification_window_level(s_animation.win, EFL_UTIL_NOTIFICATION_LEVEL_NONE);
126                 ecore_timer_add(10, __end_cb, (void *)TYPE_ON);
127         }
128
129         if (vconf_set_int(VCONFKEY_BOOT_ANIMATION_FINISHED, 1) != 0)
130                 __E("Failed to set finished set");
131 }
132
133 static Evas_Object * __create_layout(Evas_Object *win, const char *file_name)
134 {
135         Evas_Object *layout = elm_layout_add(win);
136         if (!layout) {
137                 __E("Failed to create layout");
138                 return NULL;
139         }
140         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
141         elm_win_resize_object_add(s_animation.win, layout);
142         elm_layout_signal_callback_add(layout, "end", "animation", __animation_finished_cb, NULL);
143
144         if (!elm_layout_file_set(layout, file_name, GRP_ANIM)) {
145                 __E("Failed to layout file set");
146                 return NULL;
147         }
148
149         evas_object_show(layout);
150
151         return layout;
152 }
153
154 static void __destroy_layout(void)
155 {
156         if (s_animation.display_block) {
157                 evas_object_del(s_animation.display_block);
158                 s_animation.display_block = NULL;
159         }
160
161         if (s_animation.layout) {
162                 evas_object_del(s_animation.layout);
163                 s_animation.layout = NULL;
164         }
165 }
166
167 static char * __get_layout_file_name(int animation_type, int w, int h)
168 {
169         char file_name[1024];
170         int ret = 0;
171
172         if (animation_type == TYPE_OFF)
173                 snprintf(file_name, sizeof(file_name), FILE_PATH"%dx%d_PowerOff.edj", w, h);
174         else
175                 snprintf(file_name, sizeof(file_name), FILE_PATH"%dx%d_PowerOn.edj", w, h);
176
177         __D("File name for Animation is: %s", file_name);
178
179         ret = access(file_name, 0);
180         if (ret != 0) {
181                 __E("There's no Image same with [%s], So set Default[720x1280] image", file_name);
182                 if (animation_type == TYPE_OFF)
183                         snprintf(file_name, sizeof(file_name), "%s", DEFAULT_OFF);
184                 else
185                         snprintf(file_name, sizeof(file_name), "%s", DEFAULT_ON);
186
187                 ret = access(file_name, 0);
188                 if (ret) {
189                         __E("There's no Image file[%s] on target", file_name);
190                         return NULL;
191                 }
192         }
193
194         return strdup(file_name);
195 }
196
197 static Eina_Bool __is_layout_file_exist(const char *file_name)
198 {
199         int ret = 0;
200
201         ret = access(file_name, 0);
202         if (ret == 0)
203                 return EINA_TRUE;
204         else
205                 return EINA_FALSE;
206 }
207
208 int animation_init(int animation_type)
209 {
210         __D("Init animation");
211
212         s_animation.animation_type = animation_type;
213
214         s_animation.win = __create_window();
215         if (!s_animation.win) {
216                 __E("Failed to create a new window");
217                 return EXIT_FAILURE;
218         }
219
220         char *layout_file_name = NULL;
221         layout_file_name = __get_layout_file_name(animation_type, s_animation.win_w, s_animation.win_h);
222         if (!layout_file_name) {
223                 __E("Failed to get layout file name");
224                 return EXIT_FAILURE;
225         }
226
227         if (!__is_layout_file_exist(layout_file_name)) {
228                 __E("This file is not exist");
229                 free(layout_file_name);
230                 return EXIT_FAILURE;
231         }
232
233         s_animation.layout = __create_layout(s_animation.win, layout_file_name);
234         if (!s_animation.layout) {
235                 __E("Failed to create layout");
236                 free(layout_file_name);
237                 evas_object_del(s_animation.win);
238                 return EXIT_FAILURE;
239         }
240
241         free(layout_file_name);
242
243         return EXIT_SUCCESS;
244 }
245
246 int animation_fini(void)
247 {
248         __destroy_layout();
249
250         evas_object_del(s_animation.win);
251         fflush(stdout);
252         close(1);
253         return EXIT_SUCCESS;
254 }
255
256 #include "test.h"
257 #if TEST_MODE
258 Evas_Object *__t__get_window(void)
259 {
260         return s_animation.win;
261 }
262
263 Evas_Object *__t__get_layout(void)
264 {
265         return s_animation.layout;
266 }
267
268 Evas_Object *__t__get_display_block(void)
269 {
270         return s_animation.display_block;
271 }
272
273 Evas_Object * __t__animation_create_layout(Evas_Object *win, const char *file_name)
274 {
275         return __create_layout(win, file_name);
276 }
277
278 Evas_Object *__t__animation_create_window(void)
279 {
280         return __create_window();
281 }
282
283 char * __t__get_layout_file_name(int animation_type, int w, int h)
284 {
285         return __get_layout_file_name(animation_type, w, h);
286 }
287
288 Eina_Bool __t__is_layout_file_exist(const char *file_name)
289 {
290         return __is_layout_file_exist(file_name);
291 }
292 #endif