Apply the Listener
[profile/tv/apps/native/videoplayer.git] / src / volume.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 <media/sound_manager.h>
20 #include <dbg.h>
21 #include "define.h"
22 #include "volume.h"
23
24 #define TIME_INTERVAL 3.0
25
26 struct volume_data {
27         Evas_Object *ly;
28         Evas_Object *bar;
29         Ecore_Timer *timer;
30         int volume;
31         Eina_Bool mute;
32 };
33
34 static void _set_mute(struct volume_data *data, Eina_Bool mute)
35 {
36         int r;
37         int vol;
38
39         if (data->mute == mute)
40                 return;
41
42         if (mute) {
43                 r = sound_manager_get_volume(SOUND_TYPE_MEDIA, &vol);
44                 if (r < 0)
45                         return;
46
47                 data->volume = vol;
48                 data->mute = EINA_TRUE;
49         } else {
50                 sound_manager_set_volume(SOUND_TYPE_MEDIA, data->volume);
51                 data->mute = EINA_FALSE;
52         }
53 }
54
55 static void _handle_volume(struct volume_data *data, enum volume_val val)
56 {
57         int vol;
58         int r;
59
60         vol = 0;
61
62         switch (val) {
63         case E_VOLUME_UP:
64         case E_VOLUME_DOWN:
65                 _set_mute(data, EINA_FALSE);
66
67                 r = sound_manager_get_volume(SOUND_TYPE_MEDIA, &vol);
68                 if (r != SOUND_MANAGER_ERROR_NONE) {
69                         _ERR("get volume error");
70                         return;
71                 }
72
73                 vol += val;
74
75                 sound_manager_set_volume(SOUND_TYPE_MEDIA, vol);
76                 break;
77         case E_VOLUME_MUTE:
78                 _set_mute(data, !data->mute);
79                 break;
80         default:
81                 break;
82         }
83 }
84
85 static void _update_volume_bar(struct volume_data *data)
86 {
87         double val;
88         int vol;
89         char buf[8];
90         int r;
91
92         if (!data->bar)
93                 return;
94
95         r = sound_manager_get_volume(SOUND_TYPE_MEDIA, &vol);
96         if (r != SOUND_MANAGER_ERROR_NONE) {
97                 _ERR("get volume error");
98                 vol = 0;
99         }
100
101         if (vol == 0 || data->mute) {
102                 elm_object_signal_emit(data->ly, SIG_VOLUME_MUTE, "base");
103                 val = 0;
104         } else {
105                 elm_object_signal_emit(data->ly, SIG_VOLUME_UNMUTE, "base");
106                 val = vol * 0.01;
107         }
108
109         elm_progressbar_value_set(data->bar, val);
110
111         snprintf(buf, sizeof(buf), "%d", vol);
112         elm_object_part_text_set(data->ly, PART_VOLUME_VALUE, buf);
113 }
114
115 static Eina_Bool _volume_timer_cb(void *dt)
116 {
117         struct volume_data *data;
118
119         if (!dt)
120                 return ECORE_CALLBACK_CANCEL;
121
122         data = (volume_data *)dt;
123
124         evas_object_hide(data->ly);
125         data->timer = NULL;
126
127         return ECORE_CALLBACK_CANCEL;
128 }
129
130 void volume_handle_key(struct volume_data *data, enum volume_val val)
131 {
132         if (!data)
133                 return;
134
135         if (!data->timer) {
136                 data->timer = ecore_timer_add(TIME_INTERVAL,
137                                 _volume_timer_cb, data);
138                 evas_object_show(data->ly);
139         } else {
140                 ecore_timer_reset(data->timer);
141         }
142
143         _handle_volume(data, val);
144         _update_volume_bar(data);
145 }
146
147 void volume_hide_bar(struct volume_data *data)
148 {
149         if (!data->timer)
150                 return;
151
152         evas_object_hide(data->ly);
153         ecore_timer_del(data->timer);
154         data->timer = NULL;
155 }
156
157 Eina_Bool volume_add_bar(struct volume_data *data, Evas_Object *base)
158 {
159         Evas_Object *ly;
160         Evas_Object *bar;
161
162         if (!base) {
163                 _ERR("failed to get base object");
164                 return EINA_FALSE;
165         }
166
167         ly = elm_layout_add(base);
168         if (!ly) {
169                 free(data);
170                 return EINA_FALSE;
171         }
172
173         elm_layout_file_set(ly, EDJEFILE, GRP_VOLUME);
174         elm_win_resize_object_add(base, ly);
175         evas_object_hide(ly);
176
177         bar = elm_progressbar_add(ly);
178         if (!bar) {
179                 _ERR("failed to create progressbar");
180                 free(data);
181                 evas_object_del(ly);
182                 return EINA_FALSE;
183         }
184
185         evas_object_size_hint_weight_set(bar, EVAS_HINT_EXPAND,
186                         EVAS_HINT_EXPAND);
187         elm_progressbar_horizontal_set(bar, EINA_TRUE);
188         elm_object_style_set(bar, STYLE_VOLUME_BAR);
189         elm_object_part_content_set(ly, PART_VOLUME_BAR, bar);
190         evas_object_show(bar);
191
192         data->ly = ly;
193         data->bar = bar;
194
195         return EINA_TRUE;
196 }
197
198 void volume_fini(struct volume_data *data)
199 {
200         ecore_timer_del(data->timer);
201         free(data);
202 }
203
204 struct volume_data *volume_init(void)
205 {
206         struct volume_data *data;
207
208         data = (volume_data *)calloc(1, sizeof(*data));
209         if (!data) {
210                 _ERR("allocation fail");
211                 return NULL;
212         }
213
214         sound_manager_set_session_type(SOUND_SESSION_TYPE_EXCLUSIVE);
215
216         return data;
217 }