Apply the Listener
[profile/tv/apps/native/videoplayer.git] / src / view_player.cpp
1 /*
2  * Copyright (c) 2014 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 <Eina.h>
19 #include <utilX.h>
20 #include <efl_extension.h>
21 #include <AppCommon.h>
22 #include <ViewMgr.h>
23 #include <BaseView.h>
24 #include <dbg.h>
25 #include "define.h"
26 #include "i18n.h"
27 #include "playermgr.h"
28 #include "timeout_handler.h"
29 #include "mediadata.h"
30 #include "control.h"
31 #include "volume.h"
32 #include "slider.h"
33 #include "view_player.h"
34
35 #define BTN_ID "BTN_ID"
36
37 #define TEXT_NOVIDEO N_("No Video")
38 #define TEXT_NORES N_("---- x ----")
39 #define TEXT_NODATE N_("----.--.--")
40 #define TEXT_NOSOURCE N_("-")
41
42 #define CONTROL_BTNS 7
43
44 static const char *_control_name[] = {
45         "prev",
46         "rew",
47         "playpause",
48         "ff",
49         "next",
50         "repeat",
51         "settings"
52 };
53
54 enum update_action {
55         ACTION_HIDE,
56         ACTION_SHOW,
57         ACTION_PLAY
58 };
59
60 typedef void (*btn_event_cb)(void *dt);
61
62 struct SPlayerView {
63         Evas_Object *win;
64         Evas_Object *base;
65         char *id;
66
67         struct playermgr *player;
68         struct control_data *control;
69         struct volume_data *volume;
70         struct slider_data *slider;
71
72         struct timeout_handler *timeout_handle;
73         bool bar_hidden;
74         bool error;
75
76         Ecore_Timer *drawanim_timer;
77         int duration;
78         int repeat;
79 };
80
81 enum _control_btn {
82         E_PREV_BTN = 0,
83         E_REW_BTN,
84         E_PLAYPAUSE_BTN,
85         E_FF_BTN,
86         E_NEXT_BTN,
87         E_REPEAT_BTN,
88         E_SETTINGS_BTN
89 };
90
91 enum _repeat_option {
92         E_REPEAT_ALL = 0,
93         E_REPEAT_ONE,
94         E_REPEAT_NONE
95 };
96
97 void CPlayerView::m_UpdateInfoBar(void)
98 {
99         Evas_Object *obj;
100
101         obj = m->base;
102
103         /* Title */
104         elm_object_part_text_set(obj, PART_TITLETEXT, _(TEXT_NOVIDEO));
105
106         /* Created Time */
107         elm_object_part_text_set(obj, PART_DATETEXT, _(TEXT_NODATE));
108
109         /* Source */
110         elm_object_part_text_set(obj, PART_SOURCETEXT, _(TEXT_NOSOURCE));
111
112         /* Resolution */
113         elm_object_part_text_set(obj, PART_RESOLUTIONTEXT, _(TEXT_NORES));
114 }
115
116 void CPlayerView::m_UpdateInfoBar(struct mediadata *md)
117 {
118         const char *name;
119         char buf[32];
120         time_t video_time;
121         struct tm tm;
122         const struct videodata *vd;
123
124         /* Title */
125         name = mediadata_get_displayname(md);
126         if (name)
127                 elm_object_part_text_set(m->base, PART_TITLETEXT, name);
128
129         /* Created Time */
130         video_time = mediadata_get_modifiedtime(md);
131
132         if (video_time > 0) {
133                 localtime_r(&video_time, &tm);
134                 strftime(buf, sizeof(buf), "%Y.%m.%d", &tm);
135         } else {
136                 snprintf(buf, sizeof(buf), "%s", _(TEXT_NODATE));
137         }
138
139         elm_object_part_text_set(m->base, PART_DATETEXT, buf);
140
141         /* Source */
142         /* TODO: temporary, get actual values and set */
143         elm_object_part_text_set(m->base, PART_SOURCETEXT, _("TV"));
144
145         /* Playlist Count */
146         playermgr_get_play_count(m->player, buf, sizeof(buf));
147         elm_object_part_text_set(m->base, PART_CURRENTTEXT, buf);
148
149         /* Resolution */
150         vd = mediadata_get_video_info(md);
151         if (vd) {
152                 snprintf(buf, sizeof(buf), "%dx%d",
153                                 videodata_get_width(vd),
154                                 videodata_get_height(vd));
155
156                 m->duration = videodata_get_duration(vd);
157         } else {
158                 snprintf(buf, sizeof(buf), "%s", _(TEXT_NORES));
159                 m->duration = 0;
160         }
161
162         elm_object_part_text_set(m->base, PART_RESOLUTIONTEXT, buf);
163 }
164
165 bool CPlayerView::m_PlayVideo(void)
166 {
167         struct mediadata *md;
168         const char *path;
169         int r;
170
171         r = playermgr_play_video(m->player);
172         if (r < 0)
173                 return false;
174
175         path = playermgr_get_video_path(m->player);
176
177         md = mediadata_create(path);
178         if (md) {
179                 m_UpdateInfoBar(md);
180                 mediadata_destroy(md);
181         }
182
183         slider_reset(m->slider, m->duration);
184         control_signal_emit(m->control, E_PLAYPAUSE_BTN, SIG_SET_PAUSE, "");
185
186         if (m->bar_hidden) {
187                 m_ShowBar();
188                 timeout_handler_reset(m->timeout_handle);
189         }
190
191         return true;
192 }
193
194 void CPlayerView::sm_EvtRewindBtn(void *dt)
195 {
196         SPlayerView *data;
197         int r;
198
199         if (!dt)
200                 return;
201
202         data = (SPlayerView *)dt;
203
204         r = playermgr_set_rew(data->player, data->duration);
205
206         if (r > 0) {
207                 slider_pause(data->slider);
208                 control_signal_emit(data->control, E_PLAYPAUSE_BTN,
209                                 SIG_SET_PLAY, "");
210         }
211 }
212
213 void CPlayerView::sm_EvtForwardBtn(void *dt)
214 {
215         SPlayerView *data;
216         int r;
217
218         if (!dt)
219                 return;
220
221         data = (SPlayerView *)dt;
222
223         r = playermgr_set_ff(data->player, data->duration);
224
225         if (r > 0) {
226                 slider_pause(data->slider);
227                 control_signal_emit(data->control, E_PLAYPAUSE_BTN,
228                                 SIG_SET_PLAY, "");
229         }
230 }
231
232 void CPlayerView::sm_EvtPrevBtn(void *dt)
233 {
234         SPlayerView *data;
235         update_action action;
236
237         if (!dt)
238                 return;
239
240         data = (SPlayerView *)dt;
241
242         playermgr_stop_ffrew(data->player);
243         playermgr_set_prev_video(data->player);
244
245         action = ACTION_PLAY;
246         CViewMgr::GetInstance()->UpdateView(data->id, (void *)&action);
247 }
248
249 void CPlayerView::sm_EvtNextBtn(void *dt)
250 {
251         SPlayerView *data;
252         update_action action;
253
254         if (!dt)
255                 return;
256
257         data = (SPlayerView *)dt;
258
259         playermgr_stop_ffrew(data->player);
260         playermgr_set_next_video(data->player, EINA_TRUE);
261
262         action = ACTION_PLAY;
263         CViewMgr::GetInstance()->UpdateView(data->id, (void *)&action);
264 }
265
266 void CPlayerView::sm_EvtReapeatBtn(void *dt)
267 {
268         SPlayerView *data;
269
270         if (!dt)
271                 return;
272
273         data = (SPlayerView *)dt;
274
275         switch (data->repeat) {
276         case E_REPEAT_ALL:
277                 data->repeat = E_REPEAT_ONE;
278                 break;
279         case E_REPEAT_ONE:
280                 data->repeat = E_REPEAT_NONE;
281                 break;
282         case E_REPEAT_NONE:
283                 data->repeat = E_REPEAT_ALL;
284                 break;
285         default:
286                 break;
287         }
288 }
289
290 void CPlayerView::sm_EvtSettingBtn(void *dt)
291 {
292 }
293
294 void CPlayerView::sm_EvtPlayBtn(void *dt)
295 {
296         SPlayerView *data;
297         player_state_e state;
298         int r;
299
300         if (!dt)
301                 return;
302
303         data = (SPlayerView *)dt;
304
305         if (playermgr_get_ffrew(data->player)) {
306                 playermgr_stop_ffrew(data->player);
307                 playermgr_resume(data->player);
308                 slider_resume(data->slider);
309                 return;
310         }
311
312         r = playermgr_get_state(data->player, &state);
313         if (r < 0)
314                 return;
315
316         switch (state) {
317         case PLAYER_STATE_PLAYING:
318                 playermgr_pause(data->player);
319                 slider_pause(data->slider);
320                 break;
321
322         case PLAYER_STATE_PAUSED:
323                 playermgr_resume(data->player);
324                 slider_resume(data->slider);
325                 break;
326         default:
327                 break;
328         }
329 }
330
331 void CPlayerView::sm_EvtControlBtn(void *dt, const char *ev)
332 {
333         SPlayerView *data;
334         btn_event_cb cbs[] = {
335                 sm_EvtPrevBtn,
336                 sm_EvtRewindBtn,
337                 sm_EvtPlayBtn,
338                 sm_EvtForwardBtn,
339                 sm_EvtNextBtn,
340                 sm_EvtReapeatBtn,
341                 sm_EvtSettingBtn,
342         };
343         int i;
344
345         if (!dt || !ev)
346                 return;
347
348         data = (SPlayerView *)dt;
349
350         for (i = 0; i < CONTROL_BTNS; i++) {
351                 if (!strcmp(_control_name[i], ev))
352                         cbs[i](data);
353         }
354 }
355
356 void CPlayerView::sm_CbPlayComplete(void *dt)
357 {
358         SPlayerView *data;
359         update_action action;
360         Eina_Bool r;
361
362         if (!dt)
363                 return;
364
365         data = (SPlayerView *)dt;
366         r = EINA_TRUE;
367
368         if (data->repeat == E_REPEAT_NONE)
369                 r = playermgr_set_next_video(data->player, EINA_FALSE);
370         else if (data->repeat == E_REPEAT_ALL)
371                 r = playermgr_set_next_video(data->player, EINA_TRUE);
372
373         if (!r)
374                 elm_exit();
375
376         action = ACTION_PLAY;
377         CViewMgr::GetInstance()->UpdateView(data->id, (void *)&action);
378 }
379
380 void CPlayerView::sm_CbShowViewFinish(void *dt, Evas_Object *obj,
381                 const char *emission, const char *source)
382 {
383         SPlayerView *data;
384
385         if (!dt)
386                 return;
387
388         data = (SPlayerView *)dt;
389
390         control_show(data->control);
391 }
392
393 void CPlayerView::m_ShowBar(void)
394 {
395         volume_hide_bar(m->volume);
396
397         if (m->bar_hidden) {
398                 elm_object_signal_emit(m->base, SIG_SHOW_VIEW, "");
399                 m->bar_hidden = false;
400                 slider_resume(m->slider);
401         }
402 }
403
404 void CPlayerView::m_HideBar(void)
405 {
406         elm_object_signal_emit(m->base, SIG_HIDE_VIEW, "");
407         m->bar_hidden = true;
408
409         slider_pause(m->slider);
410         control_hide(m->control);
411 }
412
413 void CPlayerView::sm_CbTimeoutEvent(void *dt, int type, void *ev)
414 {
415         SPlayerView *data;
416
417         if (!dt)
418                 return;
419
420         data = (SPlayerView *)dt;
421
422         if (!data->error) {
423                 update_action action;
424
425                 action = ACTION_HIDE;
426                 CViewMgr::GetInstance()->UpdateView(data->id, (void *)&action);
427         }
428 }
429
430 void CPlayerView::sm_EvtBack(void *dt, Evas_Object *obj, void *ev)
431 {
432         SPlayerView *data;
433
434         if (!dt)
435                 return;
436
437         data = (SPlayerView *)dt;
438
439         if (data->bar_hidden) {
440                 update_action action;
441
442                 action = ACTION_SHOW;
443                 CViewMgr::GetInstance()->UpdateView(data->id, (void *)&action);
444         } else {
445                 elm_exit();
446         }
447 }
448
449 void CPlayerView::sm_EvtVolume(SPlayerView *data, int val)
450 {
451         if (!data->bar_hidden) {
452                 update_action action;
453
454                 action = ACTION_HIDE;
455                 CViewMgr::GetInstance()->UpdateView(data->id, (void *)&action);
456         }
457
458         volume_handle_key(data->volume, (enum volume_val)val);
459 }
460
461 void CPlayerView::sm_CbEcoreEvent(void *dt, int type, void *ei)
462 {
463         SPlayerView *data;
464         bool update;
465
466         if (!dt)
467                 return;
468
469         data = (SPlayerView *)dt;
470         update = false;
471
472         if (type == ECORE_EVENT_KEY_UP) {
473                 Evas_Event_Key_Up *ev;
474
475                 ev = (Evas_Event_Key_Up *)ei;
476                 if (!ev)
477                         return;
478
479                 if (!strcmp(ev->keyname, KEY_VOLUMEUP))
480                         sm_EvtVolume(data, E_VOLUME_UP);
481                 else if (!strcmp(ev->keyname, KEY_VOLUMEDOWN))
482                         sm_EvtVolume(data, E_VOLUME_DOWN);
483                 else if (!strcmp(ev->keyname, KEY_MUTE))
484                         sm_EvtVolume(data, E_VOLUME_MUTE);
485                 else
486                         update = true;
487         } else if (type == ECORE_EVENT_MOUSE_MOVE) {
488                 update = true;
489         }
490
491         if (update) {
492                 update_action action;
493
494                 action = ACTION_SHOW;
495                 CViewMgr::GetInstance()->UpdateView(data->id, (void *)&action);
496         }
497 }
498
499 bool CPlayerView::m_AddControls(void)
500 {
501         if (!control_add_bar(m->control, m->base, _control_name, CONTROL_BTNS))
502                 return false;
503
504         m->repeat = E_REPEAT_ALL;
505
506         control_handler_init(m->control, sm_EvtControlBtn, m);
507
508         if (!slider_add_bar(m->slider, m->base, m->player))
509                 return false;
510
511         if (!volume_add_bar(m->volume, m->win))
512                 return false;
513
514         m->timeout_handle = timeout_handler_init(TIMEOUT_VIDEOPLAYER,
515                 sm_CbTimeoutEvent, m, sm_CbEcoreEvent, m);
516
517         eext_object_event_callback_add(m->base,
518                         EEXT_CALLBACK_BACK, sm_EvtBack, m);
519
520         if (!m->timeout_handle)
521                 return false;
522
523         return true;
524 }
525
526 Eina_Bool CPlayerView::sm_CbDrawAnimation(void *dt)
527 {
528         SPlayerView *data;
529
530         if (!dt)
531                 return ECORE_CALLBACK_CANCEL;
532
533         data = (SPlayerView *)dt;
534
535         elm_object_signal_emit(data->base, SIG_SHOW_VIEW, "");
536         control_focus_set(data->control, E_PLAYPAUSE_BTN, EINA_TRUE);
537
538         data->drawanim_timer = NULL;
539
540         return ECORE_CALLBACK_CANCEL;
541 }
542
543 void CPlayerView::m_PlayerInit(SPlayerParam *param)
544 {
545         int r;
546
547         r = mediadata_init();
548         if (r < 0)
549                 _ERR("mediadata init failed");
550
551         if (param->id)
552                 m->id = strdup(param->id);
553
554         m->player = playermgr_init(m->win, param->filepath, param->playlist);
555         if (!m->player)
556                 _ERR("player init failed");
557
558         m->control = control_init();
559         if (!m->control)
560                 _ERR("control init failed");
561
562         m->volume = volume_init();
563         if (!m->volume)
564                 _ERR("volume init failed");
565
566         m->slider = slider_init();
567         if (!m->slider)
568                 _ERR("slider init failed");
569 }
570
571 bool CPlayerView::m_UiInit(void)
572 {
573         Evas_Object *base;
574
575         base = elm_layout_add(m->win);
576         if (!base) {
577                 _ERR("failed to add layout");
578                 return false;
579         }
580
581         m->base = base;
582
583         if (!elm_layout_file_set(base, EDJEFILE, GRP_VIDEO_PLAYER)) {
584                 _ERR("failed to layout file set");
585                 return false;
586         }
587
588         if (!m_AddControls()) {
589                 _ERR("failed to add controls");
590                 return false;
591         }
592
593         evas_object_size_hint_weight_set(base,
594                         EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
595
596         elm_win_resize_object_add(m->win, base);
597
598         evas_object_show(base);
599
600         elm_object_focus_allow_set(base, EINA_FALSE);
601
602         return true;
603 }
604
605 bool CPlayerView::Create(void *data)
606 {
607         ASSERT(!m);
608         ASSERT(data);
609
610         Evas_Object *win;
611         bool r;
612
613         win = CViewMgr::GetInstance()->Window();
614         ASSERT(win);
615
616         m = new SPlayerView;
617         if (!m) {
618                 _ERR("alloc failed");
619                 return false;
620         }
621
622         m->win = win;
623         m->error = false;
624
625         m_PlayerInit((SPlayerParam *)data);
626
627         r = m_UiInit();
628         if (!r) {
629                 delete m;
630                 m = NULL;
631                 return false;
632         }
633
634         if (!m_PlayVideo()) {
635                 _ERR("failed to play video");
636                 m->error = true;
637
638                 m_UpdateInfoBar();
639                 control_hide(m->control);
640                 elm_object_signal_emit(m->base, SIG_SHOW_VIEW, "");
641
642                 CBaseView::Create(NULL);
643                 return true;
644         }
645
646         playermgr_set_completed_cb(m->player, sm_CbPlayComplete, m);
647
648         elm_object_signal_callback_add(m->base, "show,view,finish", "",
649                         sm_CbShowViewFinish, m);
650
651         m->drawanim_timer = ecore_timer_add(0.8, sm_CbDrawAnimation, m);
652         if (!m->drawanim_timer) {
653                 _ERR("failed to add draw timer");
654                 return false;
655         }
656
657         CBaseView::Create(NULL);
658
659         return true;
660 }
661
662 void CPlayerView::Destroy(void)
663 {
664         ASSERT(m);
665
666         CBaseView::Destroy();
667
668         if (m->drawanim_timer)
669                 ecore_timer_del(m->drawanim_timer);
670
671         mediadata_fini();
672
673         playermgr_fini(m->player);
674
675         volume_fini(m->volume);
676         slider_fini(m->slider);
677         control_fini(m->control);
678
679         timeout_handler_fini(m->timeout_handle);
680
681         free(m->id);
682
683         delete m;
684         m = NULL;
685 }
686
687 Evas_Object *CPlayerView::Base(void)
688 {
689         ASSERT(m);
690
691         return m->base;
692 }
693
694 void CPlayerView::t_OnShow(void)
695 {
696         ASSERT(m);
697
698         evas_object_show(m->base);
699 }
700
701 void CPlayerView::t_OnHide(void)
702 {
703         evas_object_hide(m->base);
704 }
705
706 void CPlayerView::t_OnPause(void)
707 {
708         elm_exit();
709 }
710
711 void CPlayerView::t_OnUpdate(void *dt)
712 {
713         update_action *action;
714
715         if (!dt)
716                 return;
717
718         action = (update_action *)dt;
719
720         switch (*action) {
721         case ACTION_HIDE:
722                 m_HideBar();
723                 break;
724         case ACTION_SHOW:
725                 m_ShowBar();
726                 break;
727         case ACTION_PLAY:
728                 m_PlayVideo();
729                 break;
730         }
731 }