74b7bb731fabc7f17cea99ad684f6f550fa352c6
[platform/upstream/enlightenment.git] / src / bin / services / e_service_launcher.c
1 #include "e.h"
2 #include "e_policy_wl.h"
3 #include "services/e_service_launcher.h"
4 #include "e_comp_wl_rsm_intern.h"
5 #include "e_comp_wl_tbm_intern.h"
6
7 #include <tzsh_server.h>
8 #include <wayland-tbm-server.h>
9
10 typedef struct _E_Service_Launcher          E_Service_Launcher;
11 typedef struct _E_Service_Launcher_Handler  E_Service_Launcher_Handler;
12 typedef struct _E_Service_Launcher_Consumer E_Service_Launcher_Consumer;
13
14 typedef enum
15 {
16    LAUNCHER_STATE_IDLE,
17    LAUNCHER_STATE_MONITORING,
18    LAUNCHER_STATE_PREPARING,
19    LAUNCHER_STATE_LAUNCHING,
20    LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER,
21    LAUNCHER_STATE_DONE,
22    LAUNCHER_STATE_CANCELED,
23    LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE,
24 } Launcher_State;
25
26 struct _E_Service_Launcher_Consumer
27 {
28    E_Service_Launcher                  *lc;
29    E_Vis_Grab                          *vis_grab;       //grab of client's visibility
30
31    E_Client                            *ec;
32    E_Object_Delfn                      *delfn;          //del callback of E_Client
33
34    Ecore_Event_Handler                 *buff_attach;    //event handler for BUFFER_CHANGE
35    int                                  buff_attach_count;
36 };
37
38 struct _E_Service_Launcher
39 {
40    Launcher_State                       state;          //current state of launcher
41
42    struct wl_resource                  *res;            //tizen_window_transition_launcher resource
43    E_Client                            *ec;             //launcher E_Client
44
45    E_Vis_Grab                          *vis_grab;       //grab of launcher visibility
46    uint32_t                             serial;         //identifier
47    enum tws_service_launcher_direction  direction;      //direction of transition
48
49    struct
50      {
51         E_Client                       *ec;             //target E_Client
52         pid_t                           pid;            //pid
53         const char                     *appid;          //appid
54         E_Vis_Grab                     *vis_grab;       //grab of target client's visibility
55
56         Eina_Bool                       delay_del;      //refered delay_del
57         E_Object_Delfn                 *delfn;          //del callback of target E_Client
58
59         const char                     *splash_path;    //path of file for splash
60         const char                     *splash_group;   //group name for splash
61      } target; //target window information for transition
62
63    E_Client                            *launched_ec;    //E_Client was launched by launcher
64    E_Object_Delfn                      *launched_delfn;  //del callback of launched_ec
65
66    Ecore_Event_Handler                 *buff_attach;    //event handler for BUFFER_CHANGE
67
68    Eina_Bool                            with_swl;       //it's for shared widget launch
69    Eina_Bool                            swl_done;       //flag indicating done of callee
70
71    Eina_Bool                            block_input;    //input is blocked(1) or not(0) while running client side animation
72
73    Eina_List                           *consumers;      //list launcher consumer of launcher ec
74 };
75
76 struct _E_Service_Launcher_Handler
77 {
78    Eina_Hash           *launcher_hash;  //hash key:launcher_ec, data:E_Service_Launcher
79    unsigned int         launcher_count; //count of launcher object
80
81    Eina_List           *hooks_ec;       //hook list for E_CLIENT_HOOK_*
82    Eina_List           *hooks_vis;      //hook list for E_POL_VIS_HOOK_TYPE_*
83    Eina_List           *hooks_co;       //hook list for E_COMP_OBJECT_INTERCEPT_HOOK_*
84    Eina_List           *hooks_appinfo;  //hook list for E_APPINFO_HOOK_*
85    Eina_List           *hdlrs_ev;       //handler list for ecore event
86
87    E_Service_Launcher  *runner;         //current runner(running launcher)
88    E_Service_Launcher  *pre_runner;     //previous runner
89 };
90
91 ////////////////////////////////////////////////////////////////////
92 static E_Service_Launcher_Handler *_laundler = NULL;
93
94 static void                _launcher_launched_ec_set(E_Service_Launcher *lc, E_Client *launched_ec);
95 static void                _launcher_target_ec_set(E_Service_Launcher *lc, E_Client *target_ec);
96
97 static E_Service_Launcher *_launcher_handler_launcher_find(E_Client *ec);
98 static Eina_Bool           _launcher_handler_launcher_add(E_Service_Launcher *lc);
99 static Eina_Bool           _launcher_handler_launcher_del(E_Service_Launcher *lc);
100
101 static E_Service_Launcher *_launcher_handler_launcher_runner_get(void);
102 static void                _launcher_handler_launcher_runner_set(E_Service_Launcher *lc);
103 static void                _launcher_handler_launcher_runner_unset(E_Service_Launcher *lc);
104 static E_Service_Launcher *_launcher_handler_launcher_pre_runner_get(void);
105 static void                _launcher_handler_launcher_pre_runner_set(E_Service_Launcher *lc);
106 static void                _launcher_handler_launcher_pre_runner_unset(E_Service_Launcher *lc);
107
108 ////////////////////////////////////////////////////////////////////
109 static Eina_List *
110 _launcher_clients_find_by_pid(pid_t pid)
111 {
112    E_Client *ec;
113    Eina_List *clients = NULL, *l;
114
115    EINA_LIST_FOREACH(e_comp->clients, l, ec)
116      {
117         if (e_object_is_del(E_OBJECT(ec))) continue;
118         if (ec->netwm.pid != pid) continue;
119         clients = eina_list_append(clients, ec);
120      }
121
122    return clients;
123 }
124
125
126 static void
127 _launcher_cb_input_block_expired(void *data)
128 {
129    E_Service_Launcher *lc = (E_Service_Launcher*)data;
130    EINA_SAFETY_ON_NULL_RETURN(lc);
131
132    lc->block_input = EINA_FALSE;
133
134    ELOGF("LAUNCHER_SRV", "Input block EXPIRED", lc->ec);
135 }
136
137 static Eina_Bool
138 _launcher_input_block_set(E_Service_Launcher *lc, Eina_Bool set)
139 {
140    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE);
141
142    if (set)
143      {
144         //request for block all input
145         lc->block_input = e_devicemgr_block_internal_add(ECORE_DEVICE_CLASS_NONE,
146                                                          EINA_TRUE,
147                                                          (uint32_t)(e_policy_visibility_timeout_get() * 1000),
148                                                          _launcher_cb_input_block_expired, lc);
149         return lc->block_input;
150      }
151    else
152      {
153         return e_devicemgr_block_internal_remove(_launcher_cb_input_block_expired, lc);
154      }
155 }
156
157 static const char*
158 _launcher_state_to_str(Launcher_State state)
159 {
160    switch (state)
161      {
162       case LAUNCHER_STATE_IDLE:
163          return "IDLE";
164       case LAUNCHER_STATE_MONITORING:
165          return "PID_MONITORING";
166       case LAUNCHER_STATE_PREPARING:
167          return "PREPARING";
168       case LAUNCHER_STATE_LAUNCHING:
169          return "LAUNCHING";
170       case LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER:
171          return "LAUNCHING_BUT_WAITING_BUFFER";
172       case LAUNCHER_STATE_DONE:
173          return "LAUNCH_DONE";
174       case LAUNCHER_STATE_CANCELED:
175          return "LAUNCH_CANCELED";
176       case LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE:
177          return "WAIT_FOR_RESPONSE_FROM_CALLEE";
178      }
179    return "UNKNOWN";
180 }
181
182 static void
183 _launcher_state_set(E_Service_Launcher *lc,
184                     Launcher_State state)
185 {
186    EINA_SAFETY_ON_NULL_RETURN(lc);
187
188    if (state == lc->state) return;
189
190    ELOGF("LAUNCHER_SRV", "Set state  %s --> %s",
191          lc->ec,
192          _launcher_state_to_str(lc->state),
193          _launcher_state_to_str(state));
194
195    lc->state = state;
196 }
197
198 static void
199 _launcher_consumer_del(E_Service_Launcher_Consumer *consumer)
200 {
201    E_Service_Launcher *lc;
202
203    EINA_SAFETY_ON_NULL_RETURN(consumer);
204
205    lc = consumer->lc;
206
207    ELOGF("LAUNCHER_SRV", "Del launcher_consumer ec:%p", lc ? lc->ec : NULL, consumer->ec);
208
209    if (consumer->ec)
210      {
211         e_object_delfn_del(E_OBJECT(consumer->ec), consumer->delfn);
212         consumer->ec = NULL;
213         consumer->delfn = NULL;
214      }
215
216    if (consumer->vis_grab)
217      {
218         e_policy_visibility_client_grab_release(consumer->vis_grab);
219         consumer->vis_grab = NULL;
220      }
221
222    if (consumer->buff_attach)
223      E_FREE_FUNC(consumer->buff_attach, ecore_event_handler_del);
224
225    if (lc)
226      lc->consumers = eina_list_remove(lc->consumers, consumer);
227
228    free(consumer);
229 }
230
231 static void
232 _launcher_cb_consumer_ec_del(void *data, void *obj)
233 {
234    E_Service_Launcher_Consumer *consumer;
235    E_Client *ec;
236
237    ec = (E_Client *)obj;
238    EINA_SAFETY_ON_NULL_RETURN(ec);
239
240    consumer= (E_Service_Launcher_Consumer *)data;
241    EINA_SAFETY_ON_NULL_RETURN(consumer);
242    EINA_SAFETY_ON_TRUE_RETURN(consumer->ec != ec);
243
244    consumer->ec = NULL;
245    consumer->delfn = NULL;
246
247    _launcher_consumer_del(consumer);
248 }
249
250 static E_Service_Launcher_Consumer *
251 _launcher_consumer_create(E_Service_Launcher *lc, E_Client *ec)
252 {
253    E_Service_Launcher_Consumer *consumer;
254
255    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, NULL);
256    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
257
258    consumer = E_NEW(E_Service_Launcher_Consumer, 1);
259    EINA_SAFETY_ON_NULL_RETURN_VAL(consumer, NULL);
260
261    consumer->ec = ec;
262    consumer->delfn = e_object_delfn_add(E_OBJECT(ec),
263                                         _launcher_cb_consumer_ec_del, consumer);
264
265    consumer->lc = lc;
266    lc->consumers = eina_list_append(lc->consumers, consumer);
267
268    ELOGF("LAUNCHER_SRV", "Create launcher_consumer ec:%p", lc->ec, ec);
269
270    return consumer;
271 }
272
273 static void
274 _launcher_consumers_reset(E_Service_Launcher *lc)
275 {
276    E_Service_Launcher_Consumer *consumer;
277    Eina_List *l, *ll;
278
279    EINA_SAFETY_ON_NULL_RETURN(lc);
280
281    EINA_LIST_FOREACH_SAFE(lc->consumers, l, ll, consumer)
282      _launcher_consumer_del(consumer);
283 }
284
285 static void
286 _launcher_post_forward(E_Service_Launcher *lc, Eina_Bool success)
287 {
288    E_Client *target_ec = NULL;
289
290    if ((lc->target.ec) && (!e_object_is_del(E_OBJECT(lc->target.ec))))
291      target_ec = lc->target.ec;
292
293    _launcher_target_ec_set(lc, NULL);
294
295    lc->serial = 0;
296    lc->target.pid = -1;
297
298    E_FREE_FUNC(lc->target.appid, eina_stringshare_del);
299    E_FREE_FUNC(lc->target.splash_path, eina_stringshare_del);
300    E_FREE_FUNC(lc->target.splash_group, eina_stringshare_del);
301    E_FREE_FUNC(lc->buff_attach, ecore_event_handler_del);
302
303    //if forward animation is failed, enlightenment can run animation instead.
304    if ((!success) && (target_ec))
305      e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 0);
306
307    if (!_launcher_input_block_set(lc, EINA_FALSE))
308      ELOGF("LAUNCHER_SRV", "Input block remove FAIL...", lc->ec);
309
310    if (lc->vis_grab)
311      e_policy_visibility_client_grab_release(lc->vis_grab);
312    if (lc->target.vis_grab)
313      e_policy_visibility_client_grab_release(lc->target.vis_grab);
314
315    lc->vis_grab = NULL;
316    lc->target.vis_grab = NULL;
317
318    if (!target_ec) return;
319
320    if (success)
321      _launcher_launched_ec_set(lc, target_ec);
322
323    //show target_ec
324    e_comp_object_damage(target_ec->frame, 0, 0, target_ec->w, target_ec->h);
325    e_comp_object_dirty(target_ec->frame);
326    e_comp_object_render(target_ec->frame);
327    evas_object_show(target_ec->frame);
328
329    e_comp_client_override_del(target_ec);
330 }
331
332 static void
333 _launcher_post_backward(E_Service_Launcher *lc, Eina_Bool success)
334 {
335    E_Client *target_ec = NULL;
336
337    target_ec = lc->target.ec;
338    _launcher_target_ec_set(lc, NULL);
339
340    lc->serial = 0;
341    lc->target.pid = -1;
342    lc->direction = 0;
343
344    E_FREE_FUNC(lc->target.appid, eina_stringshare_del);
345    E_FREE_FUNC(lc->target.splash_path, eina_stringshare_del);
346    E_FREE_FUNC(lc->target.splash_group, eina_stringshare_del);
347    E_FREE_FUNC(lc->buff_attach, ecore_event_handler_del);
348
349    if (target_ec)
350      {
351         Eina_Bool is_del;
352         is_del = e_object_is_del(E_OBJECT(target_ec));
353         if (lc->target.delay_del)
354           e_object_delay_del_unref(E_OBJECT(target_ec));
355
356         if (is_del)
357           target_ec = NULL;
358      }
359    lc->target.delay_del = EINA_FALSE;
360
361    //if forward animation is failed, enlightenment can run animation instead.
362    if ((!success) && (target_ec))
363      e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 0);
364
365    if (!_launcher_input_block_set(lc, EINA_FALSE))
366      ELOGF("LAUNCHER_SRV", "Input block remove FAIL...", lc->ec);
367
368    if (lc->vis_grab)
369      e_policy_visibility_client_grab_release(lc->vis_grab);
370    if (lc->target.vis_grab)
371      e_policy_visibility_client_grab_release(lc->target.vis_grab);
372
373    lc->vis_grab = NULL;
374    lc->target.vis_grab = NULL;
375
376    _launcher_consumers_reset(lc);
377
378    if (!target_ec) return;
379
380    if (success)
381      e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 0);
382
383    e_comp_client_override_del(target_ec);
384 }
385
386 static void
387 _launcher_stop_send(E_Service_Launcher *lc)
388 {
389    EINA_SAFETY_ON_NULL_RETURN(lc);
390
391    ELOGF("LAUNCHER_SRV", "Send STOP event(%d) target(ec:%p)",
392          lc->ec, lc->serial, lc->target.ec);
393
394    tws_service_launcher_send_stop(lc->res, lc->serial);
395 }
396
397 static Eina_Bool
398 _launcher_prepare_send(E_Service_Launcher *lc,
399                        E_Client *target_ec,
400                        int x, int y,
401                        const char *shared_widget_info)
402 {
403    uint32_t res_id = 0;
404
405    E_Comp_Object_Content_Type content_type = 0;
406    enum tws_service_launcher_target_type target_type = 0;
407    const char *target_path = NULL, *target_group = NULL;
408    Evas_Object *content = NULL;
409    struct wl_array info_array;
410
411    int len;
412    char *p_char;
413    uint32_t *p_u32;
414
415    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE);
416    EINA_SAFETY_ON_NULL_RETURN_VAL(target_ec, EINA_FALSE);
417
418    wl_array_init(&info_array);
419    if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
420      {
421         content_type = e_comp_object_content_type_get(target_ec->frame);
422         switch (content_type)
423           {
424            case E_COMP_OBJECT_CONTENT_TYPE_EXT_IMAGE:
425               content = e_comp_object_content_get(target_ec->frame);
426               EINA_SAFETY_ON_NULL_GOTO(content, fail);
427
428               target_type = TWS_SERVICE_LAUNCHER_TARGET_TYPE_IMAGE;
429               evas_object_image_file_get(content, &target_path, NULL);
430               EINA_SAFETY_ON_NULL_GOTO(target_path, fail);
431
432               len = strlen(target_path) + 1;
433               p_char = wl_array_add(&info_array, len);
434               EINA_SAFETY_ON_NULL_GOTO(p_char, fail);
435
436               strncpy(p_char, target_path, len);
437               break;
438            case E_COMP_OBJECT_CONTENT_TYPE_EXT_EDJE:
439               content = e_comp_object_content_get(target_ec->frame);
440               EINA_SAFETY_ON_NULL_GOTO(content, fail);
441
442               target_type = TWS_SERVICE_LAUNCHER_TARGET_TYPE_EDJE;
443               target_path = lc->target.splash_path;
444               target_group = lc->target.splash_group;
445               if ((!target_path) || (!target_group))
446                 edje_object_file_get(content, &target_path, &target_group);
447               EINA_SAFETY_ON_NULL_GOTO(target_path, fail);
448               EINA_SAFETY_ON_NULL_GOTO(target_group, fail);
449
450               len = strlen(target_path) + 1;
451               p_char = wl_array_add(&info_array, len);
452               EINA_SAFETY_ON_NULL_GOTO(p_char, fail);
453
454               strncpy(p_char, target_path, len);
455
456               len = strlen(target_group) + 1;
457               p_char = wl_array_add(&info_array, len);
458               EINA_SAFETY_ON_NULL_GOTO(p_char, fail);
459
460               strncpy(p_char, target_group, len);
461
462               break;
463            default:
464               target_type = TWS_SERVICE_LAUNCHER_TARGET_TYPE_REMOTE_SURFACE;
465               res_id = e_pixmap_res_id_get(target_ec->pixmap);
466
467               p_u32 = wl_array_add(&info_array, sizeof(uint32_t));
468               EINA_SAFETY_ON_NULL_GOTO(p_u32, fail);
469
470               *p_u32 = res_id;
471           }
472      }
473    else
474      {
475         target_type = TWS_SERVICE_LAUNCHER_TARGET_TYPE_REMOTE_SURFACE;
476         res_id = e_pixmap_res_id_get(target_ec->pixmap);
477
478         p_u32 = wl_array_add(&info_array, sizeof(uint32_t));
479         EINA_SAFETY_ON_NULL_GOTO(p_u32, fail);
480
481         *p_u32 = res_id;
482      }
483
484
485    ELOGF("LAUNCHER_SRV", "Send PREPARE event(%d) direction:%s target(ec:%p type:%d res:%d path:%s pos(%d,%d) widget:%s)",
486          lc->ec, lc->serial, lc->direction?"BACKWARD":"FORWARD", target_ec, target_type, res_id, target_path?:"N/A", x, y, shared_widget_info);
487
488    tws_service_launcher_send_prepare(lc->res,
489                                      target_type,
490                                      &info_array,
491                                      lc->direction,
492                                      x, y,
493                                      shared_widget_info ? shared_widget_info : "None",
494                                      lc->serial);
495
496    wl_array_release(&info_array);
497    return EINA_TRUE;
498 fail:
499    wl_array_release(&info_array);
500    return EINA_FALSE;
501 }
502
503 static Eina_Bool
504 _launcher_prepare_shared_widget_forward_send(E_Service_Launcher *lc,
505                                              E_Client *target_ec)
506 {
507    Eina_Bool sent = EINA_FALSE;
508
509    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE);
510    EINA_SAFETY_ON_NULL_RETURN_VAL(target_ec, EINA_FALSE);
511    if(e_object_is_del(E_OBJECT(target_ec))) return EINA_FALSE;
512
513    e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 1);
514    e_comp_client_override_add(target_ec);
515
516    // grab uniconify job of target_ec
517    if (target_ec->iconic)
518      {
519         lc->target.vis_grab =
520           e_policy_visibility_client_filtered_grab_get
521             (target_ec,
522              (E_VIS_JOB_TYPE_UNICONIFY | E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY),
523              __func__);
524      }
525
526    if (!_launcher_input_block_set(lc, EINA_TRUE))
527      ELOGF("LAUNCHER_SRV", "Input block add FAIL...", lc->ec);
528
529    _launcher_launched_ec_set(lc, NULL);
530    _launcher_target_ec_set(lc, target_ec);
531
532    lc->direction = TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD;
533
534    sent = e_tzsh_shared_widget_launch_prepare_send(target_ec,
535                                                    TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_HIDE,
536                                                    lc->serial);
537    if (!sent)
538      {
539         ELOGF("LAUNCHER_SRV", "Failed to send event(PREPARE:FORWARD)", lc->ec);
540         _launcher_post_forward(lc, EINA_FALSE);
541      }
542
543    return sent;
544 }
545
546 static Eina_Bool
547 _launcher_prepare_shared_widget_backward_send(E_Service_Launcher *lc,
548                                               E_Client *activity,
549                                               E_Client *target_ec,
550                                               E_Vis_Job_Type job_type)
551 {
552    Eina_Bool sent = EINA_FALSE;
553
554    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE);
555    EINA_SAFETY_ON_NULL_RETURN_VAL(activity, EINA_FALSE);
556    EINA_SAFETY_ON_NULL_RETURN_VAL(target_ec, EINA_FALSE);
557
558    if (e_object_is_del(E_OBJECT(target_ec)))
559      {
560         if (lc->with_swl) return EINA_FALSE;
561         // do nothing if ec is deleted and there's no delay_del_ref as well.
562         if (!e_object_delay_del_ref_get(E_OBJECT(target_ec)))
563           return EINA_FALSE;
564      }
565
566    e_object_delay_del_ref(E_OBJECT(target_ec));
567    lc->target.delay_del = EINA_TRUE;
568
569    e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 1);
570    e_comp_client_override_add(target_ec);
571
572    if (activity == target_ec)
573      {
574         lc->vis_grab = e_policy_visibility_client_filtered_grab_get(lc->ec, job_type, __func__);
575         lc->target.vis_grab = e_policy_visibility_client_filtered_grab_get(target_ec, E_VIS_JOB_TYPE_ALL, __func__);
576      }
577    else
578      {
579         lc->target.vis_grab = e_policy_visibility_client_filtered_grab_get(target_ec, job_type, __func__);
580      }
581
582    if (!_launcher_input_block_set(lc, EINA_TRUE))
583      ELOGF("LAUNCHER_SRV", "Input block add FAIL...", lc->ec);
584
585    _launcher_launched_ec_set(lc, NULL);
586    _launcher_target_ec_set(lc, target_ec);
587
588    lc->direction = TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD;
589    lc->serial = wl_display_next_serial(e_comp_wl->wl.disp);
590
591    sent = e_tzsh_shared_widget_launch_prepare_send(target_ec,
592                                                    TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_HIDE,
593                                                    lc->serial);
594
595    // fail to send protocol event
596    if (!sent)
597      {
598         ELOGF("LAUNCHER_SRV", "Failed to send event(PREPARE:BACKWARD)", lc->ec);
599         _launcher_post_backward(lc, EINA_FALSE);
600      }
601
602    return sent;
603 }
604
605 static Eina_Bool
606 _launcher_prepare_forward_send(E_Service_Launcher *lc,
607                                E_Client *target_ec)
608 {
609    Eina_Bool sent = EINA_FALSE;
610    int x, y;
611
612    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE);
613    EINA_SAFETY_ON_NULL_RETURN_VAL(target_ec, EINA_FALSE);
614
615    if(e_object_is_del(E_OBJECT(target_ec))) return EINA_FALSE;
616
617    e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 1);
618    e_comp_client_override_add(target_ec);
619
620    //grab uniconify job of target_ec
621    if (target_ec->iconic)
622      lc->target.vis_grab = e_policy_visibility_client_filtered_grab_get(target_ec,
623                                                                         (E_VIS_JOB_TYPE_UNICONIFY |
624                                                                          E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY),
625                                                                         __func__);
626
627    if (!_launcher_input_block_set(lc, EINA_TRUE))
628      ELOGF("LAUNCHER_SRV", "Input block add FAIL...", lc->ec);
629
630    _launcher_launched_ec_set(lc, NULL);
631    _launcher_target_ec_set(lc, target_ec);
632
633    lc->direction = TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD;
634    e_client_pos_get(target_ec, &x, &y);
635
636    sent = _launcher_prepare_send(lc, target_ec, x, y, NULL);
637
638    //fail to send protocol event
639    if (!sent)
640      {
641         ELOGF("LAUNCHER_SRV", "Failed to send event(PREPARE:FORWARD)", lc->ec);
642         _launcher_post_forward(lc, EINA_FALSE);
643      }
644
645    return sent;
646 }
647
648 static Eina_Bool
649 _launcher_prepare_backward_send(E_Service_Launcher *lc,
650                                 E_Client *activity,
651                                 E_Client *target_ec,
652                                 E_Vis_Job_Type job_type)
653 {
654    int x, y;
655    Eina_Bool sent = EINA_FALSE;
656    Eina_List *consumers;
657    Eina_List *l;
658    E_Client *ec;
659    E_Service_Launcher_Consumer *consumer;
660
661    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE);
662    EINA_SAFETY_ON_NULL_RETURN_VAL(activity, EINA_FALSE);
663    EINA_SAFETY_ON_NULL_RETURN_VAL(target_ec, EINA_FALSE);
664
665    if (e_object_is_del(E_OBJECT(target_ec)))
666      {
667         //can't do nothing if ec is deleted and there's no delay_del_ref as well.
668         if (!e_object_delay_del_ref_get(E_OBJECT(target_ec)))
669           return EINA_FALSE;
670      }
671
672    e_object_delay_del_ref(E_OBJECT(target_ec));
673    lc->target.delay_del = EINA_TRUE;
674
675    e_policy_animatable_lock(target_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 1);
676    e_comp_client_override_add(target_ec);
677
678    if ((lc->ec) && (lc->ec->remote_surface.provider))
679      {
680         consumers = e_comp_wl_remote_surface_consumers_get(lc->ec);
681         EINA_LIST_FOREACH(consumers, l, ec)
682           {
683              if (e_object_is_del(E_OBJECT(ec))) continue;
684              if (!e_policy_visibility_client_is_uniconify_render_running(ec)) continue;
685
686              consumer = _launcher_consumer_create(lc, ec);
687              consumer->vis_grab = e_policy_visibility_client_filtered_grab_get(ec,
688                                                                                (E_VIS_JOB_TYPE_UNICONIFY |
689                                                                                 E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY),
690                                                                                 __func__);
691           }
692         eina_list_free(consumers);
693      }
694
695    if (activity == target_ec)
696      {
697         lc->vis_grab = e_policy_visibility_client_filtered_grab_get(lc->ec, job_type, __func__);
698         lc->target.vis_grab = e_policy_visibility_client_filtered_grab_get(target_ec, E_VIS_JOB_TYPE_ALL, __func__);
699      }
700    else
701      {
702         lc->target.vis_grab = e_policy_visibility_client_filtered_grab_get(target_ec, job_type, __func__);
703      }
704
705    if (!_launcher_input_block_set(lc, EINA_TRUE))
706      ELOGF("LAUNCHER_SRV", "Input block add FAIL...", lc->ec);
707
708    _launcher_launched_ec_set(lc, NULL);
709    _launcher_target_ec_set(lc, target_ec);
710
711    lc->serial = wl_display_next_serial(e_comp_wl->wl.disp);
712    lc->direction = TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD;
713    e_client_pos_get(target_ec, &x, &y);
714
715    sent = _launcher_prepare_send(lc, target_ec, x, y, NULL);
716
717    //fail to send protocol event
718    if (!sent)
719      {
720         ELOGF("LAUNCHER_SRV", "Failed to send event(PREPARE:BACKWARD)", lc->ec);
721         _launcher_post_backward(lc, EINA_FALSE);
722      }
723
724    return sent;
725 }
726
727 /* Reset lc data */
728 static void
729 _launcher_data_reset(E_Service_Launcher *lc)
730 {
731    EINA_SAFETY_ON_NULL_RETURN(lc);
732
733    ELOGF("LAUNCHER_SRV", "Reset Launcher Data", lc->ec);
734
735    //clear resource and send 'DISQUALIFIED' msg
736    if (lc->res)
737      {
738         tws_service_launcher_send_error(lc->res, TWS_SERVICE_LAUNCHER_ERROR_DISQUALIFIED, lc->serial);
739         wl_resource_set_user_data(lc->res, NULL);
740         lc->res = NULL;
741      }
742
743    if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
744      _launcher_post_forward(lc, EINA_FALSE);
745    else if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
746      _launcher_post_backward(lc, EINA_FALSE);
747
748    _launcher_state_set(lc, LAUNCHER_STATE_IDLE);
749    _launcher_launched_ec_set(lc, NULL);
750    _launcher_consumers_reset(lc);
751
752    _launcher_handler_launcher_runner_unset(lc);
753    _launcher_handler_launcher_pre_runner_unset(lc);
754
755    lc->direction = 0;
756    lc->with_swl = 0;
757 }
758
759 static Eina_Bool
760 _launcher_cb_done_buff_attach(void *data, int type EINA_UNUSED, void *event)
761 {
762    E_Service_Launcher *lc;
763    E_Client *ec;
764    E_Event_Client *ev;
765
766    lc = (E_Service_Launcher*)data;
767    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, ECORE_CALLBACK_PASS_ON);
768    if (!lc->with_swl) goto clean;
769    if (lc->direction != TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD) goto clean;
770
771    ev = (E_Event_Client *)event;
772    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
773    EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
774
775    ec = ev->ec;
776    if (ec != lc->target.ec) return ECORE_CALLBACK_PASS_ON;
777    if (!lc->swl_done) goto clean;
778
779    ELOGF("LAUNCHER_SRV", "Event cb(BUFFER_CHANGE) for LAUNCH_DONE", ec);
780
781    lc->swl_done = EINA_FALSE;
782
783    _launcher_post_forward(lc, EINA_TRUE);
784
785    _launcher_handler_launcher_runner_unset(lc);
786    _launcher_handler_launcher_pre_runner_set(lc);
787    _launcher_state_set(lc, LAUNCHER_STATE_DONE);
788
789 clean:
790    E_FREE_FUNC(lc->buff_attach, ecore_event_handler_del);
791
792    return ECORE_CALLBACK_DONE;
793 }
794
795 static Eina_Bool
796 _launcher_cb_launching_consumer_buff_attach(void *data, int type EINA_UNUSED, void *event)
797 {
798    E_Service_Launcher *lc;
799    E_Service_Launcher_Consumer *consumer;
800    E_Client *ec;
801    E_Event_Client *ev;
802
803    consumer = (E_Service_Launcher_Consumer*)data;
804    EINA_SAFETY_ON_NULL_RETURN_VAL(consumer, ECORE_CALLBACK_PASS_ON);
805    lc = consumer->lc;
806    EINA_SAFETY_ON_NULL_GOTO(lc, clean);
807    EINA_SAFETY_ON_FALSE_GOTO(lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD, clean);
808
809    ev = (E_Event_Client *)event;
810    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
811    EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
812
813    ec = ev->ec;
814    if (ec != consumer->ec) return ECORE_CALLBACK_PASS_ON;
815
816    ELOGF("LAUNCHER_SRV", "Event cb(BUFFER_CHANGE) for WAIT_CONSUMER_LAUNCHING count:%d",
817           ec, consumer->buff_attach_count);
818
819    consumer->buff_attach_count++;
820    if (consumer->buff_attach_count < 2) return ECORE_CALLBACK_PASS_ON;
821
822    if (consumer->vis_grab)
823      {
824         e_policy_visibility_client_grab_release(consumer->vis_grab);
825         consumer->vis_grab = NULL;
826      }
827
828 clean:
829    _launcher_consumer_del(consumer);
830
831    return ECORE_CALLBACK_PASS_ON;
832 }
833
834 static void
835 _launcher_consumers_buffer_change_wait(E_Service_Launcher *lc)
836 {
837    E_Service_Launcher_Consumer *consumer;
838    Eina_List *l;
839
840    EINA_LIST_FOREACH(lc->consumers, l, consumer)
841      consumer->buff_attach = ecore_event_handler_add(E_EVENT_CLIENT_BUFFER_CHANGE,
842                                                      _launcher_cb_launching_consumer_buff_attach,
843                                                      consumer);
844 }
845
846 static Eina_Bool
847 _launcher_cb_launching_buff_attach(void *data, int type EINA_UNUSED, void *event)
848 {
849    E_Service_Launcher *lc;
850    E_Client *ec;
851    E_Event_Client *ev;
852
853    lc = (E_Service_Launcher*)data;
854    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, ECORE_CALLBACK_PASS_ON);
855    if (lc->direction != TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD) goto clean;
856
857    ev = (E_Event_Client *)event;
858    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
859    EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
860
861    ec = ev->ec;
862    if (ec != lc->ec) return ECORE_CALLBACK_PASS_ON;
863
864    ELOGF("LAUNCHER_SRV", "Event cb(BUFFER_CHANGE) for LAUNCHING", ec);
865
866    if (lc->state == LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER)
867      {
868         _launcher_consumers_buffer_change_wait(lc);
869         _launcher_state_set(lc, LAUNCHER_STATE_LAUNCHING);
870      }
871
872    if (lc->vis_grab)
873      {
874         e_policy_visibility_client_grab_release(lc->vis_grab);
875         lc->vis_grab = NULL;
876      }
877
878    if (lc->target.vis_grab)
879      {
880         e_policy_visibility_client_grab_release(lc->target.vis_grab);
881         lc->target.vis_grab = NULL;
882      }
883
884 clean:
885    E_FREE_FUNC(lc->buff_attach, ecore_event_handler_del);
886
887    return ECORE_CALLBACK_PASS_ON;
888 }
889
890 static void
891 _launcher_buffer_change_wait(E_Service_Launcher *lc)
892 {
893    if (!lc) return;
894    if (lc->buff_attach) return;
895
896    if (lc->state == LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER)
897      lc->buff_attach = ecore_event_handler_add(E_EVENT_CLIENT_BUFFER_CHANGE,
898                                                _launcher_cb_launching_buff_attach,
899                                                lc);
900    else if ((lc->with_swl) && (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD))
901      lc->buff_attach = ecore_event_handler_add(E_EVENT_CLIENT_BUFFER_CHANGE,
902                                                _launcher_cb_done_buff_attach,
903                                                lc);
904 }
905
906
907 static void
908 _launcher_cb_launched_ec_del(void *data, void *obj)
909 {
910    E_Service_Launcher *lc = (E_Service_Launcher *)data;
911    E_Client *launched_ec = (E_Client *)obj;
912
913    EINA_SAFETY_ON_NULL_RETURN(launched_ec);
914    EINA_SAFETY_ON_NULL_RETURN(lc);
915    EINA_SAFETY_ON_TRUE_RETURN(lc->launched_ec != launched_ec);
916
917    lc->launched_ec = NULL;
918    lc->launched_delfn = NULL;
919 }
920
921 static void
922 _launcher_cb_target_ec_del(void *data, void *obj)
923 {
924    E_Service_Launcher *lc = (E_Service_Launcher *)data;
925    E_Client *target_ec = (E_Client *)obj;
926
927    EINA_SAFETY_ON_NULL_RETURN(target_ec);
928    EINA_SAFETY_ON_NULL_RETURN(lc);
929    EINA_SAFETY_ON_TRUE_RETURN(lc->target.ec != target_ec);
930
931    lc->target.ec = NULL;
932    lc->target.delfn = NULL;
933
934    switch (lc->state)
935      {
936       case LAUNCHER_STATE_PREPARING:
937       case LAUNCHER_STATE_LAUNCHING:
938       case LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER:
939          _launcher_stop_send(lc);
940          if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
941            _launcher_post_forward(lc, EINA_FALSE);
942          else if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
943            _launcher_post_backward(lc, EINA_FALSE);
944
945          _launcher_handler_launcher_runner_unset(lc);
946          _launcher_handler_launcher_pre_runner_unset(lc);
947
948          _launcher_state_set(lc, LAUNCHER_STATE_IDLE);
949          break;
950       default:
951          break;
952      }
953 }
954
955 static void
956 _launcher_launched_ec_set(E_Service_Launcher *lc, E_Client *launched_ec)
957 {
958    EINA_SAFETY_ON_NULL_RETURN(lc);
959    if (lc->launched_ec == launched_ec) return;
960
961    if (lc->launched_ec)
962      {
963         e_object_delfn_del(E_OBJECT(lc->launched_ec), lc->launched_delfn);
964         lc->launched_ec = NULL;
965         lc->launched_delfn = NULL;
966      }
967
968    if (launched_ec)
969      {
970         lc->launched_ec = launched_ec;
971         lc->launched_delfn = e_object_delfn_add(E_OBJECT(launched_ec),
972                                                 _launcher_cb_launched_ec_del, lc);
973      }
974 }
975
976 static void
977 _launcher_target_ec_set(E_Service_Launcher *lc, E_Client *target_ec)
978 {
979    EINA_SAFETY_ON_NULL_RETURN(lc);
980    if (lc->target.ec == target_ec) return;
981
982    if (lc->target.ec)
983      {
984         e_object_delfn_del(E_OBJECT(lc->target.ec), lc->target.delfn);
985         lc->target.ec = NULL;
986         lc->target.delfn = NULL;
987      }
988
989    if (target_ec)
990      {
991         lc->target.ec = target_ec;
992         lc->target.delfn = e_object_delfn_add(E_OBJECT(target_ec),
993                                               _launcher_cb_target_ec_del, lc);
994      }
995 }
996
997 static void
998 _launcher_cb_resource_destroy(struct wl_resource *res_tws_lc)
999 {
1000    E_Service_Launcher *lc;
1001
1002    lc = wl_resource_get_user_data(res_tws_lc);
1003    if (!lc) return;
1004
1005    ELOGF("LAUNCHER_SRV", "Start Resource Destroy tws_service_launcher", lc->ec);
1006
1007    _launcher_handler_launcher_del(lc);
1008
1009    lc->res = NULL;
1010    _launcher_data_reset(lc);
1011
1012    E_FREE(lc);
1013
1014    ELOGF("LAUNCHER_SRV", "End Resource Destroy tws_service_launcher", NULL);
1015 }
1016
1017 static void
1018 _launcher_cb_destroy(struct wl_client *client EINA_UNUSED,
1019                      struct wl_resource *res_tws_lc)
1020 {
1021    ELOGF("LAUNCHER_SRV", "Received request(launcher_destroy)", NULL);
1022    wl_resource_destroy(res_tws_lc);
1023 }
1024
1025 static void
1026 _launcher_cb_launch(struct wl_client *client EINA_UNUSED,
1027                     struct wl_resource *res_tws_lc,
1028                     const char *app_id,
1029                     const char *instance_id,
1030                     int32_t pid,
1031                     uint32_t serial)
1032 {
1033    E_Service_Launcher *lc;
1034    E_Service_Launcher *runner, *pre_runner;
1035    E_Client *target_ec;
1036    Eina_List *ecs, *l;
1037    Eina_Bool sent = EINA_FALSE;
1038
1039    lc = wl_resource_get_user_data(res_tws_lc);
1040    EINA_SAFETY_ON_NULL_RETURN(lc);
1041    EINA_SAFETY_ON_NULL_RETURN(lc->ec);
1042
1043    ELOGF("LAUNCHER_SRV",
1044          "Recieved request(launcher_launch) appid:%s instance id:%s pid:%d",
1045          lc->ec, app_id?:"NONE", instance_id?:"NONE", pid);
1046
1047    EINA_SAFETY_ON_TRUE_GOTO(lc->ec->visibility.obscured == E_VISIBILITY_FULLY_OBSCURED, send_stop);
1048    EINA_SAFETY_ON_TRUE_GOTO((pid < 0) && !(app_id) , send_stop);
1049
1050    //check current state of lc
1051    runner =  _launcher_handler_launcher_runner_get();
1052    if (runner == lc)
1053      {
1054         ELOGF("LAUNCHER_SRV",
1055               "Launcher(%s) requests LAUNCH again without cancel, ignore this.",
1056               lc->ec, _launcher_state_to_str(lc->state));
1057
1058         tws_service_launcher_send_error(lc->res, TWS_SERVICE_LAUNCHER_ERROR_WRONG_REQUEST, lc->serial);
1059         return;
1060      }
1061
1062    pre_runner = _launcher_handler_launcher_pre_runner_get();
1063    if (pre_runner == lc)
1064      {
1065         _launcher_handler_launcher_pre_runner_set(NULL);
1066         _launcher_launched_ec_set(lc, NULL);
1067      }
1068
1069    lc->serial = serial;
1070    lc->target.pid = pid;
1071
1072    if (pid >= 0 )
1073      {
1074         ecs = _launcher_clients_find_by_pid(pid);
1075         EINA_LIST_FOREACH(ecs, l, target_ec)
1076           {
1077              if (e_object_is_del(E_OBJECT(target_ec))) continue;
1078              if (e_client_util_ignored_get(target_ec)) continue;
1079
1080              ELOGF("LAUNCHER_SRV", "Found target_ec:%p", lc->ec, target_ec);
1081
1082              sent = _launcher_prepare_forward_send(lc, target_ec);
1083              EINA_SAFETY_ON_FALSE_GOTO(sent, send_stop);
1084
1085              _launcher_state_set(lc, LAUNCHER_STATE_PREPARING);
1086              break;
1087           }
1088         eina_list_free(ecs);
1089      }
1090
1091    if (app_id)
1092      {
1093         lc->target.appid = eina_stringshare_add(app_id);
1094      }
1095
1096    if (!lc->target.ec)
1097      {
1098         ELOGF("LAUNCHER_SRV", "Can't find target_ec, Start Monitoring", lc->ec);
1099         _launcher_state_set(lc, LAUNCHER_STATE_MONITORING);
1100      }
1101
1102    _launcher_handler_launcher_runner_set(lc);
1103
1104    return;
1105
1106 send_stop:
1107    ELOGF("LAUNCHER_SRV", "can't process request(launcher_launch)", lc->ec);
1108    _launcher_stop_send(lc);
1109 }
1110
1111 static void
1112 _launcher_cb_launch_with_shared_widget(struct wl_client *client EINA_UNUSED,
1113                                        struct wl_resource *res_tws_lc,
1114                                        const char *app_id,
1115                                        const char *instance_id,
1116                                        int32_t pid,
1117                                        uint32_t serial)
1118 {
1119    E_Service_Launcher *lc;
1120    E_Service_Launcher *runner, *pre_runner;
1121    E_Client *target_ec;
1122    Eina_List *ecs, *l;
1123    Eina_Bool sent = EINA_FALSE;
1124
1125    lc = wl_resource_get_user_data(res_tws_lc);
1126    EINA_SAFETY_ON_NULL_RETURN(lc);
1127    EINA_SAFETY_ON_NULL_RETURN(lc->ec);
1128
1129    ELOGF("LAUNCHER_SRV",
1130          "Recieved request(launcher_launch_with_shared_widget) appid:%s instance id:%s pid:%d",
1131          lc->ec, app_id?:"NONE", instance_id?:"NONE", pid);
1132
1133    EINA_SAFETY_ON_TRUE_GOTO(lc->ec->visibility.obscured == E_VISIBILITY_FULLY_OBSCURED, send_stop);
1134    EINA_SAFETY_ON_TRUE_GOTO((pid < 0) && !(app_id), send_stop);
1135
1136    // check current state of lc
1137    runner = _launcher_handler_launcher_runner_get();
1138    if (runner == lc)
1139      {
1140         ELOGF("LAUNCHER_SRV",
1141               "Launcher(%s) requests LAUNCH again without cancel, ignore this.",
1142               lc->ec, _launcher_state_to_str(lc->state));
1143
1144         tws_service_launcher_send_error(lc->res,
1145                                         TWS_SERVICE_LAUNCHER_ERROR_WRONG_REQUEST,
1146                                         lc->serial);
1147         return;
1148      }
1149
1150    pre_runner = _launcher_handler_launcher_pre_runner_get();
1151    if (pre_runner == lc)
1152      {
1153         _launcher_handler_launcher_pre_runner_set(NULL);
1154         _launcher_launched_ec_set(lc, NULL);
1155      }
1156
1157    lc->with_swl = EINA_TRUE; /* set swl flag */
1158    lc->serial = serial;
1159    lc->target.pid = pid;
1160
1161    if (pid >= 0)
1162      {
1163         ecs = _launcher_clients_find_by_pid(pid);
1164         EINA_LIST_FOREACH(ecs, l, target_ec)
1165           {
1166              if (e_object_is_del(E_OBJECT(target_ec))) continue;
1167              if (e_client_util_ignored_get(target_ec)) continue;
1168
1169              ELOGF("LAUNCHER_SRV", "Found target_ec:%p", lc->ec, target_ec);
1170
1171              // send prepare_shared_widget event to callee
1172              sent = _launcher_prepare_shared_widget_forward_send(lc, target_ec);
1173              EINA_SAFETY_ON_FALSE_GOTO(sent, send_stop);
1174
1175              _launcher_state_set(lc, LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE);
1176              break;
1177           }
1178         eina_list_free(ecs);
1179      }
1180
1181    if (app_id)
1182      {
1183         lc->target.appid = eina_stringshare_add(app_id);
1184      }
1185
1186    if (!lc->target.ec)
1187      {
1188         ELOGF("LAUNCHER_SRV", "Can't find target_ec, Start Monitoring", lc->ec);
1189         _launcher_state_set(lc, LAUNCHER_STATE_MONITORING);
1190      }
1191
1192    _launcher_handler_launcher_runner_set(lc);
1193
1194    return;
1195
1196 send_stop:
1197    ELOGF("LAUNCHER_SRV", "can't process request(launcher_launch)", lc->ec);
1198    _launcher_stop_send(lc);
1199 }
1200
1201 static void
1202 _launcher_cb_launching(struct wl_client *client EINA_UNUSED,
1203                        struct wl_resource *res_tws_lc,
1204                        uint32_t serial)
1205 {
1206    E_Service_Launcher *lc;
1207    E_Service_Launcher *runner;
1208
1209    lc = wl_resource_get_user_data(res_tws_lc);
1210    EINA_SAFETY_ON_NULL_RETURN(lc);
1211
1212    ELOGF("LAUNCHER_SRV", "LAUNCHING(%d) %s",
1213          lc->ec, serial, lc->direction?"backward":"forward");
1214
1215    //check current state of lc
1216    runner = _launcher_handler_launcher_runner_get();
1217    if (runner != lc)
1218      {
1219         ELOGF("LAUNCHER_SRV", "lc(%p) runner(%p), lc is not runner, ignore LAUNCHING",
1220               lc->ec, lc, runner);
1221         tws_service_launcher_send_error(lc->res, TWS_SERVICE_LAUNCHER_ERROR_WRONG_REQUEST, lc->serial);
1222         return;
1223      }
1224
1225    _launcher_state_set(lc, LAUNCHER_STATE_LAUNCHING);
1226
1227    if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
1228      {
1229         _launcher_state_set(lc, LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER);
1230         _launcher_buffer_change_wait(lc);
1231      }
1232 }
1233
1234 static void
1235 _launcher_target_ec_queue_flush(E_Service_Launcher *lc)
1236 {
1237    struct wayland_tbm_client_queue *cqueue;
1238
1239    if (!e_comp_wl) return;
1240    if (!lc) return;
1241    if (!lc->target.ec) return;
1242    if (e_object_is_del(E_OBJECT(lc->target.ec))) return;
1243
1244    cqueue = e_comp_wl_tbm_client_queue_get(lc->target.ec);
1245    if (cqueue)
1246      wayland_tbm_server_client_queue_flush(cqueue);
1247 }
1248
1249 static void
1250 _launcher_cb_launch_done(struct wl_client *client EINA_UNUSED,
1251                          struct wl_resource *res_tws_lc,
1252                          uint32_t serial)
1253 {
1254    E_Service_Launcher *lc;
1255    E_Service_Launcher *runner;
1256    E_Client *target_ec = NULL;
1257    enum tws_service_launcher_direction launch_direction = 0;
1258
1259    lc = wl_resource_get_user_data(res_tws_lc);
1260    EINA_SAFETY_ON_NULL_RETURN(lc);
1261
1262    ELOGF("LAUNCHER_SRV", "LAUNCH_DONE(%d) target:%p", lc->ec, serial, lc->target.ec);
1263
1264    target_ec = lc->target.ec;
1265    launch_direction = lc->direction;
1266
1267    //check current state of lc
1268    runner = _launcher_handler_launcher_runner_get();
1269    if (runner != lc)
1270      {
1271         ELOGF("LAUNCHER_SRV", "lc(%p) runner(%p), lc is not runner, ignore LAUNCH_DONE",
1272               lc->ec, lc, runner);
1273         tws_service_launcher_send_error(lc->res, TWS_SERVICE_LAUNCHER_ERROR_WRONG_REQUEST, lc->serial);
1274         return;
1275      }
1276
1277    //shared widget launch case
1278    if (lc->with_swl)
1279      {
1280         if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
1281           {
1282              Eina_Bool sent;
1283
1284              sent = e_tzsh_shared_widget_launch_prepare_send(lc->target.ec,
1285                                                              TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_SHOW,
1286                                                              lc->serial);
1287
1288              //TODO : handle failure case
1289              if (sent)
1290                {
1291                   _launcher_buffer_change_wait(lc);
1292                   lc->swl_done = 0;
1293                }
1294
1295              return;
1296           }
1297         else if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
1298           {
1299              e_tzsh_shared_widget_launch_prepare_send(lc->target.ec,
1300                                                       TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_SHOW,
1301                                                       lc->serial);
1302              _launcher_post_backward(lc, EINA_TRUE);
1303           }
1304      }
1305    else //normal launcher
1306      {
1307         _launcher_target_ec_queue_flush(lc);
1308         if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
1309           _launcher_post_forward(lc, EINA_TRUE);
1310         else if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
1311           _launcher_post_backward(lc, EINA_TRUE);
1312      }
1313
1314    _launcher_handler_launcher_runner_unset(lc);
1315    _launcher_handler_launcher_pre_runner_set(lc);
1316    _launcher_state_set(lc, LAUNCHER_STATE_DONE);
1317
1318    if (launch_direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
1319      {
1320         if (target_ec && !e_object_is_del(E_OBJECT(target_ec)))
1321           {
1322              if (target_ec->launching == EINA_TRUE)
1323                {
1324                   ELOGF("COMP", "Un-Set launching flag..", target_ec);
1325                   target_ec->launching = EINA_FALSE;
1326
1327                   if (target_ec->first_mapped)
1328                     {
1329                        E_Comp_Wl_Client_Data *target_cdata = e_client_cdata_get(target_ec);
1330                        ELOGF("LAUNCH", "SHOW real win (target->frame:%p, map:%d) by launcher service (win:0x%08zx, ec:%p).", target_ec, target_ec->frame, target_cdata->mapped, e_client_util_win_get(lc->ec), lc->ec);
1331                        e_comp_object_signal_emit(target_ec->frame, "e,action,launch_real,done", "e");
1332                     }
1333                   e_comp_object_signal_emit(target_ec->frame, "e,action,launch,done", "e");
1334                }
1335           }
1336      }
1337 }
1338
1339 static void
1340 _launcher_cb_launch_cancel(struct wl_client *client EINA_UNUSED,
1341                            struct wl_resource *res_tws_lc,
1342                            uint32_t serial)
1343 {
1344    E_Service_Launcher *lc;
1345    E_Service_Launcher *runner;
1346
1347    lc = wl_resource_get_user_data(res_tws_lc);
1348    EINA_SAFETY_ON_NULL_RETURN(lc);
1349
1350    ELOGF("LAUNCHER_SRV", "LAUNCH_CANCEL(%d) target_ec:%p",
1351          lc->ec, serial, lc->target.ec);
1352
1353    //check state of lc
1354    runner = _launcher_handler_launcher_runner_get();
1355    if (runner != lc)
1356      {
1357         ELOGF("LAUNCHER_SRV", "lc(%p) runner(%p), lc is not runner, ignore LAUNCH_CANCEL",
1358               lc->ec, lc, runner);
1359         tws_service_launcher_send_error(lc->res, TWS_SERVICE_LAUNCHER_ERROR_WRONG_REQUEST, lc->serial);
1360         return;
1361      }
1362
1363    if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
1364      _launcher_post_forward(lc, EINA_FALSE);
1365    else if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
1366      _launcher_post_backward(lc, EINA_FALSE);
1367
1368    _launcher_handler_launcher_runner_unset(lc);
1369    _launcher_handler_launcher_pre_runner_set(lc);
1370    _launcher_state_set(lc, LAUNCHER_STATE_CANCELED);
1371 }
1372
1373 static const struct tws_service_launcher_interface _launcher_iface =
1374 {
1375    _launcher_cb_destroy,
1376    _launcher_cb_launch,
1377    _launcher_cb_launch_with_shared_widget,
1378    _launcher_cb_launching,
1379    _launcher_cb_launch_done,
1380    _launcher_cb_launch_cancel,
1381 };
1382
1383 static E_Client *
1384 _launcher_handler_rsm_provider_client_find(E_Client *rsm_consumer_ec)
1385 {
1386    E_Client *prov_ec = NULL;
1387    E_Comp_Wl_Client_Data *prov_cdata = NULL;
1388    Eina_List *tzrs_provs, *l;
1389    E_Service_Launcher *lc;
1390
1391    if (!rsm_consumer_ec->remote_surface.consumer) return NULL;
1392
1393    tzrs_provs = e_comp_wl_remote_surface_providers_get(rsm_consumer_ec);
1394    if (!tzrs_provs) return NULL;
1395
1396    EINA_LIST_FOREACH(tzrs_provs, l, prov_ec)
1397      {
1398         /* check remote surface provider */
1399         if (!prov_ec->remote_surface.provider) continue;
1400         if (prov_ec->visible) continue;
1401         if (evas_object_visible_get(prov_ec->frame)) continue;
1402         prov_cdata = e_client_cdata_get(prov_ec);
1403         if (prov_cdata->mapped) continue;
1404         if (!(lc = _launcher_handler_launcher_find(prov_ec))) continue;
1405         if (!lc->launched_ec) continue;
1406
1407         ELOGF("LAUNCHER_SRV", "Found prov_ec:%p", rsm_consumer_ec, prov_ec);
1408         break;
1409      }
1410    eina_list_free(tzrs_provs);
1411
1412    return prov_ec;
1413 }
1414
1415 static E_Service_Launcher *
1416 _launcher_handler_launcher_find(E_Client *ec)
1417 {
1418    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1419    EINA_SAFETY_ON_NULL_RETURN_VAL(_laundler, NULL);
1420    EINA_SAFETY_ON_NULL_RETURN_VAL(_laundler->launcher_hash, NULL);
1421
1422    return eina_hash_find(_laundler->launcher_hash, &ec);
1423 }
1424
1425 static Eina_Bool
1426 _launcher_handler_launcher_add(E_Service_Launcher *lc)
1427 {
1428    Eina_Bool ret;
1429
1430    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE);
1431    EINA_SAFETY_ON_NULL_RETURN_VAL(lc->ec, EINA_FALSE);
1432    EINA_SAFETY_ON_NULL_RETURN_VAL(_laundler, EINA_FALSE);
1433    EINA_SAFETY_ON_NULL_RETURN_VAL(_laundler->launcher_hash, EINA_FALSE);
1434
1435    ret = eina_hash_add(_laundler->launcher_hash, &lc->ec, lc);
1436    if (ret)
1437      _laundler->launcher_count++;
1438
1439    return ret;
1440 }
1441
1442 static Eina_Bool
1443 _launcher_handler_launcher_del(E_Service_Launcher *lc)
1444 {
1445    Eina_Bool ret;
1446
1447    EINA_SAFETY_ON_NULL_RETURN_VAL(lc, EINA_FALSE);
1448    EINA_SAFETY_ON_NULL_RETURN_VAL(lc->ec, EINA_FALSE);
1449    EINA_SAFETY_ON_NULL_RETURN_VAL(_laundler, EINA_FALSE);
1450    EINA_SAFETY_ON_NULL_RETURN_VAL(_laundler->launcher_hash, EINA_FALSE);
1451
1452    ret = eina_hash_del(_laundler->launcher_hash, &lc->ec, lc);
1453    if (ret) _laundler->launcher_count--;
1454
1455    return ret;
1456 }
1457
1458 static void
1459 _launcher_handler_launcher_runner_set(E_Service_Launcher *lc)
1460 {
1461    E_Service_Launcher *runner = NULL;
1462
1463    EINA_SAFETY_ON_NULL_RETURN(_laundler);
1464    if (_laundler->runner == lc) return;
1465
1466    //reset previous runner
1467    runner = _laundler->runner;
1468    if (runner)
1469      {
1470         switch (runner->state)
1471           {
1472            case LAUNCHER_STATE_PREPARING:
1473            case LAUNCHER_STATE_LAUNCHING:
1474            case LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER:
1475               _launcher_state_set(runner, LAUNCHER_STATE_CANCELED);
1476               _launcher_stop_send(runner);
1477               if (runner->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
1478                 _launcher_post_forward(runner, EINA_FALSE);
1479               else if (runner->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
1480                 _launcher_post_backward(runner, EINA_FALSE);
1481               break;
1482            case LAUNCHER_STATE_MONITORING:
1483               _launcher_state_set(runner, LAUNCHER_STATE_CANCELED);
1484               _launcher_stop_send(runner);
1485               runner->target.pid = -1;
1486               runner->target.ec = NULL;
1487               E_FREE_FUNC(runner->target.appid, eina_stringshare_del);
1488               E_FREE_FUNC(runner->target.splash_path, eina_stringshare_del);
1489               E_FREE_FUNC(runner->target.splash_group, eina_stringshare_del);
1490               break;
1491            default:
1492               break;
1493           }
1494         _launcher_handler_launcher_pre_runner_set(runner);
1495      }
1496
1497    ELOGF("LAUNCHER_SRV", "runner change %p(ec:%p) to %p(ec:%p)",
1498          NULL, runner, runner?runner->ec:NULL, lc, lc?lc->ec:NULL);
1499
1500    _laundler->runner = lc;
1501 }
1502
1503 static void
1504 _launcher_handler_launcher_runner_unset(E_Service_Launcher *lc)
1505 {
1506    EINA_SAFETY_ON_NULL_RETURN(_laundler);
1507    if (_laundler->runner != lc) return;
1508
1509    _laundler->runner = NULL;
1510
1511    ELOGF("LAUNCHER_SRV", "runner unset %p(ec:%p)",
1512          NULL, lc, lc?lc->ec:NULL);
1513 }
1514
1515 static E_Service_Launcher *
1516 _launcher_handler_launcher_runner_get(void)
1517 {
1518    EINA_SAFETY_ON_NULL_RETURN_VAL(_laundler, NULL);
1519    return _laundler->runner;
1520 }
1521
1522 static void
1523 _launcher_handler_launcher_pre_runner_set(E_Service_Launcher *lc)
1524 {
1525    E_Service_Launcher *pre_runner = NULL;
1526
1527    EINA_SAFETY_ON_NULL_RETURN(_laundler);
1528
1529    pre_runner = _laundler->pre_runner;
1530    if (pre_runner == lc) return;
1531    if (pre_runner)
1532      {
1533         if (pre_runner->launched_ec)
1534           e_policy_animatable_lock(pre_runner->launched_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 0);
1535         _launcher_state_set(pre_runner, LAUNCHER_STATE_IDLE);
1536      }
1537
1538    _laundler->pre_runner = lc;
1539
1540    ELOGF("LAUNCHER_SRV", "pre_runner change %p(ec:%p) to %p(ec:%p)",
1541          NULL, pre_runner, pre_runner?pre_runner->ec:NULL, lc, lc?lc->ec:NULL);
1542 }
1543
1544 static void
1545 _launcher_handler_launcher_pre_runner_unset(E_Service_Launcher *lc)
1546 {
1547    EINA_SAFETY_ON_NULL_RETURN(_laundler);
1548    if (_laundler->pre_runner != lc) return;
1549
1550    _laundler->pre_runner = NULL;
1551
1552    ELOGF("LAUNCHER_SRV", "pre_runner unset %p(ec:%p)",
1553          NULL, lc, lc?lc->ec:NULL);
1554 }
1555
1556 static E_Service_Launcher *
1557 _launcher_handler_launcher_pre_runner_get(void)
1558 {
1559    EINA_SAFETY_ON_NULL_RETURN_VAL(_laundler, NULL);
1560    return _laundler->pre_runner;
1561 }
1562
1563 static Eina_Bool
1564 _launcher_handler_cb_hook_vis_uniconify_render_running(void *data EINA_UNUSED, E_Client *ec)
1565 {
1566    E_Service_Launcher *lc = NULL;
1567    E_Service_Launcher *runner, *pre_runner = NULL;
1568    E_Client *activity = NULL, *prov_ec = NULL;
1569    Launcher_State new_state;
1570
1571    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1572
1573    lc = _launcher_handler_launcher_find(ec);
1574    if (!lc)
1575      {
1576         prov_ec = _launcher_handler_rsm_provider_client_find(ec);
1577         if (prov_ec)
1578           {
1579              /* find launcher handler again with provider ec */
1580              lc = _launcher_handler_launcher_find(prov_ec);
1581              /* set rsm provider ec pointer value to given ec (rsm consumer) */
1582              ec = prov_ec;
1583           }
1584      }
1585    if (!lc) return EINA_TRUE;
1586
1587    activity = e_policy_visibility_main_activity_get();
1588    EINA_SAFETY_ON_NULL_RETURN_VAL(activity, EINA_TRUE);
1589
1590    if (ec == lc->ec)
1591      {
1592         ELOGF("LAUNCHER_SRV", "Hook uniconify render begin target.ec:%p activity:%p launched_ec:%p",
1593               ec, lc->target.ec, activity, lc->launched_ec);
1594
1595         if (activity == lc->launched_ec)
1596           {
1597              int sent = EINA_FALSE;
1598
1599              ELOGF("LAUNCHER_SRV", "Current activity(%p, is_del:%d) was launched by launcher.",
1600                    ec, activity, e_object_is_del(E_OBJECT(activity)));
1601
1602              //check state of lc
1603              runner =  _launcher_handler_launcher_runner_get();
1604              if (runner == lc)
1605                {
1606                   ELOGF("LAUNCHER_SRV",
1607                         "Launcher(%s) is already runner, do nothing",
1608                         lc->ec, _launcher_state_to_str(lc->state));
1609                   return EINA_TRUE;
1610                }
1611
1612              pre_runner = _launcher_handler_launcher_pre_runner_get();
1613              if (pre_runner ==  lc)
1614                {
1615                   _launcher_handler_launcher_pre_runner_set(NULL);
1616                }
1617
1618              if (lc->with_swl)
1619                {
1620                   sent = _launcher_prepare_shared_widget_backward_send
1621                      (lc, activity, activity,
1622                       (E_VIS_JOB_TYPE_UNICONIFY |
1623                        E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY));
1624
1625                   new_state = LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE;
1626                }
1627              else
1628                {
1629                   sent = _launcher_prepare_backward_send
1630                      (lc, activity, activity,
1631                       (E_VIS_JOB_TYPE_UNICONIFY |
1632                        E_VIS_JOB_TYPE_UNICONIFY_BY_VISIBILITY));
1633
1634                   new_state = LAUNCHER_STATE_PREPARING;
1635                }
1636
1637
1638              if (!sent) return EINA_FALSE;
1639
1640              _launcher_state_set(lc, new_state);
1641              _launcher_handler_launcher_runner_set(lc);
1642           }
1643      }
1644
1645    return EINA_TRUE;
1646 }
1647
1648 static Eina_Bool
1649 _launcher_handler_cb_hook_vis_lower(void *data EINA_UNUSED, E_Client *ec)
1650 {
1651    E_Service_Launcher *lc = NULL;
1652    E_Service_Launcher *runner, *pre_runner;
1653    E_Client *activity = NULL, *prov_ec = NULL;
1654    Launcher_State new_state;
1655
1656    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1657
1658    activity = e_policy_visibility_main_activity_get();
1659    EINA_SAFETY_ON_NULL_RETURN_VAL(activity, EINA_FALSE);
1660
1661    lc = _launcher_handler_launcher_find(activity);
1662    if (!lc)
1663      {
1664         prov_ec = _launcher_handler_rsm_provider_client_find(activity);
1665         if (prov_ec)
1666           {
1667              /* find launcher handler again with provider activity */
1668              lc = _launcher_handler_launcher_find(prov_ec);
1669           }
1670      }
1671    if (!lc) return EINA_FALSE;
1672
1673    if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) return EINA_FALSE;
1674
1675    if (ec == lc->launched_ec)
1676      {
1677         Eina_Bool sent = EINA_FALSE;
1678         ELOGF("LAUNCHER_SRV", "Lower hook of launched_ec(%p)", lc->ec, ec);
1679
1680         //check state of lc
1681         runner =  _launcher_handler_launcher_runner_get();
1682         if (runner == lc)
1683           {
1684              ELOGF("LAUNCHER_SRV",
1685                    "Launcher(%s) is already runner, do nothing",
1686                    lc->ec, _launcher_state_to_str(lc->state));
1687              return EINA_FALSE;
1688           }
1689
1690         pre_runner = _launcher_handler_launcher_pre_runner_get();
1691         if (pre_runner ==  lc)
1692           {
1693              _launcher_handler_launcher_pre_runner_set(NULL);
1694           }
1695
1696         if (lc->with_swl)
1697           {
1698              sent = _launcher_prepare_shared_widget_backward_send(lc, activity, ec, E_VIS_JOB_TYPE_LOWER);
1699              new_state = LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE;
1700           }
1701         else
1702           {
1703              sent = _launcher_prepare_backward_send(lc, activity, ec, E_VIS_JOB_TYPE_LOWER);
1704              new_state = LAUNCHER_STATE_PREPARING;
1705           }
1706
1707         if (!sent) return EINA_FALSE;
1708
1709         _launcher_state_set(lc, new_state);
1710         _launcher_handler_launcher_runner_set(lc);
1711      }
1712
1713    return EINA_TRUE;
1714 }
1715
1716 static Eina_Bool
1717 _launcher_handler_cb_hook_vis_hide(void *data EINA_UNUSED, E_Client *ec)
1718 {
1719    E_Service_Launcher *lc = NULL;
1720    E_Service_Launcher *runner, *pre_runner;
1721    E_Client *activity = NULL, *prov_ec = NULL;
1722    Launcher_State new_state;
1723
1724    EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1725
1726    activity = e_policy_visibility_main_activity_get();
1727    EINA_SAFETY_ON_NULL_RETURN_VAL(activity, EINA_FALSE);
1728
1729    lc = _launcher_handler_launcher_find(activity);
1730    if (!lc)
1731      {
1732         prov_ec = _launcher_handler_rsm_provider_client_find(activity);
1733         if (prov_ec)
1734           {
1735              /* find launcher handler again with provider ec */
1736              lc = _launcher_handler_launcher_find(prov_ec);
1737           }
1738         else
1739           {
1740              /* Backward case
1741               *
1742               * activity: callee ec
1743               * given ec: callee ec (transient_for child)  <-- destroying by back key
1744               *           caller ec (transient_for parent) <-- will be shown
1745               *
1746               * In this case, the given ec is a callee ec and is transient_for with caller ec (lc) by
1747               * group launching. Also, because of transient_for, caller ec is not iconified.
1748               * Since the given ec is destroyed by the back key, we can't find out caller ec(lc) with activity and given ec.
1749               * We have to use transient_for to find caller ec(lc).
1750               */
1751              if (ec->parent)
1752                {
1753                   ELOGF("LAUNCHER_SRV", "Hide hook of ec->parent(%p)", ec, ec->parent);
1754                   lc = _launcher_handler_launcher_find(ec->parent);
1755                   if ((lc) && (lc->launched_ec != ec)) lc = NULL;
1756                }
1757              else
1758                {
1759                   ELOGF("LAUNCHER_SRV", "Hide hook of ec->parent(NULL)", ec);
1760                }
1761           }
1762      }
1763    if (!lc) return EINA_FALSE;
1764
1765    if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) return EINA_FALSE;
1766
1767    if (ec == lc->launched_ec)
1768      {
1769         Eina_Bool sent = EINA_FALSE;
1770         ELOGF("LAUNCHER_SRV", "Hide hook of launched_ec(%p)", lc->ec, ec);
1771
1772         //check state of lc
1773         runner =  _launcher_handler_launcher_runner_get();
1774         if (runner == lc)
1775           {
1776              ELOGF("LAUNCHER_SRV",
1777                    "Launcher(%s) is already runner, do nothing",
1778                    lc->ec, _launcher_state_to_str(lc->state));
1779              return EINA_FALSE;
1780           }
1781
1782         pre_runner = _launcher_handler_launcher_pre_runner_get();
1783         if (pre_runner ==  lc)
1784           {
1785              _launcher_handler_launcher_pre_runner_set(NULL);
1786           }
1787
1788         if (lc->with_swl)
1789           {
1790              sent = _launcher_prepare_shared_widget_backward_send(lc, activity, ec, E_VIS_JOB_TYPE_HIDE);
1791              new_state = LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE;
1792           }
1793         else
1794           {
1795              sent = _launcher_prepare_backward_send(lc, activity, ec, E_VIS_JOB_TYPE_HIDE);
1796              new_state = LAUNCHER_STATE_PREPARING;
1797           }
1798         if (!sent) return EINA_FALSE;
1799
1800         _launcher_state_set(lc, new_state);
1801         _launcher_handler_launcher_runner_set(lc);
1802      }
1803
1804    return EINA_TRUE;
1805 }
1806
1807 static void
1808 _launcher_handler_cb_hook_client_del(void *data EINA_UNUSED, E_Client *ec)
1809 {
1810    E_Service_Launcher *lc;
1811
1812    EINA_SAFETY_ON_NULL_RETURN(ec);
1813
1814    lc = _launcher_handler_launcher_find(ec);
1815    if (!lc) return;
1816
1817    if (lc->ec == ec) //launcher surface is gone.
1818      {
1819         _launcher_handler_launcher_del(lc);
1820         _launcher_data_reset(lc);
1821         E_FREE(lc);
1822      }
1823 }
1824
1825 static Eina_Bool
1826 _launcher_handler_cb_hook_intercept_show_helper(void *data, E_Client *ec)
1827 {
1828    E_Service_Launcher *runner;
1829    Eina_Bool sent = EINA_FALSE;
1830
1831    runner = _launcher_handler_launcher_runner_get();
1832
1833    if (!runner) goto show_allow;
1834    EINA_SAFETY_ON_NULL_GOTO(ec, show_allow);
1835
1836    if (ec->new_client) goto show_allow;
1837
1838    switch (runner->state)
1839      {
1840       case LAUNCHER_STATE_LAUNCHING_WAIT_BUFFER:  //waiting buffer change
1841          if (ec == runner->ec)
1842            goto show_deny;
1843          break;
1844       case LAUNCHER_STATE_PREPARING:              //waiting launcher client's preparation
1845       case LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE:
1846          if (ec  == runner->target.ec) goto show_deny;
1847          break;
1848       case LAUNCHER_STATE_LAUNCHING:              //doing animation
1849          if (ec == runner->target.ec) goto show_deny; //don't show launched app window
1850          else if (ec == runner->ec) goto show_allow;  //show launcher
1851          break;
1852       case LAUNCHER_STATE_MONITORING:             //waiting creation of target window
1853          if ((runner->target.pid >= 0) && (ec->netwm.pid != runner->target.pid)) goto show_allow; //detect by pid
1854          if ((runner->target.appid) && (runner->target.ec) && (runner->target.ec != ec)) goto show_allow; //detect by appid
1855          if ((runner->target.appid) && (runner->target.pid < 0) && (!runner->target.ec)) goto show_allow; //not enough info
1856          if (e_object_is_del(E_OBJECT(ec))) goto show_allow;
1857
1858          if (runner->with_swl)
1859            {
1860               sent = _launcher_prepare_shared_widget_forward_send(runner, ec);
1861               EINA_SAFETY_ON_FALSE_GOTO(sent, send_stop);
1862
1863               _launcher_state_set(runner, LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE);
1864            }
1865          else
1866            {
1867               sent = _launcher_prepare_forward_send(runner, ec);
1868               EINA_SAFETY_ON_FALSE_GOTO(sent, send_stop);
1869
1870               _launcher_state_set(runner, LAUNCHER_STATE_PREPARING);
1871            }
1872          goto show_deny;
1873       default:
1874          goto show_allow;
1875      }
1876
1877 show_allow:
1878    return EINA_TRUE;
1879 show_deny:
1880    return EINA_FALSE;
1881 send_stop:
1882    runner->target.pid = -1;
1883    runner->serial = 0;
1884    runner->target.ec = NULL;
1885    E_FREE_FUNC(runner->target.appid, eina_stringshare_del);
1886    E_FREE_FUNC(runner->target.splash_path, eina_stringshare_del);
1887    E_FREE_FUNC(runner->target.splash_group, eina_stringshare_del);
1888
1889    _launcher_stop_send(runner);
1890    _launcher_state_set(runner, LAUNCHER_STATE_IDLE);
1891    _launcher_handler_launcher_runner_unset(runner);
1892    return EINA_TRUE;
1893 }
1894
1895 static void _launcher_handler_cb_hook_appinfo_pid_set(const char *appid, pid_t pid, void *data)
1896 {
1897    E_Service_Launcher *runner;
1898
1899    EINA_SAFETY_ON_NULL_RETURN(appid);
1900    EINA_SAFETY_ON_TRUE_RETURN(pid < 0);
1901
1902    runner = _launcher_handler_launcher_runner_get();
1903    if (!runner) return;
1904    if (runner->state != LAUNCHER_STATE_MONITORING) return;
1905
1906    if (runner->target.appid)
1907      {
1908         if (!e_util_strcmp(appid, runner->target.appid))
1909           {
1910              runner->target.pid = pid;
1911
1912              ELOGF("LAUNCHER_SRV", "Register callee pid:%d by appid(%s)",
1913                    runner->ec, pid, runner->target.appid);
1914           }
1915      }
1916 }
1917
1918 static Eina_Bool
1919 _launcher_handler_cb_event_client_show(void *data, int type EINA_UNUSED, void *event)
1920 {
1921    E_Service_Launcher *runner, *pre_runner;
1922    E_Client *ec;
1923    E_Event_Client *ev;
1924
1925    runner = _launcher_handler_launcher_runner_get();
1926    if (!runner) return ECORE_CALLBACK_PASS_ON;
1927
1928    ev = (E_Event_Client *)event;
1929    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
1930    EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
1931
1932    ec = ev->ec;
1933
1934    switch (runner->state)
1935      {
1936       case LAUNCHER_STATE_MONITORING:
1937          if (ec->netwm.pid == runner->target.pid)
1938            goto send_stop;
1939          break;
1940       case LAUNCHER_STATE_PREPARING:
1941          if (runner->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
1942            {
1943               if (ec == runner->target.ec)  goto send_stop;
1944            }
1945          else if (runner->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
1946            {
1947               if (ec == runner->ec) goto send_stop;
1948            }
1949          break;
1950       case LAUNCHER_STATE_LAUNCHING:
1951          if (runner->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
1952            {
1953               if (ec == runner->target.ec) goto send_stop;
1954            }
1955          break;
1956       default:
1957          break;
1958      }
1959
1960    pre_runner = _launcher_handler_launcher_pre_runner_get();
1961    if (pre_runner)
1962      {
1963         switch (pre_runner->state)
1964           {
1965            case LAUNCHER_STATE_DONE:
1966               if (ec == pre_runner->launched_ec)
1967                 _launcher_handler_launcher_pre_runner_set(NULL);
1968               break;
1969            case LAUNCHER_STATE_CANCELED:
1970               _launcher_handler_launcher_pre_runner_set(NULL);
1971               break;
1972            default:
1973               break;
1974           }
1975      }
1976
1977    return ECORE_CALLBACK_PASS_ON;
1978
1979 send_stop:
1980    ELOGF("LAUNCHER_SRV", "CLIENT SHOW: Failure Case runner:%p", ec, runner);
1981
1982    _launcher_stop_send(runner);
1983
1984    if (runner->state == LAUNCHER_STATE_MONITORING)
1985      {
1986         runner->target.pid = -1;
1987         runner->serial = 0;
1988      }
1989    else if (runner->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
1990      _launcher_post_forward(runner, EINA_FALSE);
1991    else if (runner->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
1992      _launcher_post_backward(runner, EINA_FALSE);
1993
1994    _launcher_state_set(runner, LAUNCHER_STATE_IDLE);
1995    _launcher_handler_launcher_runner_unset(runner);
1996
1997    return ECORE_CALLBACK_PASS_ON;
1998 }
1999
2000 static Eina_Bool
2001 _launcher_handler_cb_event_client_visibility_change(void *data, int type EINA_UNUSED, void *event)
2002 {
2003    E_Service_Launcher *pre_runner;
2004    E_Client *ec;
2005    E_Event_Client *ev;
2006
2007    ev = (E_Event_Client *)event;
2008    EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
2009    EINA_SAFETY_ON_NULL_RETURN_VAL(ev->ec, ECORE_CALLBACK_PASS_ON);
2010
2011    ec = ev->ec;
2012    if (ec->visibility.obscured != E_VISIBILITY_UNOBSCURED)
2013      return ECORE_CALLBACK_PASS_ON;
2014
2015    pre_runner = _launcher_handler_launcher_pre_runner_get();
2016    if (pre_runner)
2017      {
2018         switch (pre_runner->state)
2019           {
2020            case LAUNCHER_STATE_DONE:
2021            case LAUNCHER_STATE_CANCELED:
2022               if (pre_runner->launched_ec)
2023                 {
2024                    if (pre_runner->launched_ec == ec)
2025                      {
2026                         e_policy_animatable_lock(pre_runner->launched_ec, E_POLICY_ANIMATABLE_CUSTOMIZED, 0);
2027                      }
2028                 }
2029               break;
2030            default:
2031               break;
2032           }
2033      }
2034
2035    return ECORE_CALLBACK_PASS_ON;
2036 }
2037
2038 #undef  LAUNCHER_HANDLER_CB_ADD
2039 #define LAUNCHER_HANDLER_CB_ADD(l, appender, event_type, cb, data)  \
2040   do                                                                \
2041     {                                                               \
2042        void *_h;                                                    \
2043        _h = appender(event_type, cb, data);                         \
2044        assert(_h);                                                  \
2045        l = eina_list_append(l, _h);                                 \
2046     }                                                               \
2047   while (0)
2048
2049
2050 static E_Service_Launcher_Handler *
2051 _launcher_handler_create(void)
2052 {
2053    E_Service_Launcher_Handler *laundler = NULL;
2054
2055    laundler = E_NEW(E_Service_Launcher_Handler, 1);
2056    EINA_SAFETY_ON_NULL_RETURN_VAL(laundler, NULL);
2057
2058    laundler->launcher_count = 0;
2059    laundler->launcher_hash = eina_hash_pointer_new(NULL);
2060
2061    LAUNCHER_HANDLER_CB_ADD(laundler->hooks_vis,
2062                            e_policy_visibility_hook_add,
2063                            E_POL_VIS_HOOK_TYPE_UNICONIFY_RENDER_RUNNING,
2064                            _launcher_handler_cb_hook_vis_uniconify_render_running, NULL);
2065
2066    LAUNCHER_HANDLER_CB_ADD(laundler->hooks_vis,
2067                            e_policy_visibility_hook_add,
2068                            E_POL_VIS_HOOK_TYPE_LOWER,
2069                            _launcher_handler_cb_hook_vis_lower, NULL);
2070
2071    LAUNCHER_HANDLER_CB_ADD(laundler->hooks_vis,
2072                            e_policy_visibility_hook_add,
2073                            E_POL_VIS_HOOK_TYPE_HIDE,
2074                            _launcher_handler_cb_hook_vis_hide, NULL);
2075
2076    LAUNCHER_HANDLER_CB_ADD(laundler->hooks_ec,
2077                            e_client_hook_add,
2078                            E_CLIENT_HOOK_DEL,
2079                            _launcher_handler_cb_hook_client_del, NULL);
2080
2081    LAUNCHER_HANDLER_CB_ADD(laundler->hooks_co,
2082                            e_comp_object_intercept_hook_add,
2083                            E_COMP_OBJECT_INTERCEPT_HOOK_SHOW_HELPER,
2084                            _launcher_handler_cb_hook_intercept_show_helper, NULL);
2085
2086    LAUNCHER_HANDLER_CB_ADD(laundler->hooks_appinfo,
2087                            e_appinfo_hook_add,
2088                            E_APPINFO_HOOK_PID_SET,
2089                            _launcher_handler_cb_hook_appinfo_pid_set, NULL);
2090
2091    LAUNCHER_HANDLER_CB_ADD(laundler->hdlrs_ev,
2092                            ecore_event_handler_add,
2093                            E_EVENT_CLIENT_SHOW,
2094                            _launcher_handler_cb_event_client_show, NULL);
2095
2096    LAUNCHER_HANDLER_CB_ADD(laundler->hdlrs_ev,
2097                            ecore_event_handler_add,
2098                            E_EVENT_CLIENT_VISIBILITY_CHANGE,
2099                            _launcher_handler_cb_event_client_visibility_change, NULL);
2100
2101    ELOGF("LAUNCHER_SRV", "new launcher handler(%p) created", NULL, laundler);
2102
2103    return laundler;
2104 }
2105
2106 static void
2107 _launcher_handler_destroy(E_Service_Launcher_Handler *laundler)
2108 {
2109    EINA_SAFETY_ON_NULL_RETURN(laundler);
2110
2111    E_FREE_LIST(laundler->hdlrs_ev, ecore_event_handler_del);
2112    E_FREE_LIST(laundler->hooks_appinfo, e_appinfo_hook_del);
2113    E_FREE_LIST(laundler->hooks_co, e_comp_object_intercept_hook_del);
2114    E_FREE_LIST(laundler->hooks_ec, e_client_hook_del);
2115    E_FREE_LIST(laundler->hooks_vis, e_policy_visibility_hook_del);
2116
2117    E_FREE_FUNC(laundler->launcher_hash, eina_hash_free);
2118    E_FREE(laundler);
2119 }
2120
2121 EINTERN void
2122 e_service_launcher_resource_set(E_Client *ec, struct wl_resource *res_tws_lc)
2123 {
2124    E_Service_Launcher *lc;
2125
2126    EINA_SAFETY_ON_NULL_RETURN(ec);
2127    EINA_SAFETY_ON_NULL_RETURN(res_tws_lc);
2128
2129    lc = _launcher_handler_launcher_find(ec);
2130    EINA_SAFETY_ON_NULL_RETURN(lc);
2131    EINA_SAFETY_ON_TRUE_RETURN(lc->ec != ec);
2132
2133    if (lc->res)
2134      _launcher_data_reset(lc);
2135
2136    lc->res = res_tws_lc;
2137    wl_resource_set_implementation(res_tws_lc,
2138                                   &_launcher_iface, lc,
2139                                   _launcher_cb_resource_destroy);
2140 }
2141
2142 EINTERN void
2143 e_service_launcher_client_set(E_Client *ec)
2144 {
2145    E_Service_Launcher *lc = NULL;
2146
2147    EINA_SAFETY_ON_NULL_RETURN(ec);
2148    EINA_SAFETY_ON_TRUE_RETURN(e_object_is_del(E_OBJECT(ec)));
2149
2150    if ((lc = _launcher_handler_launcher_find(ec)))
2151      {
2152         ELOGF("LAUNCHER_SRV", "ec(%p) is already set as launcher(%p)",
2153               ec, ec, lc);
2154         return;
2155      }
2156
2157    if (!_laundler)
2158      {
2159         _laundler = _launcher_handler_create();
2160         EINA_SAFETY_ON_NULL_RETURN(_laundler);
2161      }
2162
2163    lc = E_NEW(E_Service_Launcher, 1);
2164    EINA_SAFETY_ON_NULL_RETURN(lc);
2165
2166    lc->ec = ec;
2167    if (!_launcher_handler_launcher_add(lc))
2168      {
2169         E_FREE(lc);
2170         ELOGF("LAUNCHER_SRV", "Fail to add launcher", ec);
2171         return;
2172      }
2173
2174    ELOGF("LAUNCHER_SRV", "client set|Created New Launcher(%p)", ec, lc);
2175    _launcher_state_set(lc, LAUNCHER_STATE_IDLE);
2176
2177    return;
2178 }
2179
2180 EINTERN void
2181 e_service_launcher_client_unset(E_Client *ec)
2182 {
2183    E_Service_Launcher *lc;
2184
2185    EINA_SAFETY_ON_NULL_RETURN(ec);
2186
2187    lc = _launcher_handler_launcher_find(ec);
2188    EINA_SAFETY_ON_NULL_RETURN(lc);
2189
2190    _launcher_handler_launcher_del(lc);
2191    _launcher_data_reset(lc);
2192    E_FREE(lc);
2193
2194    ELOGF("LAUNCHER_SRV", "client unset", ec);
2195
2196    if ((_laundler) && (_laundler->launcher_count == 0))
2197      {
2198         ELOGF("LAUNCHER_SRV", "No launcher available, Destroy Launcher Handler(%p)",
2199               NULL, _laundler);
2200
2201         _launcher_handler_destroy(_laundler);
2202         _laundler = NULL;
2203      }
2204 }
2205
2206 EINTERN void
2207 e_service_launcher_prepare_send_with_shared_widget_info(E_Client *target_ec,
2208                                                         const char *shared_widget_info,
2209                                                         uint32_t state,
2210                                                         uint32_t serial)
2211 {
2212    E_Service_Launcher *lc = NULL;
2213    Eina_Bool sent;
2214    int x, y;
2215    Eina_Iterator *hash_iter;
2216    Eina_Bool found = EINA_FALSE;
2217
2218    EINA_SAFETY_ON_NULL_RETURN(_laundler);
2219
2220    /* look for launcher service object which has given target_ec */
2221    hash_iter = eina_hash_iterator_data_new(_laundler->launcher_hash);
2222    EINA_ITERATOR_FOREACH(hash_iter, lc)
2223      {
2224         if (lc->target.ec != target_ec) continue;
2225         if (lc->serial != serial) continue;
2226         found = EINA_TRUE;
2227         break;
2228      }
2229    eina_iterator_free(hash_iter);
2230
2231    EINA_SAFETY_ON_FALSE_RETURN(found);
2232    EINA_SAFETY_ON_NULL_RETURN(lc);
2233
2234    ELOGF("LAUNCHER_SRV", "SWL | callee(%p) cb(PREPARE_DONE(%d))",
2235          lc->ec, target_ec, state);
2236
2237    if (state == TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_HIDE)
2238      {
2239         e_client_pos_get(target_ec, &x, &y);
2240
2241         sent = _launcher_prepare_send(lc, target_ec, x, y, shared_widget_info);
2242         EINA_SAFETY_ON_FALSE_GOTO(sent, error);
2243
2244         _launcher_state_set(lc, LAUNCHER_STATE_PREPARING);
2245      }
2246    else if (state == TWS_SHARED_WIDGET_LAUNCH_PREPARE_STATE_WIDGET_SHOW)
2247      {
2248         if (!lc->buff_attach)
2249           {
2250              if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
2251                _launcher_post_forward(lc, EINA_TRUE);
2252              else if (lc->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
2253                _launcher_post_backward(lc, EINA_TRUE);
2254
2255              _launcher_handler_launcher_runner_unset(lc);
2256              _launcher_handler_launcher_pre_runner_set(lc);
2257              _launcher_state_set(lc, LAUNCHER_STATE_DONE);
2258           }
2259
2260         lc->swl_done = EINA_TRUE;
2261
2262         ELOGF("LAUNCHER_SRV", "SWL | send CLEANUP", lc->ec);
2263         tws_service_launcher_send_cleanup(lc->res,
2264                                           lc->serial);
2265      }
2266
2267    return;
2268
2269 error:
2270    ELOGF("LAUNCHER_SRV", "Failed to send event(PREPARE:FORWARD)", lc->ec);
2271    _launcher_post_forward(lc, EINA_FALSE);
2272 }
2273
2274 EINTERN void
2275 e_service_launcher_release_shared_widget_launch(E_Client *ec)
2276 {
2277    E_Service_Launcher *runner;
2278
2279    EINA_SAFETY_ON_NULL_RETURN(ec);
2280
2281    runner = _launcher_handler_launcher_runner_get();
2282    EINA_SAFETY_ON_NULL_RETURN(runner);
2283
2284    ELOGF("LAUNCHER_SRV", "Released tzsh_swl", ec);
2285
2286    if ((runner) && (runner->target.ec == ec))
2287      {
2288         if (runner->with_swl)
2289           {
2290              //callee is gone before replying prepare_done
2291              if (runner->state == LAUNCHER_STATE_WAIT_RESPONSE_FROM_CALLEE)
2292                {
2293                   if (runner->direction == TWS_SERVICE_LAUNCHER_DIRECTION_FORWARD)
2294                     _launcher_post_forward(runner, EINA_FALSE);
2295                   else if (runner->direction == TWS_SERVICE_LAUNCHER_DIRECTION_BACKWARD)
2296                     _launcher_post_backward(runner, EINA_FALSE);
2297
2298                   _launcher_state_set(runner, LAUNCHER_STATE_IDLE);
2299                   _launcher_launched_ec_set(runner, NULL);
2300
2301                   _launcher_handler_launcher_runner_unset(runner);
2302                   _launcher_handler_launcher_pre_runner_unset(runner);
2303
2304                   runner->direction = 0;
2305                   runner->with_swl = 0;
2306                }
2307           }
2308      }
2309 }
2310
2311 EINTERN void
2312 e_service_launcher_callee_register(E_Client *callee, const char *appid, const char *splash_path, const char *splash_group)
2313 {
2314    E_Service_Launcher *runner;
2315
2316    EINA_SAFETY_ON_NULL_RETURN(callee);
2317
2318    runner = _launcher_handler_launcher_runner_get();
2319    EINA_SAFETY_ON_NULL_RETURN(runner);
2320    EINA_SAFETY_ON_TRUE_RETURN(runner->state != LAUNCHER_STATE_MONITORING);
2321
2322    if (runner->target.appid)
2323      {
2324         if (!e_util_strcmp(appid, runner->target.appid))
2325           {
2326              runner->target.ec = callee;
2327              runner->target.splash_path = eina_stringshare_add(splash_path);
2328              runner->target.splash_group = eina_stringshare_add(splash_group);
2329
2330              ELOGF("LAUNCHER_SRV", "Register callee(%p)  by appid(%s)",
2331                    runner->ec, runner->target.ec, runner->target.appid);
2332           }
2333      }
2334 }