Tizen 2.4 SDK Rev6 Release
[apps/home/minicontrol.git] / src / minicontrol-provider.c
1 /*
2  * Copyright (c)  2013-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <Elementary.h>
18 #include <Ecore_Evas.h>
19
20 #include "minicontrol-error.h"
21 #include "minicontrol-type.h"
22 #include "minicontrol-internal.h"
23 #include "minicontrol-provider.h"
24 #include "minicontrol-provider-internal.h"
25 #include "minicontrol-log.h"
26
27 #define MINICTRL_PRIORITY_SUFFIX_TOP "__minicontrol_top"
28 #define MINICTRL_PRIORITY_SUFFIX_LOW "__minicontrol_low"
29 #define MINICTRL_DATA_KEY "__minictrl_data_internal"
30
31 enum {
32         MINICTRL_STATE_READY =0,
33         MINICTRL_STATE_RUNNING,
34 };
35
36 struct _minicontrol_provider {
37         char *name;
38         int state;
39         Evas_Object *obj;
40         minictrl_sig_handle *running_sh;
41         minictrl_sig_handle *event_sh;
42         minicontrol_event_cb event_callback;
43 };
44
45 static void _minictrl_win_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
46 static void _minictrl_win_hide_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
47 static void _minictrl_win_show_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
48 static void _minictrl_win_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
49
50 static void __minicontrol_provider_free(struct _minicontrol_provider *pd)
51 {
52         if (pd) {
53                 if (pd->name)
54                         free(pd->name);
55
56                 if (pd->running_sh)
57                         _minictrl_dbus_sig_handle_dettach(pd->running_sh);
58
59                 if (pd->event_sh)
60                         _minictrl_dbus_sig_handle_dettach(pd->event_sh);
61
62                 free(pd);
63         }
64 }
65
66 static void _running_req_cb(void *data, DBusMessage *msg)
67 {
68         struct _minicontrol_provider *pd;
69
70         if (!data) {
71                 ERR("data is NULL");
72                 return;
73         }
74         pd = data;
75
76         if (pd->state == MINICTRL_STATE_RUNNING) {
77                 Evas_Coord w = 0;
78                 Evas_Coord h = 0;
79                 evas_object_geometry_get(pd->obj, NULL, NULL, &w, &h);
80                 _minictrl_provider_message_send(MINICONTROL_EVENT_START, pd->name, w, h, 0);
81         }
82 }
83
84 static void _sig_to_provider_handler_cb(void *data, DBusMessage *msg)
85 {
86         struct _minicontrol_provider *pd;
87         DBusError err;
88         char *minicontrol_name = NULL;
89         minicontrol_viewer_event_e event;
90         dbus_bool_t dbus_ret;
91         bundle *event_arg_bundle = NULL;
92         bundle_raw *serialized_arg = NULL;
93         unsigned int serialized_arg_length = 0;
94
95         if (!data) {
96                 ERR("data is NULL");
97                 return;
98         }
99         pd = data;
100
101         dbus_error_init(&err); /* Does not allocate any memory. the error only needs to be freed if it is set at some point. */
102
103         dbus_ret = dbus_message_get_args(msg, &err,
104                                 DBUS_TYPE_STRING, &minicontrol_name,
105                                 DBUS_TYPE_INT32,  &event,
106                                 DBUS_TYPE_STRING, &serialized_arg,
107                                 DBUS_TYPE_UINT32, &serialized_arg_length,
108                                 DBUS_TYPE_INVALID);
109
110         if (!dbus_ret) {
111                 ERR("fail to get args : %s", err.message);
112                 dbus_error_free(&err);
113                 return;
114         }
115
116         INFO("minicontrol_name[%s] event[%d] pd->name[%s]", minicontrol_name, event, pd->name);
117
118         if (minicontrol_name && pd->name && strcmp(minicontrol_name, pd->name) == 0) {
119                 event_arg_bundle = bundle_decode(serialized_arg, serialized_arg_length);
120                 /* event argument can be null */
121
122                 if (event == MINICONTROL_VIEWER_EVENT_SHOW) {
123                         Evas_Coord width;
124                         Evas_Coord height;
125                         evas_object_geometry_get (pd->obj, NULL, NULL, &width, &height);
126                         INFO("width[%d] height[%d]", width, height);
127                         _minictrl_provider_message_send(MINICONTROL_EVENT_RESIZE, pd->name, width, height, 0);
128                 }
129
130                 if (pd->event_callback)
131                         pd->event_callback(event, event_arg_bundle);
132
133                 if (event_arg_bundle)
134                         bundle_free(event_arg_bundle);
135         }
136 }
137
138
139
140 static char *_minictrl_create_name(const char *name)
141 {
142         char *buf;
143         int size = 0;
144
145         if (!name) {
146                 ERR("name is NULL, invaild parameter");
147                 set_last_result(MINICONTROL_ERROR_INVALID_PARAMETER);
148                 return NULL;
149         }
150
151         size = snprintf(NULL, 0, "[%s]", name) + 1;
152         buf = (char *)malloc(sizeof(char) * size);
153         if (!buf) {
154                 ERR("fail to alloc buf");
155                 set_last_result(MINICONTROL_ERROR_OUT_OF_MEMORY);
156                 return NULL;
157         }
158
159         snprintf(buf, size, "[%s]", name);
160
161         return buf;
162 }
163
164 static void _access_changed_cb(void *data, Evas_Object *obj, void *event_info)
165 {
166         Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
167         if (ee != NULL) {
168                 if (elm_config_access_get()) {
169                         /* TODO : Check this API is supported
170                         ecore_evas_extn_socket_events_block_set(ee, EINA_TRUE);
171                          */
172                 }
173                 else {
174                         /* TODO : Check this API is supported
175                         ecore_evas_extn_socket_events_block_set(ee, EINA_FALSE);
176                          */
177                 }
178         }
179 }
180
181
182 EXPORT_API Evas_Object* minicontrol_create_window(const char *name, minicontrol_target_viewer_e target_viewer, minicontrol_event_cb event_callback)
183 {
184         Evas_Object *win = NULL;
185         char *name_inter = NULL;
186         struct _minicontrol_provider *pd;
187
188         if (!name) {
189                 ERR("invalid parameter");
190                 set_last_result(MINICONTROL_ERROR_INVALID_PARAMETER);
191                 return NULL;
192         }
193
194         win = elm_win_add(NULL, "minicontrol", ELM_WIN_SOCKET_IMAGE);
195         if (!win) {
196                 ERR("elm_win_add failed");
197                 set_last_result(MINICONTROL_ERROR_ELM_FAILURE);
198                 return NULL;
199         }
200
201         if (elm_config_access_get()) {
202                 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(win));
203
204                 if (ee != NULL) {
205                         /* TODO : Check this API is supported
206                         ecore_evas_extn_socket_events_block_set(ee, EINA_TRUE);
207                          */
208                 }
209
210         }
211         evas_object_smart_callback_add(win, "access,changed", _access_changed_cb, NULL);
212
213         name_inter = _minictrl_create_name(name);
214         if (!name_inter) {
215                 ERR("Fail to create name_inter for : %s", name);
216                 evas_object_del(win);
217                 return NULL;
218         }
219
220         if (!elm_win_socket_listen(win, name_inter, 0, EINA_TRUE)) {
221                 ERR("Fail to elm win socket listen");
222                 set_last_result(MINICONTROL_ERROR_ELM_FAILURE);
223                 evas_object_del(win);
224                 free(name_inter);
225                 return NULL;
226         }
227
228         pd = malloc(sizeof(struct _minicontrol_provider));
229         if (!pd) {
230                 ERR("Fail to alloc memory");
231                 set_last_result(MINICONTROL_ERROR_OUT_OF_MEMORY);
232                 evas_object_del(win);
233                 free(name_inter);
234                 return NULL;
235
236         }
237         memset(pd, 0x00, sizeof(struct _minicontrol_provider));
238         pd->name = name_inter;
239         pd->state = MINICTRL_STATE_READY;
240         pd->obj = win;
241
242         evas_object_data_set(win ,MINICTRL_DATA_KEY,pd);
243
244         elm_win_autodel_set(win, EINA_TRUE);
245
246         evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _minictrl_win_del_cb, pd);
247         evas_object_event_callback_add(win, EVAS_CALLBACK_SHOW, _minictrl_win_show_cb, pd);
248         evas_object_event_callback_add(win, EVAS_CALLBACK_HIDE, _minictrl_win_hide_cb, pd);
249         evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _minictrl_win_resize_cb, pd);
250
251         pd->running_sh = _minictrl_dbus_sig_handle_attach(MINICTRL_DBUS_SIG_RUNNING_REQ, _running_req_cb, pd);
252         pd->event_sh   = _minictrl_dbus_sig_handle_attach(MINICTRL_DBUS_SIG_TO_PROVIDER, _sig_to_provider_handler_cb, pd);
253         pd->event_callback = event_callback;
254
255         INFO("new minicontrol created - %s", pd->name);
256         return win;
257 }
258
259 EXPORT_API int minicontrol_send_event(Evas_Object *mincontrol, minicontrol_provider_event_e event, bundle *event_arg)
260 {
261         struct _minicontrol_provider *pd;
262         int ret = MINICONTROL_ERROR_NONE;
263
264         if (!mincontrol) {
265                 ERR("mincontrol is NULL, invaild parameter");
266                 return MINICONTROL_ERROR_INVALID_PARAMETER;
267         }
268
269         pd = evas_object_data_get(mincontrol, MINICTRL_DATA_KEY);
270         if (!pd) {
271                 ERR("pd is NULL, invaild parameter");
272                 return MINICONTROL_ERROR_INVALID_PARAMETER;
273         }
274
275         if (!pd->name) {
276                 ERR("pd name is NULL, invaild parameter");
277                 return MINICONTROL_ERROR_INVALID_PARAMETER;
278         }
279
280         if (pd->state == MINICTRL_STATE_RUNNING) {
281                 ret = _minictrl_send_event(MINICTRL_DBUS_SIG_TO_VIEWER, pd->name, event, event_arg);
282         }
283
284         return ret;
285 }
286
287 static int minicontrol_win_start(Evas_Object *mincontrol)
288 {
289         struct _minicontrol_provider *pd;
290         int ret = MINICONTROL_ERROR_NONE;
291
292         if (!mincontrol) {
293                 ERR("mincontrol is NULL, invaild parameter");
294                 return MINICONTROL_ERROR_INVALID_PARAMETER;
295         }
296
297         pd = evas_object_data_get(mincontrol, MINICTRL_DATA_KEY);
298         if (!pd) {
299                 ERR("pd is NULL, invaild parameter");
300                 return MINICONTROL_ERROR_INVALID_PARAMETER;
301         }
302
303         if (!pd->name) {
304                 ERR("pd name is NULL, invaild parameter");
305                 return MINICONTROL_ERROR_INVALID_PARAMETER;
306         }
307
308         if (pd->state != MINICTRL_STATE_RUNNING) {
309                 Evas_Coord w = 0;
310                 Evas_Coord h = 0;
311                 pd->state = MINICTRL_STATE_RUNNING;
312
313                 evas_object_geometry_get(mincontrol, NULL, NULL, &w, &h);
314                 _minictrl_provider_proc_send(MINICONTROL_DBUS_PROC_EXCLUDE);
315                 ret = _minictrl_provider_message_send(MINICONTROL_EVENT_START, pd->name, w, h, 0);
316         }
317
318         return ret;
319 }
320
321 static int minicontrol_win_stop(Evas_Object *mincontrol)
322 {
323         struct _minicontrol_provider *pd;
324         int ret = MINICONTROL_ERROR_NONE;
325
326         if (!mincontrol) {
327                 ERR("mincontrol is NULL, invaild parameter");
328                 return MINICONTROL_ERROR_INVALID_PARAMETER;
329         }
330
331         pd = evas_object_data_get(mincontrol, MINICTRL_DATA_KEY);
332         if (!pd) {
333                 ERR("pd is NULL, invaild parameter");
334                 return MINICONTROL_ERROR_INVALID_PARAMETER;
335         }
336
337         if (!pd->name) {
338                 ERR("pd name is NULL, invaild parameter");
339                 return MINICONTROL_ERROR_INVALID_PARAMETER;
340         }
341         if (pd->state != MINICTRL_STATE_READY) {
342                 pd->state = MINICTRL_STATE_READY;
343                 _minictrl_provider_proc_send(MINICONTROL_DBUS_PROC_INCLUDE);
344                 ret = _minictrl_provider_message_send(MINICONTROL_EVENT_STOP, pd->name, 0, 0, 0);
345         }
346
347         return ret;
348 }
349
350 static void _minictrl_win_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
351 {
352         struct _minicontrol_provider *pd = NULL;
353
354         minicontrol_win_stop(obj);
355
356         pd = evas_object_data_get(obj, MINICTRL_DATA_KEY);
357         __minicontrol_provider_free(pd);
358
359         evas_object_data_set(obj, MINICTRL_DATA_KEY, NULL);
360 }
361
362 static void _minictrl_win_hide_cb(void *data, Evas *e,
363                 Evas_Object *obj, void *event_info)
364 {
365         minicontrol_win_stop(obj);
366 }
367
368 static void _minictrl_win_show_cb(void *data, Evas *e,
369                 Evas_Object *obj, void *event_info)
370 {
371         minicontrol_win_start(obj);
372 }
373
374 static void _minictrl_win_resize_cb(void *data, Evas *e,
375                 Evas_Object *obj, void *event_info)
376 {
377         struct _minicontrol_provider *pd;
378
379         if (!data) {
380                 ERR("data is NULL, invaild parameter");
381                 return;
382         }
383         pd = data;
384
385         if (pd->state == MINICTRL_STATE_RUNNING) {
386                 Evas_Coord w = 0;
387                 Evas_Coord h = 0;
388
389                 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
390                 _minictrl_provider_message_send(MINICONTROL_EVENT_RESIZE, pd->name, w, h, 0);
391         }
392 }
393
394 EXPORT_API Evas_Object *minicontrol_win_add(const char *name)
395 {
396         Evas_Object *win = NULL;
397         char *name_inter = NULL;
398         struct _minicontrol_provider *pd;
399
400         INFO("minicontrol_win_add [%s]", name);
401
402         if (!name) {
403                 ERR("name is null");
404                 return NULL;
405         }
406
407         win = elm_win_add(NULL, "minicontrol", ELM_WIN_SOCKET_IMAGE);
408         if (!win) {
409                 ERR("elm_win_add returns null for [%s]", name);
410                 return NULL;
411         }
412
413         if (elm_config_access_get()) {
414                 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(win));
415
416                 if (ee != NULL) {
417                         /* TODO : Check this API is supported
418                         ecore_evas_extn_socket_events_block_set(ee, EINA_TRUE);
419                          */
420                 }
421
422         }
423         evas_object_smart_callback_add(win, "access,changed", _access_changed_cb, NULL);
424
425         name_inter = _minictrl_create_name(name);
426         if (!name_inter) {
427
428                 ERR("Fail to create name_inter for : %s", name);
429                 evas_object_del(win);
430                 return NULL;
431         }
432
433         if (!elm_win_socket_listen(win, name_inter, 0, EINA_TRUE)) {
434                 ERR("Fail to elm win socket listen");
435                 evas_object_del(win);
436                 free(name_inter);
437                 return NULL;
438         }
439
440         pd = malloc(sizeof(struct _minicontrol_provider));
441         if (!pd) {
442                 ERR("Fail to alloc memory");
443                 evas_object_del(win);
444                 free(name_inter);
445                 return NULL;
446
447         }
448         memset(pd, 0x00, sizeof(struct _minicontrol_provider));
449         pd->name = name_inter;
450         pd->state = MINICTRL_STATE_READY;
451         pd->obj = win;
452
453         evas_object_data_set(win ,MINICTRL_DATA_KEY,pd);
454
455         elm_win_autodel_set(win, EINA_TRUE);
456
457         evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _minictrl_win_del_cb, pd);
458         evas_object_event_callback_add(win, EVAS_CALLBACK_SHOW, _minictrl_win_show_cb, pd);
459         evas_object_event_callback_add(win, EVAS_CALLBACK_HIDE, _minictrl_win_hide_cb, pd);
460         evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _minictrl_win_resize_cb, pd);
461
462         pd->running_sh = _minictrl_dbus_sig_handle_attach(MINICTRL_DBUS_SIG_RUNNING_REQ, _running_req_cb, pd);
463
464         INFO("new minicontrol created - %s", pd->name);
465         return win;
466 }
467
468 EXPORT_API int minicontrol_request(Evas_Object *mincontrol, minicontrol_request_e request)
469 {
470         struct _minicontrol_provider *pd;
471         int ret = MINICONTROL_ERROR_NONE;
472         minicontrol_event_e event;
473
474         if (!mincontrol) {
475                 ERR("mincontrol is NULL, invaild parameter");
476                 return MINICONTROL_ERROR_INVALID_PARAMETER;
477         }
478
479         pd = evas_object_data_get(mincontrol, MINICTRL_DATA_KEY);
480         if (!pd) {
481                 ERR("pd is NULL, invaild parameter");
482                 return MINICONTROL_ERROR_INVALID_PARAMETER;
483         }
484
485         if (!pd->name) {
486                 ERR("pd name is NULL, invaild parameter");
487                 return MINICONTROL_ERROR_INVALID_PARAMETER;
488         }
489
490         if (pd->state == MINICTRL_STATE_RUNNING) {
491                 switch(request) {
492                 case MINICONTROL_REQ_HIDE_VIEWER :
493                         event = MINICONTROL_EVENT_REQUEST_HIDE;
494                         break;
495
496                 case MINICONTROL_REQ_REPORT_VIEWER_ANGLE :
497                         event = MINICONTROL_EVENT_REQUEST_ANGLE;
498                         break;
499
500                 case MINICONTROL_REQ_FREEZE_SCROLL_VIEWER :
501                 case MINICONTROL_REQ_UNFREEZE_SCROLL_VIEWER :
502                 case MINICONTROL_REQ_ROTATE_PROVIDER :
503                         WARN("Could be not supported [%d]", request);
504                         event = request;
505                         break;
506
507                 case MINICONTROL_REQ_NONE :
508                 default :
509                         ERR("Not supported request[%d]", request);
510                         ret = MINICONTROL_ERROR_NOT_SUPPORTED;
511                         goto out;
512                 }
513
514                 _minictrl_send_event(MINICTRL_DBUS_SIG_TO_VIEWER, pd->name, event, NULL);
515         }
516 out:
517         return ret;
518 }
519