tizen_ws_shell: sustain list of client for tzsvr even before tzsvr service is launched 55/45055/3
authorMinJeong Kim <minjjj.kim@samsung.com>
Fri, 31 Jul 2015 04:14:09 +0000 (13:14 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Sat, 1 Aug 2015 16:15:03 +0000 (09:15 -0700)
Keep list of clients that hav requested for binding with tvsvr service
even if tvsvr service is not registered yet, and support 'unbind'
request of 'tws_tzsvr' interface.

Change-Id: Ie1ee04e926268278317b008ce234e76915c0bcdf
Signed-off-by: MinJeong Kim <minjjj.kim@samsung.com>
src/e_mod_ws_shell.c
src/tizen_ws_shell-protocol.c
src/tizen_ws_shell-server-protocol.h

index a16c2067298eab10973213a32d2e2f6aa5c0a907..9ed9eeff2e2c6e74244c6e74ebff71ea2a539300 100644 (file)
@@ -9,6 +9,8 @@ typedef struct _WS_Shell_Service
    E_Tizen_Ws_Shell_Service_Role role;
    const char *name;
    E_Client *ec;
+   Eina_List *subscribers;
+   Eina_Bool enabled;
 
    struct wl_resource *resource;
 
@@ -29,6 +31,7 @@ typedef struct _WS_Shell_Region
 typedef struct _WS_Shell_Subscriber
 {
    E_Client *ec;
+   struct wl_resource *resource;
 } WS_Shell_Subscriber;
 
 #define SERVICE_FOREACH(service_idx)                   \
@@ -126,12 +129,33 @@ static const struct tws_region_interface _e_tizen_ws_shell_region_interface =
 static void
 _e_tizen_ws_shell_service_register_handle(WS_Shell_Service *service)
 {
+   WS_Shell_Subscriber *subs = NULL;
+   Eina_List *l;
+
    EINA_SAFETY_ON_NULL_RETURN(service);
    EINA_SAFETY_ON_NULL_RETURN(service->ec);
 
    switch (service->role)
      {
       case E_TIZEN_WS_SHELL_SERVICE_ROLE_TVSERVICE:
+         if (service->subscribers)
+           {
+              E_Client *above = NULL;
+
+              EINA_LIST_FOREACH(service->subscribers, l, subs)
+                {
+                   if ((subs->ec) && (subs->ec->parent != service->ec))
+                     {
+                        if (!above) above = subs->ec;
+                        e_mod_pol_stack_transient_for_set(subs->ec,
+                                                          service->ec);
+                     }
+                }
+
+              if (above)
+                evas_object_stack_below(service->ec->frame, above->frame);
+           }
+         break;
       default:
          break;
      }
@@ -140,11 +164,25 @@ _e_tizen_ws_shell_service_register_handle(WS_Shell_Service *service)
 static void
 _e_tizen_ws_shell_service_unregister_handle(WS_Shell_Service *service)
 {
+   WS_Shell_Subscriber *subs = NULL;
+
    EINA_SAFETY_ON_NULL_RETURN(service);
    EINA_SAFETY_ON_NULL_RETURN(service->ec);
 
    switch (service->role)
      {
+      case E_TIZEN_WS_SHELL_SERVICE_ROLE_TVSERVICE:
+         if (service->subscribers)
+           {
+              EINA_LIST_FREE(service->subscribers, subs)
+                {
+                   if ((subs->ec) && (subs->ec->parent == service->ec))
+                     {
+                        e_mod_pol_stack_transient_for_set(subs->ec,
+                                                          NULL);
+                     }
+                }
+           }
       default:
          break;
      }
@@ -300,6 +338,8 @@ _e_tizen_ws_shell_tvsrv_destroy(struct wl_resource *resource)
           {
              e_mod_pol_stack_transient_for_set(tvapp->ec, NULL);
           }
+
+        tvsrv->subscribers = eina_list_remove(tvsrv->subscribers, tvapp);
      }
 
    if (tvapp)
@@ -324,19 +364,48 @@ _e_tizen_ws_shell_tvsrv_cb_bind(struct wl_client *client,
    if (!tvapp) return;
 
    if (!(tvsrv = wssh_services[E_TIZEN_WS_SHELL_SERVICE_ROLE_TVSERVICE]))
-     return;
+     {
+        tvsrv = E_NEW(WS_Shell_Service, 1);
+        wssh_services[E_TIZEN_WS_SHELL_SERVICE_ROLE_TVSERVICE] = tvsrv;
+     }
+
+   if (!tvsrv->enabled)
+     {
+        tvsrv->subscribers = eina_list_append(tvsrv->subscribers, tvapp);
+        return;
+     }
 
    if (!tvapp->ec || !tvsrv->ec) return;
    if (tvapp->ec->parent == tvsrv->ec) return;
 
    e_mod_pol_stack_transient_for_set(tvapp->ec, tvsrv->ec);
-   evas_object_stack_above(tvapp->ec->frame, tvsrv->ec->frame);
 }
 
+static void
+_e_tizen_ws_shell_tvsrv_cb_unbind(struct wl_client *client,
+                                  struct wl_resource *resource)
+{
+   WS_Shell_Subscriber *tvapp = NULL;
+   WS_Shell_Service *tvsrv = NULL;
+
+   tvapp = wl_resource_get_user_data(resource);
+   if (!tvapp) return;
+
+   if ((!(tvsrv = wssh_services[E_TIZEN_WS_SHELL_SERVICE_ROLE_TVSERVICE])) ||
+       (!tvsrv->enabled))
+     return;
+
+   if ((!tvapp->ec) || (!tvapp->ec->parent)) return;
+   if (tvapp->ec->parent != tvsrv->ec) return;
+
+   tvsrv->subscribers = eina_list_remove(tvsrv->subscribers, tvapp);
+   e_mod_pol_stack_transient_for_set(tvapp->ec, NULL);
+}
 static const struct tws_tvsrv_interface _e_tizen_ws_shell_tvsrv_interface =
 {
    _e_tizen_ws_shell_tvsrv_cb_release,
    _e_tizen_ws_shell_tvsrv_cb_bind,
+   _e_tizen_ws_shell_tvsrv_cb_unbind,
 };
 
 static void
@@ -376,7 +445,7 @@ _e_tizen_ws_shell_cb_service_create(struct wl_client *client,
         return;
      }
 
-   if (wssh_services[role] != NULL)
+   if ((wssh_services[role]) && (wssh_services[role]->enabled))
 
      {
         ERR("Service %s is already created.", name);
@@ -393,11 +462,12 @@ _e_tizen_ws_shell_cb_service_create(struct wl_client *client,
    surface_resource = wl_client_get_object(client, surface_id);
    ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, (uintptr_t)surface_resource);
 
-   service = E_NEW(WS_Shell_Service, 1);
+   service = wssh_services[role]?: E_NEW(WS_Shell_Service, 1);
    service->resource = res;
    service->name = eina_stringshare_add(name);
    service->ec = ec;
    service->role = role;
+   service->enabled = EINA_TRUE;
 
    wl_resource_set_implementation(res,
                                   &_e_tizen_ws_shell_service_interface,
@@ -502,6 +572,7 @@ _e_tizen_ws_shell_cb_tvsrv_get(struct wl_client *client,
 
    tvapp = E_NEW(WS_Shell_Subscriber, 1);
    tvapp->ec = ec;
+   tvapp->resource = res;
 
    wl_resource_set_implementation(res,
                                   &_e_tizen_ws_shell_tvsrv_interface,
@@ -554,6 +625,7 @@ _e_tizen_ws_shell_bind_cb(struct wl_client *client,
    SERVICE_FOREACH(i)
      {
         if (!wssh_services[i]) continue;
+        if (!wssh_services[i]->enabled) continue;
         tizen_ws_shell_send_service_register(res, wssh_services[i]->name);
      }
 }
@@ -584,13 +656,28 @@ void
 e_mod_ws_shell_shutdown(void)
 {
    struct wl_resource *res;
+   WS_Shell_Subscriber *subs;
+   Eina_List *l, *ll;
    int i;
 
    /* destroy resource of registered services*/
    SERVICE_FOREACH(i)
      {
         if (!wssh_services[i]) continue;
-        wl_resource_destroy(wssh_services[i]->resource);
+
+        EINA_LIST_FOREACH_SAFE(wssh_services[i]->subscribers, l, ll, subs)
+          {
+             wl_resource_destroy(subs->resource);
+          }
+
+        if (wssh_services[i]->resource)
+          {
+             wl_resource_destroy(wssh_services[i]->resource);
+             continue;
+          }
+
+        E_FREE(wssh_services[i]);
+        wssh_services[i] = NULL;
      }
 
    /* destroy interfaces */
index 9126f492a997c94c3852aa4e81ad540579bbe566..ed857dae51f030e3c3b5e03eca43852c22f3179a 100644 (file)
@@ -87,11 +87,12 @@ WL_EXPORT const struct wl_interface tws_service_interface = {
 static const struct wl_message tws_tvsrv_requests[] = {
        { "release", "", types + 0 },
        { "bind", "", types + 0 },
+       { "unbind", "", types + 0 },
 };
 
 WL_EXPORT const struct wl_interface tws_tvsrv_interface = {
        "tws_tvsrv", 1,
-       2, tws_tvsrv_requests,
+       3, tws_tvsrv_requests,
        0, NULL,
 };
 
index ee6e08e1c5e37ab0d9bea7b10f44074451a7a375..47e7f0aa19ad05c19962944a06ce00ced26ecad5 100644 (file)
@@ -265,25 +265,40 @@ enum tws_tvsrv_error {
 #endif /* TWS_TVSRV_ERROR_ENUM */
 
 /**
- * tws_tvsrv - 
- * @release: release the handle of tws_quickpanel
- * @bind: (none)
+ * tws_tvsrv - interface for tv application
+ * @release: release the handle of tws_tvsrv
+ * @bind: request for binding with tv service window
+ * @unbind: request for unbinding with tv service window
  *
- * 
+ * This interface provides protocol to request for binding with tv
+ * service window.
  */
 struct tws_tvsrv_interface {
        /**
-        * release - release the handle of tws_quickpanel
+        * release - release the handle of tws_tvsrv
         *
         * 
         */
        void (*release)(struct wl_client *client,
                        struct wl_resource *resource);
        /**
-        * bind - (none)
+        * bind - request for binding with tv service window
+        *
+        * Request for binding with tv service window, user window can
+        * set tv service window as transient-for window through this
+        * request.
         */
        void (*bind)(struct wl_client *client,
                     struct wl_resource *resource);
+       /**
+        * unbind - request for unbinding with tv service window
+        *
+        * Request for un-binding with tv service window, user window can
+        * unset transient-for relation with tv service window through this
+        * request.
+        */
+       void (*unbind)(struct wl_client *client,
+                      struct wl_resource *resource);
 };