Use socket for IPC of focus APIs instead of the DBus
[platform/core/multimedia/libmm-sound.git] / mm_sound_focus.c
1 /*
2  * libmm-sound
3  *
4  * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Sangchul Lee <sc11.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <mm_debug.h>
25
26 #include "include/mm_sound.h"
27 #include "include/mm_sound_client.h"
28
29 #define RETURN_ERROR_IF_FOCUS_CB_THREAD(x_thread) \
30 { \
31         int ret = MM_ERROR_NONE; \
32         bool result = false; \
33         ret = mm_sound_client_is_focus_cb_thread(x_thread, &result); \
34         if (ret) \
35                 return ret; \
36         if (result) { \
37                 debug_error("it might be called in the thread of focus callback, it is not allowed"); \
38                 return MM_ERROR_SOUND_INVALID_OPERATION; \
39         } \
40 } \
41
42 EXPORT_API
43 int mm_sound_focus_is_cb_thread(bool *result)
44 {
45         int ret = MM_ERROR_NONE;
46
47         debug_fenter();
48
49         ret = mm_sound_client_is_focus_cb_thread(g_thread_self(), result);
50         if (!ret) {
51                 if (*result)
52                         debug_msg("it might be called in the thread of focus callback");
53         }
54
55         debug_fleave();
56
57         return ret;
58 }
59
60 EXPORT_API
61 int mm_sound_register_focus(const char *stream_type, mm_sound_focus_changed_cb callback, void *user_data, int *id)
62 {
63         int ret = MM_ERROR_NONE;
64
65         debug_fenter();
66
67         RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
68
69         if (id == NULL || callback == NULL) {
70                 debug_error("argument is not valid");
71                 return MM_ERROR_INVALID_ARGUMENT;
72         }
73
74         ret = mm_sound_client_register_focus(getpid(), stream_type, callback, user_data, id);
75         if (ret)
76                 debug_error("Could not register focus, ret[0x%x]", ret);
77
78         debug_fleave();
79
80         return ret;
81 }
82
83 EXPORT_API
84 int mm_sound_unregister_focus(int id)
85 {
86         int ret = MM_ERROR_NONE;
87         bool result = false;
88
89         debug_fenter();
90
91         if (id <= 0) {
92                 debug_error("argument is not valid");
93                 return MM_ERROR_INVALID_ARGUMENT;
94         }
95
96         mm_sound_client_is_focus_cb_thread(g_thread_self(), &result);
97         if (!result) {
98                 if ((ret = mm_sound_client_unregister_focus(id)))
99                         debug_error("Could not unregister focus, ret = %x", ret);
100         } else {
101                 ret = mm_sound_client_execute_focus_func_in_main_context(IDLE_EVENT_TYPE_UNREGISTER_FOCUS, id);
102         }
103
104         debug_fleave();
105
106         return ret;
107 }
108
109 EXPORT_API
110 int mm_sound_set_focus_reacquisition(int id, bool reacquisition)
111 {
112         int ret = MM_ERROR_NONE;
113
114         debug_fenter();
115
116         if (id < 0) {
117                 debug_error("argument is not valid");
118                 return MM_ERROR_INVALID_ARGUMENT;
119         }
120
121         if ((ret = mm_sound_client_set_focus_reacquisition(id, reacquisition)))
122                 debug_error("Could not set focus reacquisition, ret[0x%x]", ret);
123
124         debug_fleave();
125
126         return ret;
127 }
128
129 EXPORT_API
130 int mm_sound_get_focus_reacquisition(int id, bool *reacquisition)
131 {
132         int ret = MM_ERROR_NONE;
133
134         debug_fenter();
135
136         if (id < 0 || !reacquisition) {
137                 debug_error("argument is not valid");
138                 return MM_ERROR_INVALID_ARGUMENT;
139         }
140
141         ret = mm_sound_client_get_focus_reacquisition(id, reacquisition);
142         if (ret)
143                 debug_error("Could not get focus reacquisition, ret[0x%x]", ret);
144
145         debug_fleave();
146
147         return ret;
148 }
149
150 EXPORT_API
151 int mm_sound_get_stream_type_of_acquired_focus(int focus_type, char **stream_type, int *option, char **ext_info)
152 {
153         int ret = MM_ERROR_NONE;
154
155         debug_fenter();
156
157         if (stream_type == NULL) {
158                 debug_error("argument is not valid");
159                 return MM_ERROR_INVALID_ARGUMENT;
160         }
161
162         ret = mm_sound_client_get_acquired_focus_stream_type(focus_type, stream_type, option, ext_info);
163         if (ret)
164                 debug_error("Could not get acquired focus stream type, ret[0x%x]", ret);
165
166         debug_fleave();
167
168         return ret;
169 }
170
171 EXPORT_API
172 int mm_sound_acquire_focus(int id, mm_sound_focus_type_e focus_type, const char *ext_info)
173 {
174         int ret = MM_ERROR_NONE;
175
176         debug_fenter();
177
178         RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
179
180         if (id < 0) {
181                 debug_error("argument is not valid");
182                 return MM_ERROR_INVALID_ARGUMENT;
183         }
184         if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
185                 debug_error("argument is not valid");
186                 return MM_ERROR_INVALID_ARGUMENT;
187         }
188
189         ret = mm_sound_client_acquire_focus(id, focus_type, 0, ext_info);
190         if (ret)
191                 debug_error("Could not acquire focus, ret[0x%x]", ret);
192
193         debug_fleave();
194
195         return ret;
196 }
197
198 EXPORT_API
199 int mm_sound_release_focus(int id, mm_sound_focus_type_e focus_type, const char *ext_info)
200 {
201         int ret = MM_ERROR_NONE;
202
203         debug_fenter();
204
205         RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
206
207         if (id < 0) {
208                 debug_error("argument is not valid");
209                 return MM_ERROR_INVALID_ARGUMENT;
210         }
211         if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
212                 debug_error("argument is not valid");
213                 return MM_ERROR_INVALID_ARGUMENT;
214         }
215
216         ret = mm_sound_client_release_focus(id, focus_type, 0, ext_info);
217         if (ret)
218                 debug_error("Could not release focus, ret[0x%x]", ret);
219
220         debug_fleave();
221
222         return ret;
223 }
224
225 EXPORT_API
226 int mm_sound_acquire_focus_with_option(int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info)
227 {
228         int ret = MM_ERROR_NONE;
229
230         debug_fenter();
231
232         if (id < 0) {
233                 debug_error("id is not valid");
234                 return MM_ERROR_INVALID_ARGUMENT;
235         }
236
237         if (option < 0) {
238                 debug_error("option is not valid");
239                 return MM_ERROR_INVALID_ARGUMENT;
240         }
241
242         if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
243                 debug_error("focus type is not valid");
244                 return MM_ERROR_INVALID_ARGUMENT;
245         }
246
247         ret = mm_sound_client_acquire_focus(id, focus_type, option, ext_info);
248         if (ret)
249                 debug_error("Could not acquire focus, ret[0x%x]", ret);
250
251         debug_fleave();
252
253         return ret;
254 }
255
256 EXPORT_API
257 int mm_sound_release_focus_with_option(int id, mm_sound_focus_type_e focus_type, int option, const char *ext_info)
258 {
259         int ret = MM_ERROR_NONE;
260
261         debug_fenter();
262
263         if (id < 0) {
264                 debug_error("id is not valid");
265                 return MM_ERROR_INVALID_ARGUMENT;
266         }
267
268         if (option < 0) {
269                 debug_error("option is not valid");
270                 return MM_ERROR_INVALID_ARGUMENT;
271         }
272
273         if (focus_type < FOCUS_FOR_PLAYBACK || focus_type > FOCUS_FOR_BOTH) {
274                 debug_error("focus type is not valid");
275                 return MM_ERROR_INVALID_ARGUMENT;
276         }
277
278         ret = mm_sound_client_release_focus(id, focus_type, option, ext_info);
279         if (ret)
280                 debug_error("Could not release focus, ret[0x%x]", ret);
281
282         debug_fleave();
283
284         return ret;
285 }
286
287 EXPORT_API
288 int mm_sound_update_focus_status(int id, unsigned int status)
289 {
290         int ret = MM_ERROR_NONE;
291
292         if ((ret = mm_sound_client_update_stream_focus_status(id, status)))
293                 debug_error("failed to mm_sound_client_update_stream_focus_status(), id(%d), status(%d, ret[0x%x]",
294                                         id, status, ret);
295
296         return ret;
297 }
298
299 EXPORT_API
300 int mm_sound_deliver_focus(int src_id, int dst_id, mm_sound_focus_type_e focus_type)
301 {
302         int ret = MM_ERROR_NONE;
303
304         if ((ret = mm_sound_client_deliver_focus(src_id, dst_id, focus_type)))
305                 debug_error("failed to mm_sound_client_deliver_focus(), ret[0x%x]", ret);
306
307         return ret;
308 }
309
310 EXPORT_API
311 int mm_sound_set_focus_watch_callback(mm_sound_focus_type_e focus_type, mm_sound_focus_changed_watch_cb callback, void *user_data, int *id)
312 {
313         int ret = MM_ERROR_NONE;
314
315         debug_fenter();
316
317         RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
318
319         if (callback == NULL || id == NULL) {
320                 debug_error("argument is not valid");
321                 return MM_ERROR_INVALID_ARGUMENT;
322         }
323         ret = mm_sound_client_set_focus_watch_callback(getpid(), focus_type, callback, user_data, id);
324         if (ret)
325                 debug_error("Could not set focus watch callback, ret[0x%x]", ret);
326
327         debug_fleave();
328
329         return ret;
330 }
331
332 EXPORT_API
333 int mm_sound_unset_focus_watch_callback(int id)
334 {
335         int ret = MM_ERROR_NONE;
336         bool result = false;
337
338         debug_fenter();
339
340         if (id < 0) {
341                 debug_error("argument is not valid");
342                 return MM_ERROR_INVALID_ARGUMENT;
343         }
344
345         if ((ret = mm_sound_client_request_unset_focus_watch_callback(id))) {
346                 debug_error("failed to mm_sound_client_request_unset_focus_watch_callback, ret[0x%x]", ret);
347                 return ret;
348         }
349
350         mm_sound_client_is_focus_cb_thread(g_thread_self(), &result);
351         if (!result) {
352                 if ((ret = mm_sound_client_unset_focus_watch_callback(id)))
353                         debug_error("Could not unset focus watch callback, id(%d), ret[0x%x]", id, ret);
354         } else {
355                 ret = mm_sound_client_execute_focus_func_in_main_context(IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB, id);
356                 debug_msg("mm_sound_client_execute_focus_func_in_main_context() is called, id(%d), ret[0x%x]", id, ret);
357         }
358
359         debug_fleave();
360
361         return ret;
362 }