Tizen 2.0 Release
[apps/home/minicontrol.git] / src / minicontrol-provider.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.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://floralicense.org/license/
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
19 #include "minicontrol-error.h"
20 #include "minicontrol-type.h"
21 #include "minicontrol-internal.h"
22 #include "minicontrol-provider.h"
23 #include "minicontrol-log.h"
24
25 #define MINICTRL_PRIORITY_SUFFIX_TOP "__minicontrol_top"
26 #define MINICTRL_PRIORITY_SUFFIX_LOW "__minicontrol_low"
27 #define MINICTRL_DATA_KEY "__minictrl_data_internal"
28
29 enum {
30         MINICTRL_STATE_READY =0,
31         MINICTRL_STATE_RUNNING,
32 };
33
34 struct _provider_data {
35         char *name;
36         int state;
37         minicontrol_priority_e priority;
38         Evas_Object *obj;
39         minictrl_sig_handle *sh;
40 };
41
42 static void __provider_data_free(struct _provider_data *pd)
43 {
44         if (pd) {
45                 if (pd->name)
46                         free(pd->name);
47
48                 if (pd->sh)
49                         _minictrl_dbus_sig_handle_dettach(pd->sh);
50
51                 free(pd);
52         }
53 }
54
55 static int __str_has_suffix(const char *str, const char *suffix)
56 {
57         int str_len;
58         int suffix_len;
59
60         if (!str)
61                 return -1;
62
63         if (!suffix)
64                 return -1;
65
66         str_len = strlen (str);
67         suffix_len = strlen (suffix);
68
69         if (str_len < suffix_len)
70                 return -1;
71
72         return strcmp(str + str_len - suffix_len, suffix);
73 }
74
75 static void _running_req_cb(void *data, DBusMessage *msg)
76 {
77         struct _provider_data *pd;
78
79         if (!data) {
80                 ERR("data is NULL");
81                 return;
82         }
83         pd = data;
84
85         if (pd->state == MINICTRL_STATE_RUNNING) {
86                 Evas_Coord w = 0;
87                 Evas_Coord h = 0;
88                 evas_object_geometry_get(pd->obj, NULL, NULL, &w, &h);
89                 _minictrl_provider_message_send(MINICTRL_DBUS_SIG_START,
90                                         pd->name, w, h, pd->priority);
91         }
92 }
93
94 static int minicontrol_win_start(Evas_Object *mincontrol)
95 {
96         struct _provider_data *pd;
97         int ret = MINICONTROL_ERROR_NONE;
98
99         if (!mincontrol) {
100                 ERR("mincontrol is NULL, invaild parameter");
101                 return MINICONTROL_ERROR_INVALID_PARAMETER;
102         }
103
104         pd = evas_object_data_get(mincontrol, MINICTRL_DATA_KEY);
105         if (!pd) {
106                 ERR("pd is NULL, invaild parameter");
107                 return MINICONTROL_ERROR_INVALID_PARAMETER;
108         }
109
110         if (!pd->name) {
111                 ERR("pd name is NULL, invaild parameter");
112                 return MINICONTROL_ERROR_INVALID_PARAMETER;
113         }
114
115         if (pd->state != MINICTRL_STATE_RUNNING) {
116                 Evas_Coord w = 0;
117                 Evas_Coord h = 0;
118                 pd->state = MINICTRL_STATE_RUNNING;
119
120                 evas_object_geometry_get(mincontrol, NULL, NULL, &w, &h);
121                 ret = _minictrl_provider_message_send(MINICTRL_DBUS_SIG_START,
122                                         pd->name, w, h, pd->priority);
123         }
124
125         return ret;
126 }
127
128 static int minicontrol_win_stop(Evas_Object *mincontrol)
129 {
130         struct _provider_data *pd;
131         int ret = MINICONTROL_ERROR_NONE;
132
133         if (!mincontrol) {
134                 ERR("mincontrol is NULL, invaild parameter");
135                 return MINICONTROL_ERROR_INVALID_PARAMETER;
136         }
137
138         pd = evas_object_data_get(mincontrol, MINICTRL_DATA_KEY);
139         if (!pd) {
140                 ERR("pd is NULL, invaild parameter");
141                 return MINICONTROL_ERROR_INVALID_PARAMETER;
142         }
143
144         if (!pd->name) {
145                 ERR("pd name is NULL, invaild parameter");
146                 return MINICONTROL_ERROR_INVALID_PARAMETER;
147         }
148         if (pd->state != MINICTRL_STATE_READY) {
149                 pd->state = MINICTRL_STATE_READY;
150                 ret = _minictrl_provider_message_send(MINICTRL_DBUS_SIG_STOP,
151                                         pd->name, 0, 0, pd->priority);
152         }
153
154         return ret;
155 }
156
157 static void _minictrl_win_del(void *data, Evas *e,
158                         Evas_Object *obj, void *event_info)
159 {
160         struct _provider_data *pd = NULL;
161
162         minicontrol_win_stop(obj);
163
164         pd = evas_object_data_get(obj, MINICTRL_DATA_KEY);
165         __provider_data_free(pd);
166
167         evas_object_data_set(obj, MINICTRL_DATA_KEY, NULL);
168 }
169
170 static void _minictrl_win_hide(void *data, Evas *e,
171                         Evas_Object *obj, void *event_info)
172 {
173         minicontrol_win_stop(obj);
174 }
175
176 static void _minictrl_win_show(void *data, Evas *e,
177                         Evas_Object *obj, void *event_info)
178 {
179         minicontrol_win_start(obj);
180 }
181
182 static void _minictrl_win_resize(void *data, Evas *e,
183                         Evas_Object *obj, void *event_info)
184 {
185         struct _provider_data *pd;
186
187         if (!data) {
188                 ERR("data is NULL, invaild parameter");
189                 return;
190         }
191         pd = data;
192
193         if (pd->state == MINICTRL_STATE_RUNNING) {
194                 Evas_Coord w = 0;
195                 Evas_Coord h = 0;
196
197                 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
198                 _minictrl_provider_message_send(MINICTRL_DBUS_SIG_RESIZE,
199                                         pd->name, w, h, pd->priority);
200         }
201 }
202
203 static char *_minictrl_create_name(const char *name)
204 {
205         time_t now;
206         struct tm *now_tm;
207         char time_buf[20]; /* 18 chars to represent time */
208         char *buf;
209         int size = 0;
210
211         if (!name) {
212                 ERR("name is NULL, invaild parameter");
213                 return NULL;
214         }
215
216         now = time(NULL);
217         now_tm = localtime(&now);
218         strftime(time_buf, sizeof(time_buf), "%y-%m-%d-%H:%M:%S", now_tm);
219
220         size = snprintf(NULL, 0, "[%s]-[%s]", name, time_buf) + 1;
221         buf = (char *)malloc(sizeof(char) * size);
222         if (!buf) {
223                ERR("fail to alloc buf");
224                return NULL;
225         }
226
227         snprintf(buf, size, "[%s]-[%s]", name, time_buf);
228
229         return buf;
230 }
231
232 static minicontrol_priority_e _minictrl_get_priroty_by_name(const char *name)
233 {
234         minicontrol_priority_e priority = MINICONTROL_PRIORITY_MIDDLE;
235
236         if (!__str_has_suffix(name, MINICTRL_PRIORITY_SUFFIX_TOP))
237                 priority = MINICONTROL_PRIORITY_TOP;
238         else if (!__str_has_suffix(name, MINICTRL_PRIORITY_SUFFIX_LOW))
239                 priority = MINICONTROL_PRIORITY_LOW;
240
241         return priority;
242 }
243
244 EXPORT_API Evas_Object *minicontrol_win_add(const char *name)
245 {
246         Evas_Object *win = NULL;
247         char *name_inter = NULL;
248         struct _provider_data *pd;
249
250         if (!name)
251                 return NULL;
252
253         win = elm_win_add(NULL, "minicontrol", ELM_WIN_SOCKET_IMAGE);
254         if (!win)
255                 return NULL;
256
257         name_inter = _minictrl_create_name(name);
258         if (!name_inter) {
259
260                 ERR("Fail to create name_inter for : %s", name);
261                 evas_object_del(win);
262                 return NULL;
263
264         }
265
266         if (!elm_win_socket_listen(win, name_inter, 0, EINA_FALSE)) {
267                 ERR("Fail to elm win socket listen");
268                 evas_object_del(win);
269                 return NULL;
270         }
271
272         pd = malloc(sizeof(struct _provider_data));
273         if (!pd) {
274                 ERR("Fail to alloc memory");
275                 evas_object_del(win);
276                 free(name_inter);
277                 return NULL;
278
279         }
280         memset(pd, 0x00, sizeof(struct _provider_data));
281         pd->name = name_inter;
282         pd->state = MINICTRL_STATE_READY;
283         pd->obj = win;
284         pd->priority = _minictrl_get_priroty_by_name(name);
285
286         evas_object_data_set(win ,MINICTRL_DATA_KEY,pd);
287
288         elm_win_autodel_set(win, EINA_TRUE);
289
290         evas_object_event_callback_add(win, EVAS_CALLBACK_DEL,
291                                         _minictrl_win_del, pd);
292
293         evas_object_event_callback_add(win, EVAS_CALLBACK_SHOW,
294                                         _minictrl_win_show, pd);
295
296         evas_object_event_callback_add(win, EVAS_CALLBACK_HIDE,
297                                         _minictrl_win_hide, pd);
298
299         evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE,
300                                         _minictrl_win_resize, pd);
301
302         pd->sh = _minictrl_dbus_sig_handle_attach(MINICTRL_DBUS_SIG_RUNNING_REQ,
303                                         _running_req_cb, pd);
304
305         INFO("new minicontrol win[%p] created - %s, priority[%d]",
306                                 win, pd->name, pd->priority);
307
308         return win;
309 }
310
311 EXPORT_API minicontrol_error_e minicontrol_request(Evas_Object *mincontrol, minicontrol_request_e request)
312 {
313         struct _provider_data *pd;
314         int ret = MINICONTROL_ERROR_NONE;
315
316         if (!mincontrol) {
317                 ERR("mincontrol is NULL, invaild parameter");
318                 return MINICONTROL_ERROR_INVALID_PARAMETER;
319         }
320
321         pd = evas_object_data_get(mincontrol, MINICTRL_DATA_KEY);
322         if (!pd) {
323                 ERR("pd is NULL, invaild parameter");
324                 return MINICONTROL_ERROR_INVALID_PARAMETER;
325         }
326
327         if (!pd->name) {
328                 ERR("pd name is NULL, invaild parameter");
329                 return MINICONTROL_ERROR_INVALID_PARAMETER;
330         }
331
332         if (pd->state == MINICTRL_STATE_RUNNING) {
333                 ret = _minictrl_provider_message_send(MINICTRL_DBUS_SIG_REQUEST,
334                                         pd->name, request, request, pd->priority);
335         }
336
337         return ret;
338 }