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