apply FSL license
[apps/core/preloaded/video-player.git] / src / mp-video-sound-path-ctrl.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://www.tizenopensource.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
18 #include <mm_sound.h>
19 #include <Ecore_Evas.h>
20 #include <Elementary.h>
21 #include <appcore-efl.h>
22 #include <appcore-common.h>
23
24 #include "mp-util.h"
25 #include "mp-video-log.h"
26 #include "video-player.h"
27 #include "mp-video-type-define.h"
28 #include "mp-video-value-define.h"
29 #include "mp-video-string-define.h"
30 #include "mp-video-sound-path-ctrl.h"
31
32 #define MP_VIDEO_SOUND_PATH_NUM                 10
33 #define MP_VIDEO_SOUND_PATH_SPEAKER             "Speaker"
34 #define MP_VIDEO_SOUND_PATH_EARJACK             "Headphones"
35
36 static Evas_Object *pVideoSoundPathPopUpHandle = NULL;
37 static Evas_Object *pGroupRadio = NULL;
38 static Evas_Object *pGenList = NULL;
39
40 static Elm_Genlist_Item_Class st_Itc;
41 static char szSoundPathItems[MP_VIDEO_SOUND_PATH_NUM][STR_LEN_MAX];
42 static bool bIsConnectBluetooth = FALSE;
43 static bool bIsConnectEarjack = FALSE;
44
45 void MpVideoSoundpathDeleteRadioButton(void)
46 {
47         VideoLogInfo("");
48
49         if (pGroupRadio) {
50                 evas_object_del(pGroupRadio);
51                 pGroupRadio = NULL;
52         }
53 }
54
55 void MpVideoSoundpathDeletePopupHandle(void)
56 {
57         VideoLogInfo("");
58
59         int nCount = 0;
60
61         for (nCount = 0; nCount < MP_VIDEO_SOUND_PATH_NUM; nCount++) {
62                 memset(&szSoundPathItems[nCount][0], 0,
63                        sizeof(char) * STR_LEN_MAX);
64         }
65
66         MpVideoSoundpathDeleteRadioButton();
67
68         memset(&st_Itc, 0, sizeof(Elm_Genlist_Item_Class));
69
70         if (pGenList) {
71                 evas_object_del(pGenList);
72                 pGenList = NULL;
73         }
74
75         if (pVideoSoundPathPopUpHandle) {
76                 evas_object_del(pVideoSoundPathPopUpHandle);
77                 pVideoSoundPathPopUpHandle = NULL;
78         }
79
80  }
81
82 static char *MpVideoSoundpathGetLabelOfGenlistItemCb(const void *pUserData,
83                                                      Evas_Object *pObject,
84                                                      const char *pPart)
85 {
86         VideoLogInfo("");
87
88         int nIndex = (int)pUserData;
89
90         if (!strcmp(pPart, "elm.text")) {
91                 VideoLogInfo("Index : %d", nIndex);
92                 return strdup(&szSoundPathItems[nIndex][0]);
93         }
94
95         return NULL;
96 }
97
98 static Evas_Object *MpVideoSoundpathGetIconOfGenlistItemCb(const void
99                                                            *pUserData,
100                                                            Evas_Object *pObject,
101                                                            const char *pPart)
102 {
103         VideoLogInfo("");
104
105         int nIndex = (int)pUserData;
106         Evas_Object *pTmpRadio = NULL;
107
108         if (!strcmp(pPart, "elm.icon")) {
109                 VideoLogInfo("Index : %d", nIndex);
110                 pTmpRadio = elm_radio_add(pObject);
111                 elm_radio_state_value_set(pTmpRadio, nIndex);
112                 evas_object_show(pTmpRadio);
113                 elm_radio_group_add(pTmpRadio, pGroupRadio);
114         }
115
116         return pTmpRadio;
117 }
118
119 static void MpVideoSoundpathSelectSoundPathItemCb(void *pUserData,
120                                                   Evas_Object *pObject,
121                                                   void *pEventInfo)
122 {
123         if (pUserData == NULL) {
124                 VideoLogInfo("[ERR]No have pUserData");
125                 return;
126         }
127
128         VideoLogInfo("");
129
130         int nIndex = 0;
131         Elm_Object_Item *pItem = (Elm_Object_Item *) pEventInfo;
132
133         if (pItem) {
134                 nIndex = (int)elm_object_item_data_get(pItem);
135                 VideoLogInfo("Select sound path : %s", szSoundPathItems[nIndex]);
136
137                 if (!strcmp(szSoundPathItems[nIndex], MP_VIDEO_SOUND_PATH_SPEAKER)) {
138                         int nRet = 0;
139
140                         if (MpUtilIsConnectEarjack()) {
141                                 nRet = mm_sound_route_set_system_policy(SYSTEM_AUDIO_ROUTE_POLICY_HANDSET_ONLY);
142                         } else {
143                                 nRet = mm_sound_route_set_system_policy(SYSTEM_AUDIO_ROUTE_POLICY_IGNORE_A2DP);
144                         }
145
146                         elm_radio_value_set(pGroupRadio, MP_SOUND_PATH_SPEAKER);
147                 } else if (!strcmp(szSoundPathItems[nIndex], MP_VIDEO_SOUND_PATH_EARJACK)) {
148                         int nRet = mm_sound_route_set_system_policy(SYSTEM_AUDIO_ROUTE_POLICY_IGNORE_A2DP);
149                         if (nRet != MM_ERROR_NONE) {
150                                 VideoLogInfo("[ERR] mm_sound_route_set_system_policy(0x%x)",  nRet);
151                         } else {
152                                 elm_radio_value_set(pGroupRadio, MP_SOUND_PATH_EARJACK);
153                         }
154                 } else {
155                         int nRet = mm_sound_route_set_system_policy(SYSTEM_AUDIO_ROUTE_POLICY_DEFAULT);
156                         if (nRet != MM_ERROR_NONE) {
157                                 VideoLogInfo("[ERR] mm_sound_route_set_system_policy(0x%x)", nRet);
158                         } else {
159                                 elm_radio_value_set(pGroupRadio, MP_SOUND_PATH_BLUETOOTH);
160                         }
161                 }
162         }
163
164         MpVideoSoundpathDeletePopupHandle();
165 }
166
167 static void MpVideoSoundpathPopupCb(void *pUserData, Evas_Object *pObject,
168                                     void *pEventInfo)
169 {
170         VideoLogInfo("");
171
172         if (pUserData == NULL) {
173                 VideoLogInfo("[ERR]No have pUserData");
174                 return;
175         }
176
177         MpVideoSoundpathDeletePopupHandle();
178 }
179
180 void MpVideoSoundpathCurrentState(Evas_Object *pParent)
181 {
182         VideoLogInfo("");
183
184         int nBluetoothConnect = 0;
185         char *szBluetoothName = NULL;
186         bIsConnectEarjack = FALSE;
187         bIsConnectBluetooth = FALSE;
188
189         /* Speaker */
190         strncpy(&szSoundPathItems[MP_SOUND_PATH_SPEAKER][0], MP_VIDEO_SOUND_PATH_SPEAKER, STR_LEN_MAX - 1);
191
192         /*  Check and Add earjack sound path. */
193         if (MpUtilIsConnectEarjack()) {
194                 VideoLogInfo("Connect earjack.");
195                 bIsConnectEarjack = TRUE;
196                 strncpy(&szSoundPathItems[MP_SOUND_PATH_EARJACK][0], MP_VIDEO_SOUND_PATH_EARJACK, STR_LEN_MAX - 1);
197         } else {
198                 VideoLogInfo("No connect earjack.");
199         }
200
201         /*  Add bluetooth stereo sound path. */
202         if (MM_ERROR_NONE != mm_sound_route_get_a2dp_status(&nBluetoothConnect, &szBluetoothName)) {
203                 VideoLogInfo("[ERR] Fail to check bluetooth stereo sound path.");
204         } else {
205                 if (nBluetoothConnect) {
206                         VideoLogInfo("Connect szBluetoothName : %s", szBluetoothName);
207                         bIsConnectBluetooth = TRUE;
208                         strncpy(&szSoundPathItems[MP_SOUND_PATH_BLUETOOTH][0], szBluetoothName, STR_LEN_MAX - 1);
209                 } else {
210                         VideoLogInfo("Unactivate Bluetooth stereo A2DP.");
211                 }
212         }
213 }
214
215 void MpVideoSoundpathSetRadioButton(void)
216 {
217         VideoLogInfo("");
218
219         int nBluetoothConnect = 0;
220         char *szBluetoothName = NULL;
221         system_audio_route_t nPolicy = 0;
222
223         mm_sound_route_get_system_policy(&nPolicy);
224
225         if (nPolicy == SYSTEM_AUDIO_ROUTE_POLICY_DEFAULT) {
226                 VideoLogInfo("SYSTEM_AUDIO_ROUTE_POLICY_DEFAULT");
227
228                 if (MM_ERROR_NONE != mm_sound_route_get_a2dp_status(&nBluetoothConnect, &szBluetoothName)) {
229                         VideoLogInfo("[ERR] Fail to check bluetooth stereo sound path.");
230                 }
231
232                 if (nBluetoothConnect) {
233                         elm_radio_value_set(pGroupRadio, MP_SOUND_PATH_BLUETOOTH);
234                 } else if (MpUtilIsConnectEarjack()) {
235                         elm_radio_value_set(pGroupRadio, MP_SOUND_PATH_EARJACK);
236                 } else {
237                         elm_radio_value_set(pGroupRadio, MP_SOUND_PATH_SPEAKER);
238                 }
239         } else if (nPolicy == SYSTEM_AUDIO_ROUTE_POLICY_IGNORE_A2DP) {
240                 VideoLogInfo("SYSTEM_AUDIO_ROUTE_POLICY_IGNORE_A2DP");
241
242                 if (MpUtilIsConnectEarjack()) {
243                         elm_radio_value_set(pGroupRadio, MP_SOUND_PATH_EARJACK);
244                 } else {
245                         elm_radio_value_set(pGroupRadio, MP_SOUND_PATH_SPEAKER);
246                 }
247         } else {
248                 VideoLogInfo("SYSTEM_AUDIO_ROUTE_POLICY_HANDSET_ONLY");
249
250                 elm_radio_value_set(pGroupRadio, MP_SOUND_PATH_SPEAKER);
251         }
252 }
253
254 /*
255  * External function
256  */
257 bool MpVideoSoundpathShow(void *pUserData)
258 {
259         if (pUserData == NULL) {
260                 VideoLogInfo("No have popup message or pAppData is null.");
261                 return FALSE;
262         }
263
264         VideoLogInfo("");
265
266         MpVideoSoundpathIsConnectOtherSoundpath();
267
268         if (!bIsConnectBluetooth && !bIsConnectEarjack) {
269                 VideoLogInfo("Soundpath is only speaker.");
270                 return FALSE;
271         }
272
273         Evas_Object *pBox = NULL;
274         Evas_Object *pButton = NULL;
275         VideoAppData *pAppData = (VideoAppData *)pUserData;
276
277         MpVideoSoundpathDeletePopupHandle();
278
279         pVideoSoundPathPopUpHandle = elm_popup_add(pAppData->pMainWindow);
280
281         MpVideoSoundpathCurrentState(pVideoSoundPathPopUpHandle);
282
283         elm_object_style_set(pVideoSoundPathPopUpHandle, "min_menustyle");
284         elm_object_part_text_set(pVideoSoundPathPopUpHandle, "title,text", MP_VIDEO_SOUND_PATH);
285         evas_object_size_hint_weight_set(pVideoSoundPathPopUpHandle, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
286
287         pButton = elm_button_add(pVideoSoundPathPopUpHandle);
288         elm_object_text_set(pButton, dgettext(MP_SYS_STRING, MP_COM_BUTTON_CANCEL));
289         elm_object_part_content_set(pVideoSoundPathPopUpHandle, "button1", pButton);
290         evas_object_smart_callback_add(pButton, "clicked", MpVideoSoundpathPopupCb, (void*)pAppData);
291
292         /*  Set item of Genlist. */
293         st_Itc.item_style = "1text.1icon.3";
294         st_Itc.func.text_get = (void *)MpVideoSoundpathGetLabelOfGenlistItemCb;
295         st_Itc.func.content_get = (void *)MpVideoSoundpathGetIconOfGenlistItemCb;
296         st_Itc.func.state_get = NULL;
297         st_Itc.func.del = NULL;
298
299         /* Create genlist handle */
300         pGenList = elm_genlist_add(pVideoSoundPathPopUpHandle);
301         evas_object_size_hint_weight_set(pGenList, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
302         evas_object_size_hint_align_set(pGenList, EVAS_HINT_FILL, EVAS_HINT_FILL);
303
304         pGroupRadio = elm_radio_add(pGenList);
305
306         if (bIsConnectBluetooth) {
307                 elm_genlist_item_append(pGenList, &st_Itc, (void *)MP_SOUND_PATH_BLUETOOTH, NULL,
308                                         ELM_GENLIST_ITEM_NONE,
309                                         MpVideoSoundpathSelectSoundPathItemCb,
310                                         pAppData);
311         }
312
313         if (bIsConnectEarjack) {
314                 elm_genlist_item_append(pGenList, &st_Itc, (void *)MP_SOUND_PATH_EARJACK, NULL,
315                                         ELM_GENLIST_ITEM_NONE,
316                                         MpVideoSoundpathSelectSoundPathItemCb,
317                                         pAppData);
318         }
319
320         elm_genlist_item_append(pGenList, &st_Itc, (void *)MP_SOUND_PATH_SPEAKER, NULL,
321                                         ELM_GENLIST_ITEM_NONE,
322                                         MpVideoSoundpathSelectSoundPathItemCb,
323                                         pAppData);
324
325         MpVideoSoundpathSetRadioButton();
326
327         pBox = elm_box_add(pVideoSoundPathPopUpHandle);
328         if (bIsConnectBluetooth && bIsConnectEarjack) {
329                 evas_object_size_hint_min_set(pBox, 614 * elm_config_scale_get(), 338 * elm_config_scale_get());
330         } else if(bIsConnectBluetooth || bIsConnectEarjack) {
331                 evas_object_size_hint_min_set(pBox, 614 * elm_config_scale_get(), 225 * elm_config_scale_get());
332         } else {
333                 evas_object_size_hint_min_set(pBox, 614 * elm_config_scale_get(), 451 * elm_config_scale_get());
334         }
335         elm_box_pack_end(pBox, pGenList);
336         elm_object_content_set(pVideoSoundPathPopUpHandle, pBox);
337
338         evas_object_show(pGenList);
339         evas_object_show(pVideoSoundPathPopUpHandle);
340
341         return TRUE;
342 }
343
344 void MpVideoSoundpathHide(void)
345 {
346         VideoLogInfo("");
347
348         MpVideoSoundpathDeletePopupHandle();
349 }
350
351 bool MpVideoSoundpathIsConnectOtherSoundpath(void)
352 {
353         VideoLogInfo("");
354
355         int nBluetoothConnect = 0;
356         char *szBluetoothName = NULL;
357
358         bIsConnectEarjack = FALSE;
359         bIsConnectBluetooth = FALSE;
360
361         if (MpUtilIsConnectEarjack()) {
362                 VideoLogInfo("Connect earjack.");
363                 bIsConnectEarjack= TRUE;
364                 return TRUE;
365         }
366
367         mm_sound_route_get_a2dp_status(&nBluetoothConnect, &szBluetoothName);
368         if (nBluetoothConnect) {
369                 VideoLogInfo("Connect bluetooth.");
370                 bIsConnectBluetooth = TRUE;
371                 return TRUE;
372         }
373
374         VideoLogInfo("Only spaker.");
375         return FALSE;
376 }
377
378 int MpVideoSoundpathGetCurrConnectedSoundpath(void)
379 {
380         VideoLogInfo("");
381
382         int nBluetoothConnect = 0;
383         char *szBluetoothName = NULL;
384         system_audio_route_t nPolicy = 0;
385
386         mm_sound_route_get_system_policy(&nPolicy);
387
388         if (nPolicy == SYSTEM_AUDIO_ROUTE_POLICY_DEFAULT) {
389                 VideoLogInfo("SYSTEM_AUDIO_ROUTE_POLICY_DEFAULT");
390
391                 if (MM_ERROR_NONE != mm_sound_route_get_a2dp_status(&nBluetoothConnect, &szBluetoothName)) {
392                         VideoLogInfo("[ERR] Fail to check bluetooth stereo sound path.");
393                 }
394
395                 if (nBluetoothConnect) {
396                         return MP_SOUND_PATH_BLUETOOTH;
397                 } else if (MpUtilIsConnectEarjack()) {
398                         return MP_SOUND_PATH_EARJACK;
399                 } else {
400                         return MP_SOUND_PATH_SPEAKER;
401                 }
402         } else if (nPolicy == SYSTEM_AUDIO_ROUTE_POLICY_IGNORE_A2DP) {
403                 VideoLogInfo("SYSTEM_AUDIO_ROUTE_POLICY_IGNORE_A2DP");
404
405                 if (MpUtilIsConnectEarjack()) {
406                         return MP_SOUND_PATH_EARJACK;
407                 } else {
408                         return MP_SOUND_PATH_SPEAKER;
409                 }
410         } else {
411                 VideoLogInfo("SYSTEM_AUDIO_ROUTE_POLICY_HANDSET_ONLY");
412
413                 return MP_SOUND_PATH_SPEAKER;
414         }
415 }