Update License
[platform/framework/web/provider.git] / sample / org.tizen.live-video / src / CController.cpp
1 /*
2  * Copyright 2013  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
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 <stdio.h>
18 #include <errno.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <dirent.h>
22
23 #include <Elementary.h>
24 #include <Ecore.h>
25 #include <Evas.h>
26 #include <Ecore_Evas.h>
27 #include <Ecore_X.h>
28
29 #include <aul.h>
30 #include <dlog.h>
31
32 #include <provider.h>
33 #include <provider_buffer.h>
34
35 #include <mm_message.h>
36 #include <mm_player.h>
37
38 #include "debug.h"
39 #include "CVideo.h"
40 #include "CWindow.h"
41 #include "CController.h"
42 #include "CModel.h"
43
44 CController *CController::m_pInstance = NULL;
45 Ecore_Timer *CController::m_pPing = NULL;
46 const double CController::m_nPingInterval = 120.0f;
47
48 struct TWindowData {
49         Evas_Object *list;
50         char *id;
51 };
52
53 int CController::s_CreateLB(struct event_arg *arg, int *width, int *height, double *priority, void *data)
54 {
55         CVideo *video;
56
57         *width = 348;
58         *height = 348;
59         arg->info.lb_create.out_content = NULL;
60         arg->info.lb_create.out_title = NULL;
61
62         DbgPrint("Content: %s\n", arg->info.lb_create.content);
63
64         video = CVideo::Create(TYPE_LB, arg->id, *width, *height);
65         if (!video)
66                 return -EFAULT;
67
68         return 0;
69 }
70
71 int CController::s_RecreateLB(struct event_arg *arg, void *data)
72 {
73         CVideo *video;
74
75         DbgPrint("Content: %s\n", arg->info.lb_recreate.content);
76
77         video = CVideo::Create(TYPE_LB, arg->id, arg->info.lb_recreate.width, arg->info.lb_recreate.height);
78         if (!video)
79                 return -EFAULT;
80
81         return 0;
82 }
83
84 int CController::s_DestroyLB(struct event_arg *arg, void *data)
85 {
86         CVideo *video;
87         CWindow *win;
88
89         video = CVideo::Find(TYPE_LB, arg->id);
90         if (video)
91                 video->Destroy();
92
93         win = CWindow::Find(TYPE_PD, arg->id);
94         if (win)
95                 win->Destroy();
96
97         return 0;
98 }
99
100 int CController::s_ContentEvent(struct event_arg *arg, void *data)
101 {
102         CVideo *video;
103
104         video = CVideo::Find(TYPE_LB, arg->id);
105         if (!video)
106                 return -ENOENT;
107
108         return 0;
109 }
110
111 int CController::s_Clicked(struct event_arg *arg, void *data)
112 {
113         CVideo *video;
114
115         video = CVideo::Find(TYPE_LB, arg->id);
116         if (!video) {
117                 ErrPrint("Instance is not found: %s\n", arg->id);
118                 return -ENOENT;
119         }
120
121         switch (video->State()) {
122         case CVideo::PLAYING:
123                 video->Stop();
124                 break;
125         case CVideo::STOPPED:
126                 video->Play(CModel::GetInstance()->VideoFilename());
127                 break;
128         default:
129                 break;
130         }
131
132         return 0;
133 }
134
135 int CController::s_TextEvent(struct event_arg *arg, void *data)
136 {
137         CVideo *video;
138
139         video = CVideo::Find(TYPE_LB, arg->id);
140         if (!video)
141                 return -ENOENT;
142
143         return 0;
144 }
145
146 int CController::s_Resize(struct event_arg *arg, void *data)
147 {
148         CVideo *video;
149
150         video = CVideo::Find(TYPE_LB, arg->id);
151         if (!video)
152                 return -ENOENT;
153
154         video->Resize(arg->info.resize.w, arg->info.resize.h);
155         return 0;
156 }
157
158 int CController::s_SetPeriod(struct event_arg *arg, void *data)
159 {
160         CVideo *video;
161
162         video = CVideo::Find(TYPE_LB, arg->id);
163         if (!video)
164                 return -ENOENT;
165
166         return 0;
167 }
168
169 int CController::s_ChangeGroup(struct event_arg *arg, void *data)
170 {
171         CVideo *video;
172
173         video = CVideo::Find(TYPE_LB, arg->id);
174         if (!video)
175                 return -ENOENT;
176
177         return 0;
178 }
179
180 int CController::s_Pinup(struct event_arg *arg, void *data)
181 {
182         CVideo *video;
183
184         video = CVideo::Find(TYPE_LB, arg->id);
185         if (!video)
186                 return -ENOENT;
187
188         return 0;
189 }
190
191 int CController::s_UpdateContent(struct event_arg *arg, void *data)
192 {
193         CVideo *video;
194
195         video = CVideo::Find(TYPE_LB, arg->id);
196         if (!video)
197                 return -ENOENT;
198
199         return 0;
200 }
201
202 int CController::s_Pause(struct event_arg *arg, void *data)
203 {
204         if (m_pPing)
205                 ecore_timer_freeze(m_pPing);
206
207         return 0;
208 }
209
210 int CController::s_Resume(struct event_arg *arg, void *data)
211 {
212         if (m_pPing)
213                 ecore_timer_thaw(m_pPing);
214
215         return 0;
216 }
217
218 int CController::s_Disconnected(struct event_arg *arg, void *data)
219 {
220         if (m_pPing) {
221                 ecore_timer_del(m_pPing);
222                 m_pPing = NULL;
223         }
224
225         aul_terminate_pid(getpid());
226         return 0;
227 }
228
229 Eina_Bool CController::s_PingHandler(void *data)
230 {
231         provider_send_ping();
232         return ECORE_CALLBACK_RENEW;
233 }
234
235 int CController::s_Connected(struct event_arg *arg, void *data)
236 {
237         if (m_pPing)
238                 return -EINVAL;
239
240         /*!
241          * \note
242          * Phase 2. Send "hello" signal to master
243          *          Add "ping" timer (Master will wait 240 seconds)
244          */
245         if (provider_send_hello() < 0)
246                 return -EFAULT;
247
248         m_pPing = ecore_timer_add(m_nPingInterval, s_PingHandler, NULL);
249         if (!m_pPing)
250                 ErrPrint("Failed to add a ping timer\n");
251         return 0;
252 }
253
254 static void press_cb(void *data, Evas_Object *list, void *event_info)
255 {
256         CVideo *video;
257         Elm_Object_Item *item;
258         const char *filename;
259         char *path;
260         int pathlen;
261         TWindowData *win_data = (TWindowData *)data;
262
263         video = CVideo::Find(TYPE_LB, win_data->id);
264         if (!video) {
265                 ErrPrint("Video is not exists\n");
266                 return;
267         }
268
269         item = elm_list_selected_item_get(list);
270         if (!item) {
271                 ErrPrint("Item is not selected\n");
272                 return;
273         }
274
275         filename = elm_object_item_part_text_get(item, NULL);
276         if (!filename) {
277                 ErrPrint("Selected item is not valid\n");
278                 return;
279         }
280
281         pathlen = strlen(filename) + strlen("/opt/usr/media/Videos/") + 1;
282         path = (char *)malloc(pathlen);
283         if (!path) {
284                 ErrPrint("Heap: %s\n", strerror(errno));
285                 return;
286         }
287
288         snprintf(path, pathlen, "/opt/usr/media/Videos/%s", filename);
289         CModel::GetInstance()->SetVideoFilename(path);
290         DbgPrint("Updated Video file: %s\n", path);
291         free(path);
292
293         if (video->State() == CVideo::PLAYING)
294                 video->Stop();
295
296         video->Play(CModel::GetInstance()->VideoFilename());
297 }
298
299 int CController::s_CreatePD(struct event_arg *arg, void *data)
300 {
301         Evas_Object *list;
302         TWindowData *win_data;
303         CWindow *win;
304         Evas_Object *parent;
305         int w;
306         int h;
307
308         DIR *handle;
309
310         win_data = (TWindowData *)malloc(sizeof(*win_data));
311         if (!win_data) {
312                 ErrPrint("Heap: %s\n", strerror(errno));
313                 return -ENOMEM;
314         }
315
316         win = CWindow::Create(TYPE_PD, arg->id, arg->info.pd_create.w, arg->info.pd_create.h);
317         if (!win) {
318                 ErrPrint("Window for PID is not able to create\n");
319                 free(win_data);
320                 return -EFAULT;
321         }
322
323         parent = win->Object();
324         if (!parent) {
325                 ErrPrint("Window is not valid\n");
326                 free(win_data);
327                 return -EFAULT;
328         }
329
330         list = elm_list_add(parent);
331         evas_object_geometry_get(parent, NULL, NULL, &w, &h);
332         evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
333         elm_list_multi_select_set(list, EINA_FALSE);
334         elm_list_mode_set(list, ELM_LIST_COMPRESS);
335         elm_scroller_bounce_set(list, EINA_TRUE, EINA_FALSE);
336         evas_object_resize(list, w, h);
337         evas_object_move(list, 0, 0);
338         evas_object_show(list);
339
340         handle = opendir("/opt/usr/media/Videos/");
341         if (handle) {
342                 struct dirent *ent;
343
344                 while ((ent = readdir(handle)))
345                         elm_list_item_append(list, ent->d_name, NULL, NULL /* end */, press_cb, win_data);
346
347                 closedir(handle);
348         }
349
350         elm_list_go(list);
351
352         win_data->id = strdup(arg->id);
353         if (!win_data->id) {
354                 evas_object_del(list);
355                 free(win_data);
356                 return -ENOMEM;
357         }
358         win_data->list = list;
359
360         evas_object_data_set(parent, "win_data", win_data);
361         return 0;
362 }
363
364 int CController::s_DestroyPD(struct event_arg *arg, void *data)
365 {
366         CWindow *win;
367         TWindowData *win_data;
368
369         win = CWindow::Find(TYPE_PD, arg->id);
370         if (!win) {
371                 ErrPrint("PD Window for %s is not exists\n", arg->id);
372                 return -ENOENT;
373         }
374
375         win_data = (TWindowData *)evas_object_data_del(win->Object(), "win_data");
376         if (win_data) {
377                 evas_object_del(win_data->list);
378                 free(win_data->id);
379                 free(win_data);
380         }
381
382         win->Destroy();
383         return 0;
384 }
385
386 CController::CController(void)
387 : m_sName(NULL)
388 {
389 }
390
391 CController::~CController(void)
392 {
393         free(m_sName);
394         m_sName = NULL;
395
396         m_pInstance = NULL;
397
398         if (m_pPing) {
399                 ecore_timer_del(m_pPing);
400                 m_pPing = NULL;
401         }
402 }
403
404 int CController::Initialize(const char *name)
405 {
406         int ret;
407         struct event_handler table;
408
409         if (CController::m_pInstance)
410                 return -EALREADY;
411
412         try {
413                 m_pInstance = new CController();
414         } catch (...) {
415                 return -ENOMEM;
416         }
417
418         m_pInstance->m_sName = strdup(name);
419         if (!m_pInstance->m_sName) {
420                 delete m_pInstance;
421                 return -ENOMEM;
422         }
423
424         table.lb_create = CController::s_CreateLB;
425         table.lb_recreate = CController::s_RecreateLB;
426         table.lb_destroy = CController::s_DestroyLB;
427         table.content_event = CController::s_ContentEvent;
428         table.clicked = CController::s_Clicked;
429         table.text_signal = CController::s_TextEvent;
430         table.resize = CController::s_Resize;
431         table.set_period = CController::s_SetPeriod;
432         table.change_group = CController::s_ChangeGroup;
433         table.pinup = CController::s_Pinup;
434         table.update_content = CController::s_UpdateContent;
435         table.pause = CController::s_Pause;
436         table.resume = CController::s_Resume;
437         table.disconnected = CController::s_Disconnected;
438         table.connected = CController::s_Connected;
439         table.pd_create = CController::s_CreatePD;
440         table.pd_destroy = CController::s_DestroyPD;
441
442         ret = provider_init(ecore_x_display_get(), m_pInstance->m_sName, &table, NULL);
443         if (ret < 0) {
444                 delete m_pInstance;
445                 return ret;
446         }
447
448         return 0;
449 }
450
451 int CController::Finalize(void)
452 {
453         if (!m_pInstance)
454                 return -EINVAL;
455
456         provider_fini();
457
458         delete m_pInstance;
459         return 0;
460 }
461
462 /* End of a file */