Din't register soubscribe_signal_for_daemon
[platform/core/multimedia/libmm-radio.git] / src / mm_radio_sound_focus.c
1 /*
2  * mm_radio_sound_focus.c
3  *
4  * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <assert.h>
21 #include <unistd.h>
22 #include <mm_debug.h>
23 #include <mm_sound.h>
24 #include <mm_sound_focus.h>
25 #include <mm_sound_device.h>
26 #include "mm_radio_utils.h"
27 #include "mm_radio_priv_hal.h"
28 #include "mm_radio_sound_focus.h"
29
30 static void _mmradio_device_connected_cb(MMSoundDevice_t device, bool is_connected, void *user_data)
31 {
32         mm_radio_t *radio = (mm_radio_t *)user_data;
33         int result = MM_ERROR_NONE;
34         mm_sound_device_type_e type;
35
36         MMRADIO_LOG_FENTER();
37         MMRADIO_CHECK_INSTANCE_RETURN_VOID(radio);
38
39         if (mm_sound_get_device_type(device, &type) != MM_ERROR_NONE) {
40                 MMRADIO_LOG_ERROR("getting device type failed");
41         } else {
42                 switch (type) {
43                 case MM_SOUND_DEVICE_TYPE_AUDIOJACK:
44                 case MM_SOUND_DEVICE_TYPE_BLUETOOTH:
45                 case MM_SOUND_DEVICE_TYPE_HDMI:
46                 case MM_SOUND_DEVICE_TYPE_MIRRORING:
47                 case MM_SOUND_DEVICE_TYPE_USB_AUDIO:
48                         if (!is_connected) {
49                                 MMRADIO_LOG_ERROR("sound device unplugged");
50                                 radio->sound_focus.by_focus_cb = MMRADIO_FOCUS_CB_POSTMSG;
51                                 radio->sound_focus.event_src = MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG;
52
53                                 result = _mmradio_stop(radio);
54                                 if (result != MM_ERROR_NONE)
55                                         MMRADIO_LOG_ERROR("failed to stop radio\n");
56                         }
57                         break;
58                 default:
59                         break;
60                 }
61         }
62         MMRADIO_LOG_FLEAVE();
63 }
64
65 void _mmradio_sound_signal_callback(mm_sound_signal_name_t signal, int value, void *user_data)
66 {
67         mm_radio_sound_focus *sound_focus = (mm_radio_sound_focus *)user_data;
68         int ret = MM_ERROR_NONE;
69
70         MMRADIO_LOG_DEBUG("sound signal callback %d / %d", signal, value);
71
72         if (signal == MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS) {
73                 if (value == 1) {
74                         /* unregister watch callback */
75                         if (sound_focus->watch_id > 0) {
76                                 MMRADIO_LOG_DEBUG("unset the focus watch cb %d", sound_focus->watch_id);
77
78                                 ret = mm_sound_unset_focus_watch_callback(sound_focus->watch_id);
79                                 sound_focus->watch_id = 0;
80                                 if (ret != MM_ERROR_NONE)
81                                         MMRADIO_LOG_ERROR("failed to mm_sound_unset_focus_watch_callback()");
82                         }
83                         /* unregister focus callback */
84                         if (sound_focus->focus_id > 0) {
85                                 ret = mm_sound_unregister_focus(sound_focus->focus_id);
86                                 sound_focus->focus_id = 0;
87                                 if (ret != MM_ERROR_NONE)
88                                         MMRADIO_LOG_ERROR("failed to mm_sound_unregister_focus() %d", sound_focus->focus_id);
89                         }
90                         /* unregister device connected callback */
91                         if (sound_focus->device_subs_id > 0) {
92                                 MMRADIO_LOG_DEBUG("unset the device connected cb %d", sound_focus->device_subs_id);
93                                 ret = mm_sound_remove_device_connected_callback(sound_focus->device_subs_id);
94                                 sound_focus->device_subs_id = 0;
95                                 if (ret != MM_ERROR_NONE)
96                                         MMRADIO_LOG_ERROR("failed to mm_sound_remove_device_connected_callback()");
97                         }
98                 }
99         }
100 }
101
102 int mmradio_sound_focus_register(mm_radio_sound_focus *sound_focus,
103         mm_sound_focus_changed_cb focus_cb, mm_sound_focus_changed_watch_cb watch_cb, void *param)
104 {
105         /* read mm-session information */
106         int session_type = MM_SESSION_TYPE_MEDIA;
107         int session_flags = 0;
108         int ret = MM_ERROR_NONE;
109         int pid = getpid();
110         int handle = 0;
111
112         MMRADIO_LOG_FENTER();
113
114         if (!sound_focus) {
115                 MMRADIO_LOG_ERROR("invalid session handle\n");
116                 return MM_ERROR_RADIO_NOT_INITIALIZED;
117         }
118         sound_focus->cur_focus_type = FOCUS_NONE;
119
120         /* read session information */
121         ret = _mm_session_util_read_information(pid, &session_type, &session_flags);
122         MMRADIO_LOG_DEBUG("Read Session type ret:0x%X", ret);
123         if (ret == MM_ERROR_INVALID_HANDLE) {
124                 MMRADIO_LOG_WARNING("subscribe_id=%d\n", sound_focus->subscribe_id);
125                 if (sound_focus->subscribe_id == 0) {
126 /*
127                         ret = mm_sound_subscribe_signal_for_daemon(MM_SOUND_SIGNAL_RELEASE_INTERNAL_FOCUS, pid, &sound_focus->subscribe_id,
128                                                                         (mm_sound_signal_callback)_mmradio_sound_signal_callback, (void*)sound_focus);
129                         if (ret != MM_ERROR_NONE) {
130                                 MMRADIO_LOG_ERROR("mm_sound_subscribe_signal is failed\n");
131                                 return MM_ERROR_POLICY_BLOCKED;
132                         }
133 */
134                         MMRADIO_LOG_DEBUG("register focus watch callback for the value is 0, sub_cb id %d\n", sound_focus->subscribe_id);
135                         /* register watch callback */
136                         ret = mm_sound_set_focus_watch_callback_for_session(pid,
137                                         FOCUS_FOR_BOTH, watch_cb, (void *)param, &sound_focus->watch_id);
138                         if (ret != MM_ERROR_NONE) {
139                                 MMRADIO_LOG_ERROR("mm_sound_set_focus_watch_callback is failed\n");
140                                 return MM_ERROR_POLICY_BLOCKED;
141                         }
142                         MMRADIO_LOG_DEBUG("(%p) set focus watch callback = %d", param, sound_focus->watch_id);
143
144                         /* register device connected callback */
145                         ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG,
146                                         (mm_sound_device_connected_cb)_mmradio_device_connected_cb, (void *)param, &sound_focus->device_subs_id);
147                         if (ret != MM_ERROR_NONE) {
148                                 MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
149                                 return MM_ERROR_POLICY_BLOCKED;
150                         }
151                         MMRADIO_LOG_ERROR("register device connected callback for the value is 0, sub_cb id %d\n", sound_focus->device_subs_id);
152                 }
153                 ret = MM_ERROR_NONE;
154         } else if (ret == MM_ERROR_NONE) {
155                 MMRADIO_LOG_WARNING("Read Session Information success. session_type : %d flags: %d \n", session_type, session_flags);
156                 sound_focus->session_type = session_type;
157                 sound_focus->snd_session_flags = session_flags;
158                 if (sound_focus->session_type == MM_SESSION_TYPE_MEDIA) {
159                         if (sound_focus->snd_session_flags & MM_SESSION_OPTION_PAUSE_OTHERS) {
160                                 /* register focus session */
161                                 sound_focus->pid = pid;
162                                 MMRADIO_LOG_DEBUG("sound register focus pid[%d]", pid);
163                                 ret = mm_sound_focus_get_id(&handle);
164                                 if (ret != MM_ERROR_NONE) {
165                                         MMRADIO_LOG_ERROR("Failed to get sound focus id");
166                                         return MM_ERROR_POLICY_BLOCKED;
167                                 }
168                                 sound_focus->handle = handle;
169
170                                 ret = mm_sound_register_focus_for_session(handle, pid, "radio", focus_cb, param);
171                                 if (ret != MM_ERROR_NONE) {
172                                         MMRADIO_LOG_DEBUG("mm_sound_register_focus_for_session is failed\n");
173                                         return MM_ERROR_POLICY_BLOCKED;
174                                 }
175                                 MMRADIO_LOG_DEBUG("(%p) register focus for session %d", param, pid);
176                                 /* register device_connected_cb */
177                                 ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG,
178                                         (mm_sound_device_connected_cb)_mmradio_device_connected_cb, (void *)param, &sound_focus->device_subs_id);
179                                 if (ret != MM_ERROR_NONE) {
180                                         MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
181                                         return MM_ERROR_POLICY_BLOCKED;
182                                 }
183                                 MMRADIO_LOG_DEBUG("(%p) add device connected callback = %d", param, sound_focus->device_subs_id);
184
185                         } else if (sound_focus->snd_session_flags & MM_SESSION_OPTION_UNINTERRUPTIBLE) {
186                                 /* register device_connected_cb */
187                                 ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG,
188                                         (mm_sound_device_connected_cb)_mmradio_device_connected_cb, (void*)param, &sound_focus->device_subs_id);
189                                 if (ret != MM_ERROR_NONE) {
190                                         MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
191                                         return MM_ERROR_POLICY_BLOCKED;
192                                 }
193                                 MMRADIO_LOG_DEBUG("add device connected callback = %d", sound_focus->device_subs_id);
194                                 MMRADIO_LOG_WARNING("settion flags isn't OPTION_PAUSE_OTHERS and UNINTERRUPTIBLE. skip it..");
195                         } else {
196                                 /* register watch callback */
197                                 ret = mm_sound_set_focus_watch_callback_for_session(pid,
198                                                 FOCUS_FOR_BOTH, watch_cb, (void*)param, &sound_focus->watch_id);
199                                 if (ret != MM_ERROR_NONE) {
200                                         MMRADIO_LOG_ERROR("mm_sound_set_focus_watch_callback is failed\n");
201                                         return MM_ERROR_POLICY_BLOCKED;
202                                 }
203                                 MMRADIO_LOG_DEBUG("set focus watch callback = %d", sound_focus->watch_id);
204
205                                 /* register device connected callback */
206                                 ret = mm_sound_add_device_connected_callback(MM_SOUND_DEVICE_TYPE_EXTERNAL_FLAG,
207                                                 (mm_sound_device_connected_cb)_mmradio_device_connected_cb, (void*)param, &sound_focus->device_subs_id);
208                                 if (ret != MM_ERROR_NONE) {
209                                         MMRADIO_LOG_ERROR("mm_sound_add_device_connected_callback is failed\n");
210                                         return MM_ERROR_POLICY_BLOCKED;
211                                 }
212                                 MMRADIO_LOG_DEBUG("(%p) add device connected callback = %d", param, sound_focus->device_subs_id);
213                         }
214                 } else if (sound_focus->session_type == MM_SESSION_TYPE_REPLACED_BY_STREAM) {
215                         /* didn't register device connected cb */
216                         MMRADIO_LOG_WARNING("this process is using stream info. skip it..");
217                 } else {
218                         MMRADIO_LOG_WARNING("seesion type is not MEDIA (%d)", sound_focus->session_type);
219                         return MM_ERROR_RADIO_INTERNAL;
220                 }
221                 ret = MM_ERROR_NONE;
222         } else {
223                 MMRADIO_LOG_WARNING("Read Session Information failed. skip sound focus register function. errorcode %x \n", ret);
224         }
225
226         MMRADIO_LOG_FLEAVE();
227
228         return MM_ERROR_NONE;
229 }
230
231 int mmradio_sound_focus_deregister(mm_radio_sound_focus *sound_focus)
232 {
233
234         int ret = MM_ERROR_NONE;
235
236         MMRADIO_LOG_FENTER();
237
238         if (!sound_focus) {
239                 MMRADIO_LOG_ERROR("invalid session handle\n");
240                 return MM_ERROR_RADIO_NOT_INITIALIZED;
241         }
242
243         if (sound_focus->watch_id > 0) {
244                 MMRADIO_LOG_DEBUG("unset the focus watch cb %d", sound_focus->watch_id);
245
246                 ret = mm_sound_unset_focus_watch_callback(sound_focus->watch_id);
247                 sound_focus->watch_id = 0;
248                 if (ret != MM_ERROR_NONE)
249                         MMRADIO_LOG_ERROR("failed to mm_sound_unset_focus_watch_callback() ret = %d", ret);
250         }
251         /* unregister focus callback */
252         if (sound_focus->focus_id > 0) {
253                 ret = mm_sound_unregister_focus(sound_focus->focus_id);
254                 sound_focus->focus_id = 0;
255                 if (ret != MM_ERROR_NONE)
256                         MMRADIO_LOG_ERROR("failed to mm_sound_unregister_focus() ret = %d", ret);
257         }
258         /* unregister device connected callback */
259         if (sound_focus->device_subs_id > 0) {
260                 MMRADIO_LOG_DEBUG("unset the device connected cb %d", sound_focus->device_subs_id);
261                 ret = mm_sound_remove_device_connected_callback(sound_focus->device_subs_id);
262                 sound_focus->device_subs_id = 0;
263                 if (ret != MM_ERROR_NONE)
264                         MMRADIO_LOG_ERROR("failed to mm_sound_remove_device_connected_callback() ret = %d", ret);
265         }
266
267         MMRADIO_LOG_FLEAVE();
268
269         return MM_ERROR_NONE;
270 }
271
272 int mmradio_acquire_sound_focus(mm_radio_sound_focus *sound_focus)
273 {
274         int ret = MM_ERROR_NONE;
275         mm_sound_focus_type_e focus_type = FOCUS_NONE;
276         MMRADIO_LOG_FENTER();
277
278         MMRADIO_LOG_ERROR("mmradio_acquire_sound_focus sound_focus->cur_focus_type : %d\n", sound_focus->cur_focus_type);
279
280         focus_type = FOCUS_FOR_BOTH & ~(sound_focus->cur_focus_type);
281         if (focus_type != FOCUS_NONE) {
282                 ret = mm_sound_acquire_focus(sound_focus->handle, focus_type, NULL);
283                 if (ret != MM_ERROR_NONE) {
284                         MMRADIO_LOG_ERROR("mm_sound_acquire_focus is failed\n");
285                         return MM_ERROR_POLICY_BLOCKED;
286                 }
287                 sound_focus->cur_focus_type = FOCUS_FOR_BOTH;
288         }
289
290         MMRADIO_LOG_FLEAVE();
291         return ret;
292 }
293
294 int mmradio_release_sound_focus(mm_radio_sound_focus *sound_focus)
295 {
296         int ret = MM_ERROR_NONE;
297         MMRADIO_LOG_FENTER();
298
299         MMRADIO_LOG_ERROR("mmradio_release_sound_focus sound_focus->cur_focus_type : %d\n", sound_focus->cur_focus_type);
300         if (sound_focus->cur_focus_type != FOCUS_NONE) {
301                 ret = mm_sound_release_focus(sound_focus->handle, sound_focus->cur_focus_type, NULL);
302                 if (ret != MM_ERROR_NONE) {
303                         MMRADIO_LOG_ERROR("mm_sound_release_focus is failed\n");
304                         return MM_ERROR_POLICY_BLOCKED;
305                 }
306                 sound_focus->cur_focus_type = FOCUS_NONE;
307         }
308
309         MMRADIO_LOG_FLEAVE();
310         return ret;
311 }
312
313 #define AUDIO_FOCUS_REASON_MAX  128
314
315 void mmradio_get_sound_focus_reason(mm_sound_focus_state_e focus_state, const char *reason_for_change, enum MMMessageInterruptedCode *event_source, int *postMsg)
316 {
317         MMRADIO_LOG_FENTER();
318         MMRADIO_LOG_ERROR("mmradio_get_sound_focus_reason focus_state : %d reason_for_change :%s\n", focus_state, reason_for_change);
319
320         if (0 == strncmp(reason_for_change, "call-voice", AUDIO_FOCUS_REASON_MAX)
321                 || (0 == strncmp(reason_for_change, "voip", AUDIO_FOCUS_REASON_MAX))
322                 || (0 == strncmp(reason_for_change, "ringtone-voip", AUDIO_FOCUS_REASON_MAX))
323                 || (0 == strncmp(reason_for_change, "ringtone-call", AUDIO_FOCUS_REASON_MAX))
324                 ) {
325                 if (focus_state == FOCUS_IS_RELEASED)
326                         *event_source = MM_MSG_CODE_INTERRUPTED_BY_CALL_START;
327                 else if (focus_state == FOCUS_IS_ACQUIRED)
328                         *event_source = MM_MSG_CODE_INTERRUPTED_BY_CALL_END;
329                 *postMsg = true;
330         } else if (0 == strncmp(reason_for_change, "alarm", AUDIO_FOCUS_REASON_MAX)) {
331                 if (focus_state == FOCUS_IS_RELEASED)
332                         *event_source = MM_MSG_CODE_INTERRUPTED_BY_ALARM_START;
333                 else if (focus_state == FOCUS_IS_ACQUIRED)
334                         *event_source = MM_MSG_CODE_INTERRUPTED_BY_ALARM_END;
335                 *postMsg = true;
336         } else if (0 == strncmp(reason_for_change, "notification", AUDIO_FOCUS_REASON_MAX)) {
337                 if (focus_state == FOCUS_IS_RELEASED)
338                         *event_source = MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_START;
339                 else if (focus_state == FOCUS_IS_ACQUIRED)
340                         *event_source = MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_END;
341                 *postMsg = true;
342         } else if (0 == strncmp(reason_for_change, "emergency", AUDIO_FOCUS_REASON_MAX)) {
343                 if (focus_state == FOCUS_IS_RELEASED)
344                         *event_source = MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_START;
345                 else if (focus_state == FOCUS_IS_ACQUIRED)
346                         *event_source = MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_END;
347                 *postMsg = false;
348         } else if (0 == strncmp(reason_for_change, "media", AUDIO_FOCUS_REASON_MAX)) {
349                 *event_source = MM_MSG_CODE_INTERRUPTED_BY_MEDIA;
350                 *postMsg = false;
351         } else {
352                 *event_source = MM_MSG_CODE_INTERRUPTED_BY_MEDIA;
353                 *postMsg = false;
354         }
355         MMRADIO_LOG_FLEAVE();
356 }