ea5eabf47cdb904ab3666e2b2387b9a45314e8ed
[framework/appfw/app-core.git] / src / appcore-efl.c
1 /*
2  *  app-core
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/un.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <stdarg.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <X11/Xatom.h>
32 #include <X11/Xlib.h>
33 #include <X11/Xutil.h>
34 #include <X11/extensions/Xcomposite.h>
35 #include <X11/extensions/XShm.h>
36 #include <sys/shm.h>
37 #ifdef WEARABLE
38 #include <proc_stat.h>
39 #endif
40
41 #include <Ecore_X.h>
42 #include <Ecore.h>
43 #include <Ecore_Evas.h>
44 #include <Evas.h>
45 #include <Ecore_Input_Evas.h>
46 #include <Elementary.h>
47 #include <glib-object.h>
48 #include <malloc.h>
49 #include <glib.h>
50 #include <stdbool.h>
51 #include <aul.h>
52 #include "appcore-internal.h"
53 #include "appcore-efl.h"
54 #include "virtual_canvas.h"
55 #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS
56 #include <vconf/vconf.h>
57 #endif
58
59 #define SYSMAN_MAXSTR 100
60 #define SYSMAN_MAXARG 16
61 #define SYSNOTI_SOCKET_PATH "/tmp/sn"
62 #define RETRY_READ_COUNT        10
63 #define MAX_PACKAGE_STR_SIZE 512
64
65 #define PREDEF_BACKGRD                          "backgrd"
66 #define PREDEF_FOREGRD                          "foregrd"
67
68 enum sysnoti_cmd {
69         ADD_SYSMAN_ACTION,
70         CALL_SYSMAN_ACTION
71 };
72
73 struct sysnoti {
74         int pid;
75         int cmd;
76         char *type;
77         char *path;
78         int argc;
79         char *argv[SYSMAN_MAXARG];
80 };
81
82 static pid_t _pid;
83
84 static bool resource_reclaiming = TRUE;
85 static bool prelaunching = FALSE;
86
87
88
89 struct ui_priv {
90         const char *name;
91         enum app_state state;
92
93         Ecore_Event_Handler *hshow;
94         Ecore_Event_Handler *hhide;
95         Ecore_Event_Handler *hvchange;
96         Ecore_Event_Handler *hcmsg; /* WM_ROTATE */
97
98         Ecore_Timer *mftimer;   /* Ecore Timer for memory flushing */
99
100         struct appcore_ops *ops;
101         void (*mfcb) (void);    /* Memory Flushing Callback */
102
103         /* WM_ROTATE */
104         int wm_rot_supported;
105         int rot_started;
106         int (*rot_cb) (void *event_info, enum appcore_rm, void *);
107         void *rot_cb_data;
108         enum appcore_rm rot_mode;
109 };
110
111 static struct ui_priv priv;
112
113 static const char *_ae_name[AE_MAX] = {
114         [AE_UNKNOWN] = "UNKNOWN",
115         [AE_CREATE] = "CREATE",
116         [AE_TERMINATE] = "TERMINATE",
117         [AE_PAUSE] = "PAUSE",
118         [AE_RESUME] = "RESUME",
119         [AE_RESET] = "RESET",
120         [AE_LOWMEM_POST] = "LOWMEM_POST",
121         [AE_MEM_FLUSH] = "MEM_FLUSH",
122 };
123
124 static const char *_as_name[] = {
125         [AS_NONE] = "NONE",
126         [AS_CREATED] = "CREATED",
127         [AS_RUNNING] = "RUNNING",
128         [AS_PAUSED] = "PAUSED",
129         [AS_DYING] = "DYING",
130 };
131
132 static int b_active = -1;
133 static bool first_launch = 1;
134 static int is_legacy_lifecycle = 0;
135
136 struct win_node {
137         unsigned int win;
138         bool bfobscured;
139 };
140
141 static struct ui_wm_rotate wm_rotate;
142
143 static inline int send_int(int fd, int val)
144 {
145         return write(fd, &val, sizeof(int));
146 }
147
148 static inline int send_str(int fd, char *str)
149 {
150         int len;
151         int ret;
152         if (str == NULL) {
153                 len = 0;
154                 ret = write(fd, &len, sizeof(int));
155         } else {
156                 len = strlen(str);
157                 if (len > SYSMAN_MAXSTR)
158                         len = SYSMAN_MAXSTR;
159                 write(fd, &len, sizeof(int));
160                 ret = write(fd, str, len);
161         }
162         return ret;
163 }
164
165 static int sysnoti_send(struct sysnoti *msg)
166 {
167         int client_len;
168         int client_sockfd;
169         int result;
170         int r;
171         int retry_count = 0;
172         struct sockaddr_un clientaddr;
173         int i;
174
175         client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
176         if (client_sockfd == -1) {
177                 _ERR("%s: socket create failed\n", __FUNCTION__);
178                 return -1;
179         }
180         bzero(&clientaddr, sizeof(clientaddr));
181         clientaddr.sun_family = AF_UNIX;
182         strncpy(clientaddr.sun_path, SYSNOTI_SOCKET_PATH, sizeof(clientaddr.sun_path) - 1);
183         client_len = sizeof(clientaddr);
184
185         if (connect(client_sockfd, (struct sockaddr *)&clientaddr, client_len) <
186             0) {
187                 _ERR("%s: connect failed\n", __FUNCTION__);
188                 close(client_sockfd);
189                 return -1;
190         }
191
192         send_int(client_sockfd, msg->pid);
193         send_int(client_sockfd, msg->cmd);
194         send_str(client_sockfd, msg->type);
195         send_str(client_sockfd, msg->path);
196         send_int(client_sockfd, msg->argc);
197         for (i = 0; i < msg->argc; i++)
198                 send_str(client_sockfd, msg->argv[i]);
199
200         while (retry_count < RETRY_READ_COUNT) {
201                 r = read(client_sockfd, &result, sizeof(int));
202                 if (r < 0) {
203                         if (errno == EINTR) {
204                                 _ERR("Re-read for error(EINTR)");
205                                 retry_count++;
206                                 continue;
207                         }
208                         _ERR("Read fail for str length");
209                         result = -1;
210                         break;
211
212                 }
213                 break;
214         }
215         if (retry_count == RETRY_READ_COUNT) {
216                 _ERR("Read retry failed");
217         }
218
219         close(client_sockfd);
220         return result;
221 }
222
223 void __trm_app_info_send_socket(char *write_buf)
224 {
225         const char trm_socket_for_app_info[] = "/dev/socket/app_info";
226         int socket_fd = 0;
227         int ret = 0;
228         struct sockaddr_un addr;
229
230         _DBG("__trm_app_info_send_socket");
231
232         if (access(trm_socket_for_app_info, F_OK) != 0) {
233                 _ERR("access");
234                 goto trm_end;
235         }
236
237         socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
238         if (socket_fd < 0) {
239                 _ERR("socket");
240                 goto trm_end;
241         }
242
243         memset(&addr, 0, sizeof(addr));
244         sprintf(addr.sun_path, "%s", trm_socket_for_app_info);
245         addr.sun_family = AF_LOCAL;
246
247         ret = connect(socket_fd, (struct sockaddr *) &addr ,sizeof(sa_family_t) + strlen(trm_socket_for_app_info) );
248         if (ret != 0) {
249                 close(socket_fd);
250                 goto trm_end;
251         }
252
253         send(socket_fd, write_buf, strlen(write_buf), MSG_DONTWAIT | MSG_NOSIGNAL);
254         _DBG("send");
255
256         close(socket_fd);
257 trm_end:
258         return;
259 }
260
261 #ifdef _APPFW_FEATURE_CPU_BOOST
262 static void __stop_cpu_boost(void)
263 {
264         const char trm_sock_for_cpu_boost[] = "/dev/socket/scenario_info";
265         int sock_fd = 0;
266         int ret = 0;
267         struct sockaddr_un addr;
268         const char command[] = "AppLaunchUnlock";
269
270         _DBG("__stop_cpu_boost enter");
271
272         if (access(trm_sock_for_cpu_boost, F_OK) != 0) {
273                 _ERR("access() failed, errno: %d (%s)", errno, strerror(errno));
274                 goto error;
275         }
276
277         sock_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
278         if (sock_fd < 0) {
279                 _ERR("socket() failed, errno: %d (%s)", errno, strerror(errno));
280                 goto error;
281         }
282
283         memset(&addr, 0, sizeof(addr));
284         sprintf(addr.sun_path, "%s", trm_sock_for_cpu_boost);
285         addr.sun_family = AF_LOCAL;
286
287         ret = connect(sock_fd, (struct sockaddr *) &addr, sizeof(sa_family_t) + strlen(trm_sock_for_cpu_boost));
288         if (ret != 0) {
289                 _ERR("connect() failed, errno: %d (%s)", errno, strerror(errno));
290                 close(sock_fd);
291                 goto error;
292         }
293
294         ret = send(sock_fd, command, strlen(command), MSG_DONTWAIT | MSG_NOSIGNAL);
295         if (ret < 0) {
296                 _ERR("send() failed, errno: %d (%s)", errno, strerror(errno));
297                 close(sock_fd);
298                 goto error;
299         }
300
301         close(sock_fd);
302         _DBG("__stop_cpu_boost ok");
303
304 error:
305         return;
306 }
307 #endif
308
309 static int _call_predef_action(const char *type, int num, ...)
310 {
311         struct sysnoti *msg;
312         int ret;
313         va_list argptr;
314
315         int i;
316         char *args = NULL;
317
318         if (type == NULL || num > SYSMAN_MAXARG) {
319                 errno = EINVAL;
320                 return -1;
321         }
322
323         msg = malloc(sizeof(struct sysnoti));
324
325         if (msg == NULL) {
326                 /* Do something for not enought memory error */
327                 return -1;
328         }
329
330         msg->pid = getpid();
331         msg->cmd = CALL_SYSMAN_ACTION;
332         msg->type = (char *)type;
333         msg->path = NULL;
334
335         msg->argc = num;
336         va_start(argptr, num);
337         for (i = 0; i < num; i++) {
338                 args = va_arg(argptr, char *);
339                 msg->argv[i] = args;
340         }
341         va_end(argptr);
342
343         ret = sysnoti_send(msg);
344         free(msg);
345
346         return ret;
347 }
348
349 static int _inform_foregrd(void)
350 {
351         char buf[255];
352         snprintf(buf, sizeof(buf), "%d", getpid());
353         return _call_predef_action(PREDEF_FOREGRD, 1, buf);
354 }
355
356 static int _inform_backgrd(void)
357 {
358         char buf[255];
359         snprintf(buf, sizeof(buf), "%d", getpid());
360         return _call_predef_action(PREDEF_BACKGRD, 1, buf);
361 }
362
363
364
365 char appid[APPID_MAX];
366
367 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
368 bool taskmanage;
369 static void _capture_and_make_file(Ecore_X_Window win, int pid, const char *package);
370 #endif
371
372 static bool __check_skip(Ecore_X_Window xwin);
373
374
375 static int WIN_COMP(gconstpointer data1, gconstpointer data2)
376 {
377         struct win_node *a = (struct win_node *)data1;
378         struct win_node *b = (struct win_node *)data2;
379         return (int)((a->win)-(b->win));
380 }
381
382 GSList *g_winnode_list = NULL;
383
384 #if defined(MEMORY_FLUSH_ACTIVATE)
385 static Eina_Bool __appcore_memory_flush_cb(void *data)
386 {
387         struct ui_priv *ui = (struct ui_priv *)data;
388
389         appcore_flush_memory();
390         ui->mftimer = NULL;
391
392         return ECORE_CALLBACK_CANCEL;
393 }
394
395 static int __appcore_low_memory_post_cb(struct ui_priv *ui)
396 {
397         if (ui->state == AS_PAUSED) {
398         //      appcore_flush_memory();
399         } else {
400                 malloc_trim(0);
401         }
402
403         return 0;
404 }
405
406 static void __appcore_timer_add(struct ui_priv *ui)
407 {
408         ui->mftimer = ecore_timer_add(5, __appcore_memory_flush_cb, ui);
409 }
410
411 static void __appcore_timer_del(struct ui_priv *ui)
412 {
413         if (ui->mftimer) {
414                 ecore_timer_del(ui->mftimer);
415                 ui->mftimer = NULL;
416         }
417 }
418
419 #else
420
421 static int __appcore_low_memory_post_cb(ui_priv *ui)
422 {
423         return -1;
424 }
425
426 #define __appcore_timer_add(ui) 0
427 #define __appcore_timer_del(ui) 0
428
429 #endif
430
431 static void __appcore_efl_memory_flush_cb(void)
432 {
433         //_DBG("[APP %d]   __appcore_efl_memory_flush_cb()", _pid);
434         elm_cache_all_flush();
435 }
436
437 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
438 static Eina_Bool __appcore_mimiapp_capture_cb(void *data)
439 {
440         GSList *iter = NULL;
441         struct win_node *entry = NULL;
442
443         for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) {
444                 entry = iter->data;
445                 if(__check_skip(entry->win) == FALSE)
446                         break;
447         }
448         if(iter) {
449                 entry = iter->data;
450                 if(taskmanage) {
451                         _capture_and_make_file(entry->win, getpid(), appid);
452                 }
453         }
454
455         return ECORE_CALLBACK_CANCEL;
456 }
457 #endif
458
459 static void __do_app(enum app_event event, void *data, bundle * b)
460 {
461         int r = -1;
462         struct ui_priv *ui = data;
463         char trm_buf[MAX_PACKAGE_STR_SIZE];
464 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
465         const char *miniapp = NULL;
466 #endif
467
468         _ret_if(ui == NULL || event >= AE_MAX);
469         _DBG("[APP %d] Event: %s State: %s", _pid, _ae_name[event],
470              _as_name[ui->state]);
471
472         if (event == AE_MEM_FLUSH) {
473                 ui->mfcb();
474                 return;
475         }
476
477         if (event == AE_LOWMEM_POST) {
478                 if (__appcore_low_memory_post_cb(ui) == 0)
479                         return;
480         }
481
482         if (!(ui->state == AS_PAUSED && event == AE_PAUSE))
483                 __appcore_timer_del(ui);
484
485         if (event == AE_TERMINATE) {
486                 _DBG("[APP %d] TERMINATE", _pid);
487                 ui->state = AS_DYING;
488                 elm_exit();
489                 return;
490         }
491
492         _ret_if(ui->ops == NULL);
493
494         switch (event) {
495         case AE_RESET:
496                 _DBG("[APP %d] RESET", _pid);
497                 LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:start]",
498                         ui->name);
499                 if (ui->ops->reset)
500                         r = ui->ops->reset(b, ui->ops->data);
501                 LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:reset:done]", ui->name);
502
503                 if(first_launch) {
504                         first_launch = 0;
505                         is_legacy_lifecycle = aul_get_support_legacy_lifecycle();
506
507                         _INFO("Legacy lifecycle: %d", is_legacy_lifecycle);
508                         if (!is_legacy_lifecycle) {
509                                 _INFO("[APP %d] Initial Launching, call the resume_cb", _pid);
510                                 if (ui->ops->resume)
511                                         r = ui->ops->resume(ui->ops->data);
512                         }
513                 } else {
514                         _INFO("Legacy lifecycle: %d", is_legacy_lifecycle);
515                         if (!is_legacy_lifecycle) {
516                                 _INFO("[APP %d] App already running, raise the window", _pid);
517                                 x_raise_win(getpid());
518
519                                 if (ui->state == AS_PAUSED) {
520                                         _INFO("[APP %d] Call the resume_cb", _pid);
521                                         if (ui->ops->resume)
522                                                 r = ui->ops->resume(ui->ops->data);
523                                 }
524                         }
525                 }
526
527                 ui->state = AS_RUNNING;
528
529 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
530                 miniapp = bundle_get_val(b, "http://tizen.org/appcontrol/data/miniapp");
531                 if(miniapp && strncmp(miniapp, "on", 2) == 0) {
532                         ecore_timer_add(0.5, __appcore_mimiapp_capture_cb, NULL);
533                 }
534 #endif
535                 break;
536         case AE_PAUSE:
537                 if (ui->state == AS_RUNNING) {
538                         _DBG("[APP %d] PAUSE", _pid);
539                         if (ui->ops->pause)
540                                 r = ui->ops->pause(ui->ops->data);
541                         ui->state = AS_PAUSED;
542                         if(r >= 0 && resource_reclaiming == TRUE)
543                                 __appcore_timer_add(ui);
544                 }
545                 /* TODO : rotation stop */
546                 //r = appcore_pause_rotation_cb();
547
548                 snprintf(trm_buf, MAX_PACKAGE_STR_SIZE, "appinfo_pause:[PID]%d", getpid());
549                 __trm_app_info_send_socket(trm_buf);
550 #ifdef WEARABLE
551                 proc_group_change_status(PROC_CGROUP_SET_BACKGRD, getpid(), NULL);
552 #endif
553                 //_inform_backgrd();
554                 break;
555         case AE_RESUME:
556                 LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:start]",
557                     ui->name);
558                 if (ui->state == AS_PAUSED) {
559                         _DBG("[APP %d] RESUME", _pid);
560                         if (ui->ops->resume)
561                                 r = ui->ops->resume(ui->ops->data);
562                         ui->state = AS_RUNNING;
563                 }
564                 /*TODO : rotation start*/
565                 //r = appcore_resume_rotation_cb();
566                 LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:done]",
567                     ui->name);
568                 LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:Launching:done]",
569                     ui->name);
570
571 #ifdef _GATE_TEST_ENABLE
572                 if(strncmp(ui->name, "wrt-client", 10) != 0) {
573                         LOG(LOG_DEBUG, "GATE-M", "<GATE-M>APP_FULLY_LOADED_%s<GATE-M>", ui->name);
574                 }
575 #endif
576
577 #ifdef WEARABLE
578                 proc_group_change_status(PROC_CGROUP_SET_FOREGRD, getpid(), NULL);
579 #endif
580                 snprintf(trm_buf, MAX_PACKAGE_STR_SIZE,"appinfo_resume:[PID]%d", getpid());
581                 __trm_app_info_send_socket(trm_buf);
582 #ifdef _APPFW_FEATURE_CPU_BOOST
583                 __stop_cpu_boost();
584 #endif
585                 //_inform_foregrd();
586
587                 break;
588         default:
589                 /* do nothing */
590                 break;
591         }
592 }
593
594 static struct ui_ops efl_ops = {
595         .data = &priv,
596         .cb_app = __do_app,
597 };
598
599
600 static bool __check_visible(void)
601 {
602         GSList *iter = NULL;
603         struct win_node *entry = NULL;
604
605         for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) {
606                 entry = iter->data;
607                 //_DBG("win : %x obscured : %d\n", entry->win, entry->bfobscured);
608                 if(entry->bfobscured == FALSE)
609                         return TRUE;
610         }
611         return FALSE;
612 }
613
614 static bool __check_skip(Ecore_X_Window xwin)
615 {
616         unsigned int i, num;
617         Ecore_X_Window_State *state;
618         int ret;
619
620         ret = ecore_x_netwm_window_state_get(xwin, &state, &num);
621         _DBG("ret(%d), win(%x), state(%x), num(%d)", ret, xwin, state, num);
622         if (state) {
623                 for (i = 0; i < num; i++) {
624                         _DBG("state[%d] : %d", i, state[i]);
625                         switch (state[i]) {
626                                 case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
627                                         free(state);
628                                         return TRUE;
629                                         break;
630                                 case ECORE_X_WINDOW_STATE_SKIP_PAGER:
631                                         free(state);
632                                         return TRUE;
633                                         break;
634                                 default:
635                                         /* Ignore */
636                                         break;
637                         }
638                 }
639         }
640         free(state);
641         return FALSE;
642 }
643
644 static bool __exist_win(unsigned int win)
645 {
646         struct win_node temp;
647         GSList *f;
648
649         temp.win = win;
650
651         f = g_slist_find_custom(g_winnode_list, &temp, WIN_COMP);
652         if (f == NULL) {
653                 return FALSE;
654         } else {
655                 return TRUE;
656         }
657
658 }
659
660 static bool __add_win(unsigned int win)
661 {
662         struct win_node *t;
663         GSList *f;
664
665         t = calloc(1, sizeof(struct win_node));
666         if (t == NULL)
667                 return FALSE;
668
669         t->win = win;
670         t->bfobscured = TRUE;
671
672         _DBG("[EVENT_TEST][EVENT] __add_win WIN:%x\n", win);
673
674         f = g_slist_find_custom(g_winnode_list, t, WIN_COMP);
675
676         if (f) {
677                 errno = ENOENT;
678                 _DBG("[EVENT_TEST][EVENT] ERROR There is already window : %x \n", win);
679                 free(t);
680                 return 0;
681         }
682
683         g_winnode_list = g_slist_append(g_winnode_list, t);
684
685         return TRUE;
686
687 }
688
689 static bool __delete_win(unsigned int win)
690 {
691         struct win_node temp;
692         GSList *f;
693
694         temp.win = win;
695
696         f = g_slist_find_custom(g_winnode_list, &temp, WIN_COMP);
697         if (f == NULL) {
698                 errno = ENOENT;
699                 _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n",
700                      win);
701                 return 0;
702         }
703
704         free(f->data);
705         g_winnode_list = g_slist_delete_link(g_winnode_list, f);
706
707         return TRUE;
708 }
709
710 static bool __update_win(unsigned int win, bool bfobscured)
711 {
712         struct win_node temp;
713         GSList *f;
714
715         struct win_node *t;
716
717         _DBG("[EVENT_TEST][EVENT] __update_win WIN:%x fully_obscured %d\n", win,
718              bfobscured);
719
720         temp.win = win;
721
722         f = g_slist_find_custom(g_winnode_list, &temp, WIN_COMP);
723
724         if (f == NULL) {
725                 errno = ENOENT;
726                 _DBG("[EVENT_TEST][EVENT] ERROR There is no window : %x \n", win);
727                 return FALSE;
728         }
729
730         free(f->data);
731         g_winnode_list = g_slist_delete_link(g_winnode_list, f);
732
733         t = calloc(1, sizeof(struct win_node));
734         if (t == NULL)
735                 return FALSE;
736
737         t->win = win;
738         t->bfobscured = bfobscured;
739
740         g_winnode_list = g_slist_append(g_winnode_list, t);
741
742         return TRUE;
743
744 }
745
746 /* WM_ROTATE */
747 static Ecore_X_Atom _WM_WINDOW_ROTATION_SUPPORTED = 0;
748 static Ecore_X_Atom _WM_WINDOW_ROTATION_CHANGE_REQUEST = 0;
749
750 static int __check_wm_rotation_support(void)
751 {
752         _DBG("Disable window manager rotation");
753         return -1;
754 #if 0
755         Ecore_X_Window root, win, win2;
756         int ret;
757
758         if (!_WM_WINDOW_ROTATION_SUPPORTED) {
759                 _WM_WINDOW_ROTATION_SUPPORTED =
760                                         ecore_x_atom_get("_E_WINDOW_ROTATION_SUPPORTED");
761         }
762
763         if (!_WM_WINDOW_ROTATION_CHANGE_REQUEST) {
764                 _WM_WINDOW_ROTATION_CHANGE_REQUEST =
765                                         ecore_x_atom_get("_E_WINDOW_ROTATION_CHANGE_REQUEST");
766         }
767
768         root = ecore_x_window_root_first_get();
769         ret = ecore_x_window_prop_xid_get(root,
770                         _WM_WINDOW_ROTATION_SUPPORTED,
771                         ECORE_X_ATOM_WINDOW,
772                         &win, 1);
773         if ((ret == 1) && (win))
774         {
775                 ret = ecore_x_window_prop_xid_get(win,
776                                 _WM_WINDOW_ROTATION_SUPPORTED,
777                                 ECORE_X_ATOM_WINDOW,
778                                 &win2, 1);
779                 if ((ret == 1) && (win2 == win))
780                         return 0;
781         }
782
783         return -1;
784 #endif
785 }
786
787 static void __set_wm_rotation_support(unsigned int win, unsigned int set)
788 {
789         GSList *iter = NULL;
790         struct win_node *entry = NULL;
791
792         if (0 == win) {
793                 for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) {
794                         entry = iter->data;
795                         if (entry->win) {
796                                 ecore_x_window_prop_card32_set(entry->win,
797                                                 _WM_WINDOW_ROTATION_SUPPORTED,
798                                                 &set, 1);
799                         }
800                 }
801         } else {
802                 ecore_x_window_prop_card32_set(win,
803                                 _WM_WINDOW_ROTATION_SUPPORTED,
804                                 &set, 1);
805         }
806 }
807
808 Ecore_X_Atom atom_parent;
809 Ecore_X_Atom xsend_Atom;
810
811 static Eina_Bool __show_cb(void *data, int type, void *event)
812 {
813         Ecore_X_Event_Window_Show *ev;
814         int ret;
815         Ecore_X_Window parent;
816
817         ev = event;
818
819         ret = ecore_x_window_prop_window_get(ev->win, atom_parent, &parent, 1);
820         if (ret != 1)
821         {
822                 // This is child window. Skip!!!
823                 return ECORE_CALLBACK_PASS_ON;
824         }
825
826         _DBG("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN:%x\n", ev->win);
827
828         if (!__exist_win((unsigned int)ev->win)) {
829                 /* WM_ROTATE */
830                 if ((priv.wm_rot_supported) && (1 == priv.rot_started)) {
831                         __set_wm_rotation_support(ev->win, 1);
832                 }
833                 __add_win((unsigned int)ev->win);
834         }
835         else
836                 __update_win((unsigned int)ev->win, FALSE);
837
838         return ECORE_CALLBACK_RENEW;
839 }
840
841 static Eina_Bool __hide_cb(void *data, int type, void *event)
842 {
843         Ecore_X_Event_Window_Hide *ev;
844         int bvisibility = 0;
845
846         ev = event;
847
848         _DBG("[EVENT_TEST][EVENT] GET HIDE EVENT!!!. WIN:%x\n", ev->win);
849
850         if (__exist_win((unsigned int)ev->win)) {
851                 __delete_win((unsigned int)ev->win);
852
853                 bvisibility = __check_visible();
854                 if (!bvisibility && b_active != 0) {
855                         _DBG(" Go to Pasue state \n");
856                         b_active = 0;
857                         __do_app(AE_PAUSE, data, NULL);
858 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
859                         if(taskmanage) {
860                                 _capture_and_make_file(ev->win, getpid(), appid);
861                         } else if ( aul_is_subapp() ) {
862                                 _capture_and_make_file(ev->win, getpid(), appcore_get_caller_appid());
863                         }
864 #endif
865                 }
866         }
867
868         return ECORE_CALLBACK_RENEW;
869 }
870
871 static Eina_Bool __visibility_cb(void *data, int type, void *event)
872 {
873         Ecore_X_Event_Window_Visibility_Change *ev;
874         int bvisibility = 0;
875 #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS
876         int lcd_status = 0;
877 #endif
878
879         ev = event;
880
881         __update_win((unsigned int)ev->win, ev->fully_obscured);
882         bvisibility = __check_visible();
883
884         _DBG("bvisibility %d, b_active %d", bvisibility, b_active);
885
886         if (bvisibility && b_active != 1) {
887                 _DBG(" Go to Resume state\n");
888                 b_active = 1;
889
890 #ifdef _APPFW_FEATURE_VISIBILITY_CHECK_BY_LCD_STATUS
891                 vconf_get_int(VCONFKEY_PM_STATE, &lcd_status);
892                 if(lcd_status == VCONFKEY_PM_STATE_LCDOFF) {
893                         return ECORE_CALLBACK_RENEW;
894                 }
895 #endif
896                 __do_app(AE_RESUME, data, NULL);
897         } else if (!bvisibility && (b_active != 0)) {
898                 _DBG(" Go to Pasue state \n");
899                 b_active = 0;
900                 __do_app(AE_PAUSE, data, NULL);
901 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
902                 if(taskmanage) {
903                         _capture_and_make_file(ev->win, getpid(), appid);
904                 } else if ( aul_is_subapp() ) {
905                         _capture_and_make_file(ev->win, getpid(), appcore_get_caller_appid());
906                 }
907 #endif
908         } else
909                 _DBG(" No change state \n");
910
911         return ECORE_CALLBACK_RENEW;
912
913 }
914
915 /* WM_ROTATE */
916 static Eina_Bool __cmsg_cb(void *data, int type, void *event)
917 {
918         struct ui_priv *ui = (struct ui_priv *)data;
919         Ecore_X_Event_Client_Message *e = event;
920
921 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
922         if (e->message_type == xsend_Atom) {
923                 _DBG("_E_ILLUME_ATOM_APPCORE_RECAPTURE_REQUEST win(%x)", e->win);
924                 _capture_and_make_file(e->win, getpid(), appid);
925                 return ECORE_CALLBACK_PASS_ON;
926         }
927 #endif
928
929         if (!ui) return ECORE_CALLBACK_PASS_ON;
930         if (e->format != 32) return ECORE_CALLBACK_PASS_ON;
931         if (e->message_type == _WM_WINDOW_ROTATION_CHANGE_REQUEST) {
932                 if ((0 == ui->wm_rot_supported) ||
933                         (0 == ui->rot_started) ||
934                         (NULL == ui->rot_cb)) {
935                         return ECORE_CALLBACK_PASS_ON;
936                 }
937
938                 enum appcore_rm rm;
939                 switch (e->data.l[1])
940                 {
941                         case   0: rm = APPCORE_RM_PORTRAIT_NORMAL;   break;
942                         case  90: rm = APPCORE_RM_LANDSCAPE_REVERSE; break;
943                         case 180: rm = APPCORE_RM_PORTRAIT_REVERSE;  break;
944                         case 270: rm = APPCORE_RM_LANDSCAPE_NORMAL;  break;
945                         default:  rm = APPCORE_RM_UNKNOWN;           break;
946                 }
947
948                 ui->rot_mode = rm;
949
950                 if (APPCORE_RM_UNKNOWN != rm) {
951                         ui->rot_cb((void *)&rm, rm, ui->rot_cb_data);
952                 }
953         }
954
955         return ECORE_CALLBACK_PASS_ON;
956 }
957
958 static void __add_climsg_cb(struct ui_priv *ui)
959 {
960         _ret_if(ui == NULL);
961
962         atom_parent = ecore_x_atom_get("_E_PARENT_BORDER_WINDOW");
963         if (!atom_parent)
964         {
965                 // Do Error Handling
966                 _ERR("atom_parent is NULL");
967         }
968         xsend_Atom = ecore_x_atom_get("_E_ILLUME_ATOM_APPCORE_RECAPTURE_REQUEST");
969         if (!xsend_Atom)
970         {
971                 // Do Error Handling
972                 _ERR("xsend_Atom is NULL");
973         }
974
975         ui->hshow = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, __show_cb, ui);
976         ui->hhide = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, __hide_cb, ui);
977         ui->hvchange = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, __visibility_cb, ui);
978
979 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
980         ui->hcmsg = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, __cmsg_cb, ui);
981 #endif
982
983         /* Add client message callback for WM_ROTATE */
984         if(!__check_wm_rotation_support())
985         {
986                 //ui->hcmsg = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, __cmsg_cb, ui);
987                 ui->wm_rot_supported = 1;
988                 appcore_set_wm_rotation(&wm_rotate);
989         }
990 }
991
992 static int __before_loop(struct ui_priv *ui, int *argc, char ***argv)
993 {
994         int r;
995         char *hwacc = NULL;
996         char *tm_tmp = NULL;
997
998         if (argc == NULL || argv == NULL) {
999                 _ERR("argc/argv is NULL");
1000                 errno = EINVAL;
1001                 return -1;
1002         }
1003
1004         g_type_init();
1005         elm_init(*argc, *argv);
1006
1007         hwacc = getenv("HWACC");
1008         if(hwacc == NULL) {
1009                 _DBG("elm_config_preferred_engine_set is not called");
1010         } else if(strcmp(hwacc, "USE") == 0) {
1011                 elm_config_preferred_engine_set("opengl_x11");
1012                 _DBG("elm_config_preferred_engine_set : opengl_x11");
1013         } else if(strcmp(hwacc, "NOT_USE") == 0) {
1014                 elm_config_preferred_engine_set("software_x11");
1015                 _DBG("elm_config_preferred_engine_set : software_x11");
1016         } else {
1017                 _DBG("elm_config_preferred_engine_set is not called");
1018         }
1019 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
1020         tm_tmp = getenv("TASKMANAGE");
1021         if(tm_tmp == NULL) {
1022                 _DBG("taskmanage is null");
1023                 taskmanage = 1;
1024         } else if(strcmp(tm_tmp, "false") == 0) {
1025                 _DBG("taskmanage is false");
1026                 taskmanage = 0;
1027         } else {
1028                 _DBG("taskmanage is true %s", tm_tmp);
1029                 taskmanage = 1;
1030         }
1031 #endif
1032         r = appcore_init(ui->name, &efl_ops, *argc, *argv);
1033         _retv_if(r == -1, -1);
1034
1035         LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:appcore_init:done]", ui->name);
1036         if (ui->ops && ui->ops->create) {
1037                 r = ui->ops->create(ui->ops->data);
1038                 if (r < 0) {
1039                         _ERR("create() return error");
1040                         appcore_exit();
1041                         if (ui->ops && ui->ops->terminate)
1042                                 ui->ops->terminate(ui->ops->data);
1043                         errno = ECANCELED;
1044                         return -1;
1045                 }
1046                 LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:create:done]",
1047                     ui->name);
1048         }
1049         ui->state = AS_CREATED;
1050
1051         __add_climsg_cb(ui);
1052
1053         return 0;
1054 }
1055
1056 static void __after_loop(struct ui_priv *ui)
1057 {
1058         appcore_unset_rotation_cb();
1059         appcore_exit();
1060
1061         if (ui->state == AS_RUNNING) {
1062                 _DBG("[APP %d] PAUSE before termination", _pid);
1063                 if (ui->ops && ui->ops->pause)
1064                         ui->ops->pause(ui->ops->data);
1065         }
1066
1067         if (ui->ops && ui->ops->terminate)
1068                 ui->ops->terminate(ui->ops->data);
1069
1070         if (ui->hshow)
1071                 ecore_event_handler_del(ui->hshow);
1072         if (ui->hhide)
1073                 ecore_event_handler_del(ui->hhide);
1074         if (ui->hvchange)
1075                 ecore_event_handler_del(ui->hvchange);
1076
1077         __appcore_timer_del(ui);
1078
1079         elm_shutdown();
1080
1081 #ifdef _GATE_TEST_ENABLE
1082         if((ui->name) && (strncmp(ui->name, "wrt-client", 10) != 0)) {
1083                 LOG(LOG_DEBUG, "GATE-M", "<GATE-M>APP_CLOSED_%s<GATE-M>", ui->name);
1084         }
1085 #endif
1086 }
1087
1088 static int __set_data(struct ui_priv *ui, const char *name,
1089                     struct appcore_ops *ops)
1090 {
1091         if (ui->name) {
1092                 _ERR("Mainloop already started");
1093                 errno = EINPROGRESS;
1094                 return -1;
1095         }
1096
1097         if (name == NULL || name[0] == '\0') {
1098                 _ERR("Invalid name");
1099                 errno = EINVAL;
1100                 return -1;
1101         }
1102
1103         if (ops == NULL) {
1104                 _ERR("ops is NULL");
1105                 errno = EINVAL;
1106                 return -1;
1107         }
1108
1109         ui->name = strdup(name);
1110         _retv_if(ui->name == NULL, -1);
1111
1112         ui->ops = ops;
1113
1114         ui->mfcb = __appcore_efl_memory_flush_cb;
1115
1116         _pid = getpid();
1117
1118         /* WM_ROTATE */
1119         ui->wm_rot_supported = 0;
1120         ui->rot_started = 0;
1121         ui->rot_cb = NULL;
1122         ui->rot_cb_data = NULL;
1123         ui->rot_mode = APPCORE_RM_UNKNOWN;
1124
1125         return 0;
1126 }
1127
1128 static void __unset_data(struct ui_priv *ui)
1129 {
1130         if (ui->name)
1131                 free((void *)ui->name);
1132
1133         memset(ui, 0, sizeof(struct ui_priv));
1134 }
1135
1136 /* WM_ROTATE */
1137 static int __wm_set_rotation_cb(int (*cb) (void *event_info, enum appcore_rm, void *), void *data)
1138 {
1139         if (cb == NULL) {
1140                 errno = EINVAL;
1141                 return -1;
1142         }
1143
1144         if ((priv.wm_rot_supported) && (0 == priv.rot_started)) {
1145                 __set_wm_rotation_support(0, 1);
1146         }
1147
1148         priv.rot_cb = cb;
1149         priv.rot_cb_data = data;
1150         priv.rot_started = 1;
1151
1152         return 0;
1153 }
1154
1155 static int __wm_unset_rotation_cb(void)
1156 {
1157         if ((priv.wm_rot_supported) && (1 == priv.rot_started)) {
1158                 __set_wm_rotation_support(0, 0);
1159         }
1160
1161         priv.rot_cb = NULL;
1162         priv.rot_cb_data = NULL;
1163         priv.rot_started = 0;
1164
1165         return 0;
1166 }
1167
1168 static int __wm_get_rotation_state(enum appcore_rm *curr)
1169 {
1170         if (curr == NULL) {
1171                 errno = EINVAL;
1172                 return -1;
1173         }
1174
1175         *curr = priv.rot_mode;
1176
1177         return 0;
1178 }
1179
1180 static int __wm_pause_rotation_cb(void)
1181 {
1182         if ((1 == priv.rot_started) && (priv.wm_rot_supported)) {
1183                 __set_wm_rotation_support(0, 0);
1184         }
1185
1186         priv.rot_started = 0;
1187
1188         return 0;
1189 }
1190
1191 static int __wm_resume_rotation_cb(void)
1192 {
1193         if ((0 == priv.rot_started) && (priv.wm_rot_supported)) {
1194                 __set_wm_rotation_support(0, 1);
1195         }
1196
1197         priv.rot_started = 1;
1198
1199         return 0;
1200 }
1201
1202 static struct ui_wm_rotate wm_rotate = {
1203         __wm_set_rotation_cb,
1204         __wm_unset_rotation_cb,
1205         __wm_get_rotation_state,
1206         __wm_pause_rotation_cb,
1207         __wm_resume_rotation_cb
1208 };
1209
1210 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
1211 static Window _get_parent_window(Window id)
1212 {
1213         Window root;
1214         Window parent;
1215         Window *children;
1216         unsigned int num;
1217
1218         if (!XQueryTree(ecore_x_display_get(), id, &root, &parent, &children, &num)) {
1219                 return 0;
1220         }
1221
1222         if (children) {
1223                 XFree(children);
1224         }
1225
1226         return parent;
1227 }
1228
1229 static Window _find_capture_window(Window id, Visual **visual, int *depth, int *width, int *height)
1230 {
1231         XWindowAttributes attr;
1232         Window parent = id;
1233         Window orig_id = id;
1234
1235         if (id == 0) {
1236                 return (Window)-1;
1237         }
1238
1239         do {
1240                 id = parent;
1241
1242                 if (!XGetWindowAttributes(ecore_x_display_get(), id, &attr)) {
1243                         return (Window)-1;
1244                 }
1245
1246                 parent = _get_parent_window(id);
1247
1248                 if (attr.map_state == IsViewable
1249                     && attr.override_redirect == True
1250                     && attr.class == InputOutput && parent == attr.root) {
1251                         *depth = attr.depth;
1252                         *width = attr.width;
1253                         *height = attr.height;
1254                         *visual = attr.visual;
1255                         return id;
1256                 }
1257         } while (parent != attr.root && parent != 0);
1258
1259         XGetWindowAttributes(ecore_x_display_get(), orig_id, &attr);
1260         *depth = attr.depth;
1261         *width = attr.width;
1262         *height = attr.height;
1263         *visual = attr.visual;
1264
1265         return (Window) 0;
1266
1267 }
1268
1269 static char *_capture_window(Window id, Visual *visual, int width, int height, int depth, int *size)
1270 {
1271         XShmSegmentInfo si;
1272         XImage *xim;
1273         int img_size;
1274         char *captured_img = NULL;
1275
1276         /* (depth >> 3) + 1 == 4 byte */
1277         si.shmid =
1278             shmget(IPC_PRIVATE, width * height * ((depth >> 3) + 1),
1279                    IPC_CREAT | 0666);
1280
1281         if (si.shmid < 0) {
1282                 _ERR("shmget");
1283                 return NULL;
1284         }
1285
1286         si.readOnly = False;
1287         si.shmaddr = shmat(si.shmid, NULL, 0);
1288
1289         if (si.shmaddr == (char *)-1) {
1290                 shmdt(si.shmaddr);
1291                 shmctl(si.shmid, IPC_RMID, 0);
1292                 return NULL;
1293         }
1294
1295         xim = XShmCreateImage(ecore_x_display_get(), visual, depth, ZPixmap, NULL, &si,
1296                             width, height);
1297
1298         if (xim == 0) {
1299                 shmdt(si.shmaddr);
1300                 shmctl(si.shmid, IPC_RMID, 0);
1301
1302                 return NULL;
1303         }
1304
1305         img_size = xim->bytes_per_line * xim->height;
1306         xim->data = si.shmaddr;
1307
1308         XSync(ecore_x_display_get(), False);
1309         XShmAttach(ecore_x_display_get(), &si);
1310         XShmGetImage(ecore_x_display_get(), id, xim, 0, 0, 0xFFFFFFFF);
1311         XSync(ecore_x_display_get(), False);
1312
1313         captured_img = calloc(1, img_size);
1314         if (captured_img) {
1315                 memcpy(captured_img, xim->data, img_size);
1316         } else {
1317                 _ERR("calloc");
1318         }
1319
1320         XShmDetach(ecore_x_display_get(), &si);
1321         XDestroyImage(xim);
1322
1323
1324         shmdt(si.shmaddr);
1325         shmctl(si.shmid, IPC_RMID, 0);
1326
1327         *size = img_size;
1328
1329         return captured_img;
1330
1331 }
1332
1333 #define _WND_REQUEST_ANGLE_IDX 0
1334 #define _WND_CURR_ANGLE_IDX    1
1335 int _get_angle(Ecore_X_Window win)
1336 {
1337         int after = -1;
1338         int before = -1;
1339
1340         do {
1341                 int ret, count;
1342                 int angle[2] = {-1, -1};
1343                 unsigned char* prop_data = NULL;
1344
1345                 ret = ecore_x_window_prop_property_get(win,
1346                                 ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
1347                                 ECORE_X_ATOM_CARDINAL,
1348                                 32,
1349                                 &prop_data,
1350                                 &count);
1351                 if (ret <= 0) {
1352                         if (prop_data) free(prop_data);
1353                         break;
1354                 }
1355
1356                 if (prop_data) {
1357                         memcpy(&angle, prop_data, sizeof (int) *count);
1358                         free(prop_data);
1359                 }
1360
1361                 after= angle[_WND_REQUEST_ANGLE_IDX];
1362                 before = angle[_WND_CURR_ANGLE_IDX];
1363         } while (0);
1364
1365         if (-1 == after) after = 0;
1366
1367         return after;
1368 }
1369
1370 static void _rotate_img(Evas_Object *image_object, int angle, int cx, int cy)
1371 {
1372         Evas_Map *em;
1373
1374         _ret_if(NULL == image_object);
1375
1376         em = evas_map_new(4);
1377         _ret_if(NULL == em);
1378
1379         evas_map_util_points_populate_from_object(em, image_object);
1380         evas_map_util_rotate(em, (double) angle, cx, cy);
1381
1382         evas_object_map_set(image_object, em);
1383         evas_object_map_enable_set(image_object, EINA_TRUE);
1384
1385         evas_map_free(em);
1386 }
1387
1388 #define EXTENSION_LEN 128
1389 #define CAPTURE_FILE_PATH "/opt/usr/share/app_capture"
1390 bool _make_capture_file(const char *package, int width, int height, char *img, int angle)
1391 {
1392         int len;
1393         char *filename;
1394         Evas *e;
1395         Evas_Object *image_object;
1396         int canvas_width, canvas_height;
1397         int cx = 0, cy = 0;
1398         int mx = 0;
1399         int r = 0;
1400
1401         _retv_if(NULL == package, false);
1402
1403         len = strlen(package) + EXTENSION_LEN;
1404         filename = malloc(len);
1405         _retv_if(NULL == filename, false);
1406         snprintf(filename, len, CAPTURE_FILE_PATH"/%s.jpg", package);
1407
1408         if (90 == angle || 270 == angle) {
1409                 canvas_width = height;
1410                 canvas_height = width;
1411         } else {
1412                 canvas_width = width;
1413                 canvas_height = height;
1414         }
1415
1416         e = virtual_canvas_create(canvas_width, canvas_height);
1417         goto_if(NULL == e, error);
1418
1419         image_object = evas_object_image_add(e);
1420         goto_if(NULL == image_object, error);
1421
1422         evas_object_image_size_set(image_object, width, height);
1423         evas_object_image_data_set(image_object, img);
1424         evas_object_image_data_update_add(image_object, 0, 0, width, height);
1425         evas_object_resize(image_object, width, height);
1426         evas_object_image_filled_set(image_object, EINA_TRUE);
1427         switch (angle) {
1428                 case 90:
1429                         cx = canvas_width - width / 2;
1430                         cy = canvas_height / 2;
1431                         mx = canvas_width - width;
1432                         break;
1433                 case 180:
1434                         cx = width / 2;
1435                         cy = height / 2;
1436                         break;
1437                 case 270:
1438                         cx = width / 2;
1439                         cy = canvas_height / 2;
1440                         break;
1441                 default:
1442                         break;
1443         }
1444         evas_object_move(image_object, mx, 0);
1445         _rotate_img(image_object, angle, cx, cy);
1446         evas_object_show(image_object);
1447
1448         if (access(CAPTURE_FILE_PATH, F_OK) != 0) {
1449                 r = mkdir(CAPTURE_FILE_PATH, 0777);
1450                 goto_if(r < 0, error);
1451         }
1452         goto_if(false == virtual_canvas_flush_to_file(e, filename, canvas_width, canvas_height), error);
1453
1454         evas_object_del(image_object);
1455         virtual_canvas_destroy(e);
1456         free(filename);
1457
1458         return true;
1459
1460 error:
1461         do {
1462                 free(filename);
1463
1464                 if (!e) break;
1465                 virtual_canvas_destroy(e);
1466
1467                 if (!image_object) break;
1468                 evas_object_del(image_object);
1469         } while (0);
1470
1471         return false;
1472 }
1473
1474 int __resize8888(const char* pDataIn, char* pDataOut, int inWidth, int inHeight, int outWidth, int outHeight)
1475 {
1476         int scaleX = 0;
1477         int scaleY = 0;
1478         int i = 0;
1479         int j = 0;
1480         int iRow = 0;
1481         int iIndex = 0;
1482         char* pOutput = pDataOut;
1483         char* pOut = pDataOut;
1484         const char* pIn = NULL;
1485         int *pColLUT = malloc(sizeof(int) * outWidth);
1486
1487         /* Calculate X Scale factor */
1488         scaleX = inWidth * 256 / outWidth;
1489         /* Calculate Y Scale factor, aspect ratio is not maintained */
1490         scaleY = inHeight * 256 / outHeight;
1491         for (j = 0; j < outWidth; j++)
1492         {
1493         /* Get input index based on column scale factor */
1494         /* To get more optimization, this is calculated once and
1495         * is placed in a LUT and used for indexing
1496         */
1497         pColLUT [j] = ((j * scaleX) >> 8) * 4;
1498         }
1499         pOut = pOutput;
1500         for (i = 0; i < outHeight; i++)
1501         {
1502                 /* Get input routWidth index based on routWidth scale factor */
1503                 iRow = (i * scaleY >> 8) * inWidth * 4;
1504                 /* Loop could be unrolled for more optimization */
1505                 for (j = 0; j < (outWidth); j++)
1506                 {
1507                         /* Get input index based on column scale factor */
1508                         iIndex = iRow + pColLUT [j];
1509                         pIn = pDataIn + iIndex;
1510                         *pOut++ = *pIn++;
1511                         *pOut++ = *pIn++;
1512                         *pOut++ = *pIn++;
1513                         *pOut++ = *pIn++;
1514                 }
1515         }
1516
1517         free(pColLUT);
1518         return 0;
1519 }
1520
1521 static void _capture_and_make_file(Ecore_X_Window win, int pid, const char *package)
1522 {
1523         Visual *visual;
1524         Window redirected_id;
1525
1526         int width, height, depth;
1527         int width_out, height_out;
1528         int size = 0;
1529         int angle;
1530
1531         char *img;
1532
1533         redirected_id = _find_capture_window(win, &visual, &depth, &width, &height);
1534         _ret_if(redirected_id == (Window) -1 ||
1535                                 redirected_id == (Window) 0);
1536
1537         SECURE_LOGD("Capture : win[%x] -> redirected win[%x] for %s[%d]", win, redirected_id, package, pid);
1538
1539         img = _capture_window(redirected_id, visual, width, height, depth, &size);
1540         _ret_if(NULL == img);
1541
1542         width_out = width/2;
1543         height_out = height/2;
1544
1545         if ( width_out < 1 || height_out < 1 ) {
1546                 free(img);
1547                 return;
1548         }
1549
1550         __resize8888(img, img, width, height, width_out, height_out);
1551
1552         angle = _get_angle(win);
1553         if (false == _make_capture_file(package, width_out, height_out, img, angle)) {
1554                 _ERR("cannot a capture file for the package of [%s]", package);
1555         }
1556
1557         free(img);
1558 }
1559 #endif
1560
1561 extern int aul_status_update(int status);
1562
1563 EXPORT_API int appcore_efl_main(const char *name, int *argc, char ***argv,
1564                                 struct appcore_ops *ops)
1565 {
1566         int r;
1567         GSList *iter = NULL;
1568         struct win_node *entry = NULL;
1569         int pid;
1570
1571         LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:main:done]", name);
1572
1573         pid = getpid();
1574         r = aul_app_get_appid_bypid(pid, appid, APPID_MAX);
1575         if( r < 0) {
1576                 _ERR("aul_app_get_appid_bypid fail");
1577         }
1578
1579         r = __set_data(&priv, name, ops);
1580         _retv_if(r == -1, -1);
1581
1582         r = __before_loop(&priv, argc, argv);
1583         if (r == -1) {
1584                 __unset_data(&priv);
1585                 return -1;
1586         }
1587
1588         elm_run();
1589
1590         aul_status_update(STATUS_DYING);
1591
1592 #ifdef _APPFW_FEATURE_CAPTURE_FOR_TASK_MANAGER
1593         for (iter = g_winnode_list; iter != NULL; iter = g_slist_next(iter)) {
1594                 entry = iter->data;
1595                 if(__check_skip(entry->win) == FALSE)
1596                         break;
1597         }
1598         if(iter) {
1599                 entry = iter->data;
1600                 if(taskmanage) {
1601                         _capture_and_make_file(entry->win, pid, appid);
1602                 }
1603         }
1604 #endif
1605
1606         __after_loop(&priv);
1607
1608         __unset_data(&priv);
1609
1610         return 0;
1611 }
1612
1613 EXPORT_API int appcore_set_system_resource_reclaiming(bool enable)
1614 {
1615         resource_reclaiming = enable;
1616
1617         return 0;
1618 }
1619
1620 EXPORT_API int appcore_set_app_state(int state)
1621 {
1622         priv.state = state;
1623
1624         return 0;
1625 }
1626
1627 EXPORT_API int appcore_efl_goto_pause()
1628 {
1629         _DBG(" Go to Pasue state \n");
1630         b_active = 0;
1631         __do_app(AE_PAUSE, &priv, NULL);
1632
1633         return 0;
1634 }
1635
1636 EXPORT_API int appcore_set_prelaunching(bool value)
1637 {
1638         prelaunching = value;
1639
1640         return 0;
1641 }
1642
1643 #ifdef _APPFW_FEATURE_PROCESS_POOL
1644 EXPORT_API int appcore_set_preinit_window_name(const char* win_name)
1645 {
1646         int ret = -1;
1647         void *preinit_window = NULL;
1648
1649         if(!win_name) {
1650                 _ERR("invalid input param");
1651                 return -1;
1652         }
1653
1654         preinit_window = aul_get_preinit_window(win_name);
1655         if(!preinit_window) {
1656                 _ERR("no preinit window");
1657                 return -1;
1658         }
1659
1660         const Evas *e = evas_object_evas_get((const Evas_Object *)preinit_window);
1661         if(e) {
1662                 Ecore_Evas *ee = ecore_evas_ecore_evas_get(e);
1663                 if(ee) {
1664                         ecore_evas_name_class_set(ee, win_name, win_name);
1665                         _DBG("name class set success : %s", win_name);
1666                         ret = 0;
1667                 }
1668         }
1669
1670         return ret;
1671 }
1672 #endif