fix prevent issue #453398
[platform/core/multimedia/libmm-player.git] / src / mm_player_asm.c
1 /*
2  * libmm-player
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: JongHyuk Choi <jhchoi.choi@samsung.com>, YeJin Cho <cho.yejin@samsung.com>,
7  * Seungbae Shin <seungbae.shin@samsung.com>, YoungHwan An <younghwan_.an@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <mm_debug.h>
24 #include <mm_error.h>
25 #include "mm_player_utils.h"
26 #include "mm_player_priv.h"
27 #include "mm_player_asm.h"
28 #include <vconf.h>
29 #include <vconf-internal-sound-keys.h>
30
31 #define MMPLAYER_CHECK_SESSION_SKIP(x_player_asm) \
32 do \
33 { \
34         if (x_player_asm->skip_session == TRUE) \
35         { \
36                 debug_log("skip session"); \
37                 return MM_ERROR_NONE; \
38         } \
39 }while(0);
40
41 #define MMPLAYER_CHECK_SESSION_INSTANCE(x_player_asm) \
42 do \
43 { \
44         if (!x_player_asm) \
45         { \
46                 debug_log("no session instance");\
47                 return MM_ERROR_SOUND_NOT_INITIALIZED; \
48         } \
49 }while(0);
50
51 static ASM_sound_events_t __mmplayer_asm_get_event_type(gint type);
52
53 const gchar *
54 __mmplayer_asm_get_state_name ( int state )
55 {
56         switch ( state )
57         {
58                 case ASM_STATE_NONE:
59                         return "NONE";
60                 case ASM_STATE_PLAYING:
61                         return "PLAYING";
62                 case ASM_STATE_PAUSE:
63                         return "PAUSED";
64                 case ASM_STATE_STOP:
65                         return "STOP";
66                 case ASM_STATE_WAITING:
67                         return "BUFFERING";
68                 default:
69                         return "INVAID";
70         }
71 }
72
73 #define MMPLAYER_ASM_STATE_GET_NAME(state)      __mmplayer_asm_get_state_name(state)
74
75 gint
76 _mmplayer_asm_register(MMPlayerASM* sm, ASM_sound_cb_t callback, void* param)
77 {
78         return MM_ERROR_NONE;
79
80         gint session_type = MM_SESSION_TYPE_MEDIA;
81         gint session_options = 0;
82         gint errorcode = MM_ERROR_NONE;
83         gint asm_handle = -1;
84         gint event_type = ASM_EVENT_NONE;
85         gint pid = -1;
86
87         MMPLAYER_FENTER();
88
89         MMPLAYER_CHECK_SESSION_INSTANCE(sm);
90         MMPLAYER_CHECK_SESSION_SKIP(sm);
91
92         /* check if it's running on the media_server */
93         if ( sm->pid > 0 )
94         {
95                 pid = sm->pid;
96                 debug_log("mm-player is running on different process. Just faking pid to [%d]. :-p\n", pid);
97         }
98
99         /* read session information */
100         errorcode = _mm_session_util_read_information(pid, &session_type, &session_options);
101         if ( errorcode )
102         {
103                 debug_warning("Read Session Type failed. use default \"media\" type\n");
104                 session_type = MM_SESSION_TYPE_MEDIA;
105         }
106
107         /* interpret session information */
108         event_type = __mmplayer_asm_get_event_type(session_type);
109
110         /* check if it's one of CALL series */
111         if ( event_type == ASM_EVENT_CALL ||
112                 event_type == ASM_EVENT_VIDEOCALL ||
113                 event_type == ASM_EVENT_VOIP)
114         {
115                 debug_warning("session type is one of CALL series(%d), skip registering ASM\n", session_type);
116                 sm->event = event_type;
117                 sm->skip_session = TRUE;
118                 return MM_ERROR_NONE;
119         }
120
121         /* register audio-session-manager handle and callback */
122         if( ! ASM_register_sound(pid, &asm_handle, event_type, ASM_STATE_NONE, callback, (void*)param, ASM_RESOURCE_NONE, &errorcode))
123         {
124                 debug_error("ASM_register_sound() failed, error(%x)\n", errorcode);
125                 return errorcode;
126         }
127         /* set session options */
128         if (session_options)
129         {
130                 if( ! ASM_set_session_option(asm_handle, session_options, &errorcode))
131                 {
132                         debug_error("ASM_set_session_options() failed, error(%x)\n", errorcode);
133                         return errorcode;
134                 }
135         }
136
137         /* now succeed to register our callback. take result */
138         sm->handle = asm_handle;
139         sm->state = ASM_STATE_NONE;
140         sm->event = event_type;
141
142         MMPLAYER_FLEAVE();
143
144         return MM_ERROR_NONE;
145 }
146
147 gint
148 _mmplayer_asm_unregister(MMPlayerASM* sm)
149 {
150         gint event_type = ASM_EVENT_NONE;
151         gint errorcode = 0;
152         gint pid = -1;
153
154         MMPLAYER_FENTER();
155
156         MMPLAYER_CHECK_SESSION_INSTANCE(sm);
157         MMPLAYER_CHECK_SESSION_SKIP(sm);
158
159         /* check if it's running on the media_server */
160         if ( sm->pid > 0 )
161         {
162                 pid = sm->pid;
163                 debug_log("mm-player is running on different process. Just faking pid to [%d]. :-p\n", pid);
164         }
165
166         event_type = sm->event;
167
168         if (sm->handle)
169         {
170                 if( ! ASM_unregister_sound( sm->handle, event_type, &errorcode) )
171                 {
172                         debug_error("Unregister sound failed 0x%X\n", errorcode);
173                         return MM_ERROR_POLICY_INTERNAL;
174                 }
175         }
176         debug_warning("asm unregistered");
177
178         MMPLAYER_FLEAVE();
179
180         return MM_ERROR_NONE;
181 }
182
183 gint _mmplayer_asm_set_state(MMHandleType hplayer, ASM_sound_states_t state, gboolean enable_safety_vol)
184 {
185         return MM_ERROR_NONE;
186
187         gint event_type = ASM_EVENT_NONE;
188         gint pid = -1;
189 //      int vconf_safety_vol_val = 0;
190         ASM_resource_t resource = ASM_RESOURCE_NONE;
191         mm_player_t *player = (mm_player_t *)hplayer;
192         MMPlayerASM* sm  = &player->sm;
193         MMPLAYER_FENTER();
194
195 #if 0
196         if (player->set_mode.safety_volume)
197         {
198                 /* get safety volume */
199                 if (vconf_get_int(VCONFKEY_SOUND_ENABLE_SAFETY_VOL, &vconf_safety_vol_val))
200                 {
201                         debug_error ("failed to get safety volume");
202                 }
203
204                 if (enable_safety_vol)
205                 {
206                         vconf_safety_vol_val = vconf_safety_vol_val | VCONFKEY_SOUND_SAFETY_VOL_FW_MMPLAYER;
207                 }
208                 else
209                 {
210                         vconf_safety_vol_val = vconf_safety_vol_val & ~VCONFKEY_SOUND_SAFETY_VOL_FW_MMPLAYER;
211                 }
212
213                 /* set safety volume */
214                 if (vconf_set_int(VCONFKEY_SOUND_ENABLE_SAFETY_VOL, vconf_safety_vol_val))
215                 {
216                         debug_error ("failed to set safety volume");
217                 }
218                 debug_log("safety vol : %d(0:false, 1:true), current result of vconf val : 0x%x", enable_safety_vol, vconf_safety_vol_val);
219         }
220 #endif
221         MMPLAYER_CHECK_SESSION_INSTANCE(sm);
222         MMPLAYER_CHECK_SESSION_SKIP(sm);
223
224         /* check if it's running on the media_server */
225         if ( sm->pid > 0 )
226         {
227                 pid = sm->pid;
228                 debug_log("mm-player is running on different process. Just faking pid to [%d]. :-p\n", pid);
229         }
230
231         /* in case of stop, it should be stop first and post interrupt message to application */
232         if ( !sm->by_asm_cb || state == ASM_STATE_STOP)//|| sm->state == ASM_STATE_PLAYING )
233         {
234                 int ret = 0;
235                 event_type = sm->event;
236                 resource = sm->resource;
237
238                 /* check if there is video */
239                 /* NOTE: resource can be set as NONE when it's not occupied or unknown resource is used. */
240                 if(ASM_STATE_PLAYING == state || ASM_STATE_PAUSE == state || ASM_STATE_WAITING == state)
241                 {
242                         int surface_type = 0;
243                         mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &surface_type);
244                         debug_log("surface type = %d", surface_type);
245
246                         if (player->pipeline && player->pipeline->videobin)
247                         {
248                                 if(surface_type == MM_DISPLAY_SURFACE_X)
249                                 {
250                                         resource = ASM_RESOURCE_VIDEO_OVERLAY | ASM_RESOURCE_HW_DECODER;
251                                 }
252                                 else if (surface_type == MM_DISPLAY_SURFACE_EVAS)
253                                 {
254                                         resource = ASM_RESOURCE_HW_DECODER;
255                                 }
256                         }
257
258                         if( __mmplayer_is_streaming (player))
259                                 resource = resource | ASM_RESOURCE_STREAMING;
260
261                         /* reset */
262                         sm->keep_last_pos = FALSE;
263                 }
264
265                 if( ((sm->state != state) || (sm->resource != resource)) && ! ASM_set_sound_state( sm->handle, event_type, state, resource, &ret) )
266                 {
267                         gint retval = MM_ERROR_POLICY_INTERNAL;
268
269                         debug_error("Set state to [%d] failed 0x%X\n", state, ret);
270                         switch(ret)
271                         {
272                                 case ERR_ASM_POLICY_CANNOT_PLAY:
273                                 case ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL:
274                                 case ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM:
275                                         retval = MM_ERROR_POLICY_BLOCKED;
276                                         break;
277                                 default:
278                                         retval = MM_ERROR_POLICY_INTERNAL;
279                                         break;
280                         }
281
282                         return retval;
283                 }
284         }
285         else
286         {
287                 sm->by_asm_cb = FALSE;
288         }
289
290         sm->state = state;
291
292         /* waiting to be changed because callback can be called */
293         if (ASM_STATE_STOP == state)
294         {
295                 ASM_sound_states_t session_state;
296                 ASM_get_sound_state(sm->handle, event_type, &session_state, NULL);
297         }
298
299         debug_error("ASM state changed to [%s]", MMPLAYER_ASM_STATE_GET_NAME(state));
300         MMPLAYER_FLEAVE();
301         return MM_ERROR_NONE;
302 }
303
304 static ASM_sound_events_t
305 __mmplayer_asm_get_event_type(gint type)
306 {
307         gint event_type = ASM_EVENT_NONE;
308
309         /* interpret session type */
310         switch(type)
311         {
312                 case MM_SESSION_TYPE_CALL:
313                         event_type = ASM_EVENT_CALL;
314                         break;
315
316                 case MM_SESSION_TYPE_VIDEOCALL:
317                         event_type = ASM_EVENT_VIDEOCALL;
318                         break;
319
320                 case MM_SESSION_TYPE_VOIP:
321                         event_type = ASM_EVENT_VOIP;
322                         break;
323
324                 case MM_SESSION_TYPE_MEDIA:
325 //              case MM_SESSION_TYPE_MEDIA_RECORD:
326                         event_type = ASM_EVENT_MEDIA_MMPLAYER;
327                         break;
328
329                 case MM_SESSION_TYPE_NOTIFY:
330                         event_type = ASM_EVENT_NOTIFY;
331                         break;
332
333                 case MM_SESSION_TYPE_ALARM:
334                         event_type = ASM_EVENT_ALARM;
335                         break;
336
337                 case MM_SESSION_TYPE_EMERGENCY:
338                         event_type = ASM_EVENT_EMERGENCY;
339                         break;
340 #if 0
341                 case MM_SESSION_TYPE_RECORD_VIDEO:
342                 case MM_SESSION_TYPE_RECORD_AUDIO:
343                         event_type = ASM_EVENT_MEDIA_MMPLAYER;
344                         break;
345 #endif
346
347                 default:
348                         debug_msg("unexpected case!\n");
349                         event_type = ASM_EVENT_MEDIA_MMPLAYER;
350                         break;
351         }
352
353         return event_type;
354 }
355
356 gint
357 _mmplayer_asm_ignore_session(MMHandleType hplayer)
358 {
359         mm_player_t *player = (mm_player_t *)hplayer;
360
361         MMPLAYER_FENTER();
362
363         return_val_if_fail (player, MM_ERROR_PLAYER_NOT_INITIALIZED);
364
365         /* check state */
366         if (player->state != MM_PLAYER_STATE_NULL)
367         {
368                 debug_log("invalid state to make session mix");
369                 return MM_ERROR_PLAYER_INVALID_STATE;
370         }
371
372         if (player->sm.skip_session == FALSE && player->sm.handle)
373         {
374                 int error_code = 0;
375
376                 if (!ASM_unregister_sound(player->sm.handle, player->sm.event, &error_code))
377                 {
378                         debug_error("Unregister sound failed 0x%X", error_code);
379                         return MM_ERROR_POLICY_INTERNAL;
380                 }
381                 player->sm.skip_session = TRUE;
382                 player->sm.handle = 0;
383
384                 debug_log("session skip enabled");
385         }
386
387         MMPLAYER_FLEAVE();
388
389         return MM_ERROR_NONE;
390 }