tizen 2.3.1 release
[framework/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         gint session_type = MM_SESSION_TYPE_MEDIA;
79         gint session_options = 0;
80         gint errorcode = MM_ERROR_NONE;
81         gint asm_handle = -1;
82         gint event_type = ASM_EVENT_NONE;
83         gint pid = -1;
84
85         MMPLAYER_FENTER();
86
87         MMPLAYER_CHECK_SESSION_INSTANCE(sm);
88         MMPLAYER_CHECK_SESSION_SKIP(sm);
89
90         /* check if it's running on the media_server */
91         if ( sm->pid > 0 )
92         {
93                 pid = sm->pid;
94                 debug_log("mm-player is running on different process. Just faking pid to [%d]. :-p\n", pid);
95         }
96
97         /* read session information */
98         errorcode = _mm_session_util_read_information(pid, &session_type, &session_options);
99         if ( errorcode )
100         {
101                 debug_warning("Read Session Type failed. use default \"media\" type\n");
102                 session_type = MM_SESSION_TYPE_MEDIA;
103         }
104
105         /* interpret session information */
106         event_type = __mmplayer_asm_get_event_type(session_type);
107
108         /* check if it's one of CALL series */
109         if ( event_type == ASM_EVENT_CALL ||
110                 event_type == ASM_EVENT_VIDEOCALL ||
111                 event_type == ASM_EVENT_VOIP)
112         {
113                 debug_warning("session type is one of CALL series(%d), skip registering ASM\n", session_type);
114                 sm->event = event_type;
115                 sm->skip_session = TRUE;
116                 return MM_ERROR_NONE;
117         }
118
119         /* register audio-session-manager handle and callback */
120         if( ! ASM_register_sound(pid, &asm_handle, event_type, ASM_STATE_NONE, callback, (void*)param, ASM_RESOURCE_NONE, &errorcode))
121         {
122                 debug_error("ASM_register_sound() failed, error(%x)\n", errorcode);
123                 return errorcode;
124         }
125         /* set session options */
126         if (session_options)
127         {
128                 if( ! ASM_set_session_option(asm_handle, session_options, &errorcode))
129                 {
130                         debug_error("ASM_set_session_options() failed, error(%x)\n", errorcode);
131                         return errorcode;
132                 }
133         }
134
135         /* now succeed to register our callback. take result */
136         sm->handle = asm_handle;
137         sm->state = ASM_STATE_NONE;
138         sm->event = event_type;
139
140         MMPLAYER_FLEAVE();
141
142         return MM_ERROR_NONE;
143 }
144
145 gint
146 _mmplayer_asm_unregister(MMPlayerASM* sm)
147 {
148         gint event_type = ASM_EVENT_NONE;
149         gint errorcode = 0;
150         gint pid = -1;
151
152         MMPLAYER_FENTER();
153
154         MMPLAYER_CHECK_SESSION_INSTANCE(sm);
155         MMPLAYER_CHECK_SESSION_SKIP(sm);
156
157         /* check if it's running on the media_server */
158         if ( sm->pid > 0 )
159         {
160                 pid = sm->pid;
161                 debug_log("mm-player is running on different process. Just faking pid to [%d]. :-p\n", pid);
162         }
163
164         event_type = sm->event;
165
166         if (sm->handle)
167         {
168                 if( ! ASM_unregister_sound( sm->handle, event_type, &errorcode) )
169                 {
170                         debug_error("Unregister sound failed 0x%X\n", errorcode);
171                         return MM_ERROR_POLICY_INTERNAL;
172                 }
173         }
174         debug_warning("asm unregistered");
175
176         MMPLAYER_FLEAVE();
177
178         return MM_ERROR_NONE;
179 }
180
181 gint _mmplayer_asm_set_state(MMHandleType hplayer, ASM_sound_states_t state, gboolean enable_safety_vol)
182 {
183         gint event_type = ASM_EVENT_NONE;
184         gint pid = -1;
185         int vconf_safety_vol_val = 0;
186         ASM_resource_t resource = ASM_RESOURCE_NONE;
187         mm_player_t *player = (mm_player_t *)hplayer;
188         MMPlayerASM* sm  = &player->sm;
189         MMPLAYER_FENTER();
190
191         if (player->set_mode.safety_volume)
192         {
193                 /* get safety volume */
194                 if (vconf_get_int(VCONFKEY_SOUND_ENABLE_SAFETY_VOL, &vconf_safety_vol_val))
195                 {
196                         debug_error ("failed to get safety volume");
197                 }
198
199                 if (enable_safety_vol)
200                 {
201                         vconf_safety_vol_val = vconf_safety_vol_val | VCONFKEY_SOUND_SAFETY_VOL_FW_MMPLAYER;
202                 }
203                 else
204                 {
205                         vconf_safety_vol_val = vconf_safety_vol_val & ~VCONFKEY_SOUND_SAFETY_VOL_FW_MMPLAYER;
206                 }
207
208                 /* set safety volume */
209                 if (vconf_set_int(VCONFKEY_SOUND_ENABLE_SAFETY_VOL, vconf_safety_vol_val))
210                 {
211                         debug_error ("failed to set safety volume");
212                 }
213                 debug_log("safety vol : %d(0:false, 1:true), current result of vconf val : 0x%x", enable_safety_vol, vconf_safety_vol_val);
214         }
215
216         MMPLAYER_CHECK_SESSION_INSTANCE(sm);
217         MMPLAYER_CHECK_SESSION_SKIP(sm);
218
219         /* check if it's running on the media_server */
220         if ( sm->pid > 0 )
221         {
222                 pid = sm->pid;
223                 debug_log("mm-player is running on different process. Just faking pid to [%d]. :-p\n", pid);
224         }
225
226         /* in case of stop, it should be stop first and post interrupt message to application */
227         if ( !sm->by_asm_cb || state == ASM_STATE_STOP)//|| sm->state == ASM_STATE_PLAYING )
228         {
229                 int ret = 0;
230                 event_type = sm->event;
231                 resource = sm->resource;
232
233                 /* check if there is video */
234                 /* NOTE: resource can be set as NONE when it's not occupied or unknown resource is used. */
235                 if(ASM_STATE_PLAYING == state || ASM_STATE_PAUSE == state || ASM_STATE_WAITING == state)
236                 {
237                         int surface_type = 0;
238                         mm_attrs_get_int_by_name (player->attrs, "display_surface_type", &surface_type);
239                         debug_log("surface type = %d", surface_type);
240
241                         if (player->pipeline && player->pipeline->videobin)
242                         {
243                                 if(surface_type == MM_DISPLAY_SURFACE_X)
244                                 {
245                                         resource = ASM_RESOURCE_VIDEO_OVERLAY | ASM_RESOURCE_HW_DECODER;
246                                 }
247                                 else if (surface_type == MM_DISPLAY_SURFACE_EVAS)
248                                 {
249                                         resource = ASM_RESOURCE_HW_DECODER;
250                                 }
251                         }
252
253                         if( __mmplayer_is_streaming (player))
254                                 resource = resource | ASM_RESOURCE_STREAMING;
255
256                         /* reset */
257                         sm->keep_last_pos = FALSE;
258                 }
259
260                 if( ((sm->state != state) || (sm->resource != resource)) && ! ASM_set_sound_state( sm->handle, event_type, state, resource, &ret) )
261                 {
262                         gint retval = MM_ERROR_POLICY_INTERNAL;
263
264                         debug_error("Set state to [%d] failed 0x%X\n", state, ret);
265                         switch(ret)
266                         {
267                                 case ERR_ASM_POLICY_CANNOT_PLAY:
268                                 case ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL:
269                                 case ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM:
270                                         retval = MM_ERROR_POLICY_BLOCKED;
271                                         break;
272                                 default:
273                                         retval = MM_ERROR_POLICY_INTERNAL;
274                                         break;
275                         }
276
277                         return retval;
278                 }
279         }
280         else
281         {
282                 sm->by_asm_cb = FALSE;
283         }
284
285         sm->state = state;
286
287         /* waiting to be changed because callback can be called */
288         if (ASM_STATE_STOP == state)
289         {
290                 ASM_sound_states_t session_state;
291                 ASM_get_sound_state(sm->handle, event_type, &session_state, NULL);
292         }
293
294         debug_error("ASM state changed to [%s]", MMPLAYER_ASM_STATE_GET_NAME(state));
295         MMPLAYER_FLEAVE();
296         return MM_ERROR_NONE;
297 }
298
299 static ASM_sound_events_t
300 __mmplayer_asm_get_event_type(gint type)
301 {
302         gint event_type = ASM_EVENT_NONE;
303
304         /* interpret session type */
305         switch(type)
306         {
307                 case MM_SESSION_TYPE_CALL:
308                         event_type = ASM_EVENT_CALL;
309                         break;
310
311                 case MM_SESSION_TYPE_VIDEOCALL:
312                         event_type = ASM_EVENT_VIDEOCALL;
313                         break;
314
315                 case MM_SESSION_TYPE_VOIP:
316                         event_type = ASM_EVENT_VOIP;
317                         break;
318
319                 case MM_SESSION_TYPE_MEDIA:
320 //              case MM_SESSION_TYPE_MEDIA_RECORD:
321                         event_type = ASM_EVENT_MEDIA_MMPLAYER;
322                         break;
323
324                 case MM_SESSION_TYPE_NOTIFY:
325                         event_type = ASM_EVENT_NOTIFY;
326                         break;
327
328                 case MM_SESSION_TYPE_ALARM:
329                         event_type = ASM_EVENT_ALARM;
330                         break;
331
332                 case MM_SESSION_TYPE_EMERGENCY:
333                         event_type = ASM_EVENT_EMERGENCY;
334                         break;
335
336                 case MM_SESSION_TYPE_RECORD_VIDEO:
337                 case MM_SESSION_TYPE_RECORD_AUDIO:
338                         event_type = ASM_EVENT_MEDIA_MMPLAYER;
339                         break;
340
341                 default:
342                         debug_msg("unexpected case!\n");
343                         event_type = ASM_EVENT_MEDIA_MMPLAYER;
344                         break;
345         }
346
347         return event_type;
348 }