From 315e304ab174881c65eff7962accf04da80ddb48 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Tue, 14 Jun 2016 16:13:50 +0900 Subject: [PATCH 01/16] stream-manager: Fix memory leak Fix code to free a hashmap for stream parentes in subscribe_cb(). [Version] 5.0.57 [Profile] Common [Issue Type] Bug fix Change-Id: If1c282c36c577db26383923a79a2216c6f424303 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager.c | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 32abcab..098a6e7 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.56 +Version: 5.0.57 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager.c b/src/stream-manager.c index f460560..829cdca 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -3435,17 +3435,16 @@ static void subscribe_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t pa_log_info("subscribe_cb() is called, t(%x), idx(%u)", t, idx); - if ((client = pa_idxset_get_by_index(core->clients, idx)) == NULL) { - pa_log_error(" - could not find any client that has idx(%u)", idx); - return; - } - name = pa_proplist_gets(client->proplist, PA_PROP_APPLICATION_NAME); - if (!name || (name && !pa_streq(name, STREAM_MANAGER_CLIENT_NAME))) { - pa_log_warn(" - this is not a client(%s) that we should take care of, skip it", name); - return; - } - if (t == (PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE)) { + if ((client = pa_idxset_get_by_index(core->clients, idx)) == NULL) { + pa_log_error(" - could not find any client that has idx(%u)", idx); + return; + } + name = pa_proplist_gets(client->proplist, PA_PROP_APPLICATION_NAME); + if (!name || (name && !pa_streq(name, STREAM_MANAGER_CLIENT_NAME))) { + pa_log_warn(" - this is not a client(%s) that we should take care of, skip it", name); + return; + } /* add a stream parent */ sp = pa_xmalloc0(sizeof(stream_parent)); sp->idx_sink_inputs = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); @@ -3455,7 +3454,7 @@ static void subscribe_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t pa_hashmap_put(m->stream_parents, (void*)idx, sp); pa_log_debug(" - add sp(%p), idx(%u)", sp, idx); - } else if (t == (PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE)) { + } else if (t == (PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE)) { /* remove the stream parent */ sp = pa_hashmap_get(m->stream_parents, (const void*)idx); if (sp) { -- 2.7.4 From b1acdaaa97ce604fe1880bc13f1a7a21242ad7fb Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Thu, 16 Jun 2016 16:39:40 +0900 Subject: [PATCH 02/16] Add license boilerplate [Version] 5.0.58 [Profile] Common [Issue Type] License boilerplate Change-Id: Ia0f45ffc4a161326bf3e28d62ec96e41613fc7a1 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/communicator.h | 22 ++++++++++++++++++++++ src/device-manager.c | 20 ++++++++++++++++++++ src/device-manager.h | 20 ++++++++++++++++++++ src/hal-interface.h | 22 ++++++++++++++++++++++ src/module-tizenaudio-policy.c | 21 +++++++++++++++++++++ src/stream-manager-priv.h | 21 +++++++++++++++++++++ src/stream-manager-restriction-priv.h | 21 +++++++++++++++++++++ src/stream-manager-volume-priv.h | 21 +++++++++++++++++++++ src/stream-manager-volume.h | 21 +++++++++++++++++++++ src/stream-manager.c | 2 +- src/stream-manager.h | 22 ++++++++++++++++++++++ src/subscribe-observer.c | 21 +++++++++++++++++++++ src/subscribe-observer.h | 21 +++++++++++++++++++++ 14 files changed, 255 insertions(+), 2 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 098a6e7..10cc12f 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.57 +Version: 5.0.58 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/communicator.h b/src/communicator.h index 3fb2f30..8f75be8 100644 --- a/src/communicator.h +++ b/src/communicator.h @@ -1,5 +1,27 @@ +/*** + This file is part of PulseAudio. + + Copyright 2015-2016 Sangchul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + #ifndef foocommunicatorfoo #define foocommunicatorfoo + #include typedef enum pa_communicator_hook { diff --git a/src/device-manager.c b/src/device-manager.c index c98d106..243aabf 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -1,3 +1,23 @@ +/*** + This file is part of PulseAudio. + + Copyright 2015-2016 Jeonho Mok + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ #ifdef HAVE_CONFIG_H #include diff --git a/src/device-manager.h b/src/device-manager.h index 146ae33..fbf9a9e 100644 --- a/src/device-manager.h +++ b/src/device-manager.h @@ -1,3 +1,23 @@ +/*** + This file is part of PulseAudio. + + Copyright 2015-2016 Jeonho Mok + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ #include diff --git a/src/hal-interface.h b/src/hal-interface.h index 9741339..faebb03 100644 --- a/src/hal-interface.h +++ b/src/hal-interface.h @@ -1,5 +1,27 @@ +/*** + This file is part of PulseAudio. + + Copyright 2015-2016 Sangchul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + #ifndef foohalinterfacefoo #define foohalinterfacefoo + #include #include diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index c03fa9e..b9022e2 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -1,3 +1,24 @@ +/*** + This file is part of PulseAudio. + + Copyright 2013-2016 Seungbae Shin, Sangchul Lee, Jeongho Mok + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + #ifdef HAVE_CONFIG_H #include #endif diff --git a/src/stream-manager-priv.h b/src/stream-manager-priv.h index b20e8d1..e595d77 100644 --- a/src/stream-manager-priv.h +++ b/src/stream-manager-priv.h @@ -1,3 +1,24 @@ +/*** + This file is part of PulseAudio. + + Copyright 2015-2016 Sangchul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + #ifndef foostreammanagerprivfoo #define foostreammanagerprivfoo diff --git a/src/stream-manager-restriction-priv.h b/src/stream-manager-restriction-priv.h index dcc5ce8..bc1906d 100644 --- a/src/stream-manager-restriction-priv.h +++ b/src/stream-manager-restriction-priv.h @@ -1,3 +1,24 @@ +/*** + This file is part of PulseAudio. + + Copyright 2016 Sangchul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + #ifndef foostreammanagerrestrictionprivfoo #define foostreammanagerrestrictionprivfoo diff --git a/src/stream-manager-volume-priv.h b/src/stream-manager-volume-priv.h index e727137..4287ec7 100644 --- a/src/stream-manager-volume-priv.h +++ b/src/stream-manager-volume-priv.h @@ -1,3 +1,24 @@ +/*** + This file is part of PulseAudio. + + Copyright 2015 Sangchul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + #ifndef foostreammanagervolumeprivfoo #define foostreammanagervolumeprivfoo diff --git a/src/stream-manager-volume.h b/src/stream-manager-volume.h index dbc0f40..960158f 100644 --- a/src/stream-manager-volume.h +++ b/src/stream-manager-volume.h @@ -1,3 +1,24 @@ +/*** + This file is part of PulseAudio. + + Copyright 2015 Sangchul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + #ifndef foostreammanagervolumefoo #define foostreammanagervolumefoo diff --git a/src/stream-manager.c b/src/stream-manager.c index 829cdca..1fa9adc 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -1,7 +1,7 @@ /*** This file is part of PulseAudio. - Copyright 2015 Sangchul Lee + Copyright 2015-2016 Sangchul Lee PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published diff --git a/src/stream-manager.h b/src/stream-manager.h index f0f855c..2e50746 100644 --- a/src/stream-manager.h +++ b/src/stream-manager.h @@ -1,5 +1,27 @@ +/*** + This file is part of PulseAudio. + + Copyright 2015-2016 Sangchul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + #ifndef foostreammanagerfoo #define foostreammanagerfoo + #include #define IS_ROUTE_TYPE_FOR_EXTERNAL_DEV(route_type_str, route_type) \ diff --git a/src/subscribe-observer.c b/src/subscribe-observer.c index 03d76a6..21a6576 100644 --- a/src/subscribe-observer.c +++ b/src/subscribe-observer.c @@ -1,3 +1,24 @@ +/*** + This file is part of PulseAudio. + + Copyright 2016 Jeonho Mok + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + #ifdef HAVE_CONFIG_H #include #endif diff --git a/src/subscribe-observer.h b/src/subscribe-observer.h index 62431ac..4102e3a 100644 --- a/src/subscribe-observer.h +++ b/src/subscribe-observer.h @@ -1,3 +1,24 @@ +/*** + This file is part of PulseAudio. + + Copyright 2016 Jeonho Mok + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + #ifndef foosubscribeobserverfoo #define foosubscribeobserverfoo -- 2.7.4 From ee344e31da6d7e5894bc22a420168ddcd2b7c92a Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Wed, 22 Jun 2016 15:17:11 +0900 Subject: [PATCH 03/16] tizenaudio-policy: Fix codes to select source properly in case of loading module-loopback [Version] 5.0.59 [Profile] Common [Issue Type] Bug fix Change-Id: I8d39cefbd66eaf363553da9534ffe1188d79e1ca Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-tizenaudio-policy.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 10cc12f..0e9b806 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.58 +Version: 5.0.59 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index b9022e2..a095937 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -909,9 +909,9 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ } /* Check for in/out devices in case of loopback */ if (pa_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) { - if (dm_device_direction & DM_DEVICE_DIRECTION_OUT) + if ((data->stream_type == STREAM_SINK_INPUT) && (dm_device_direction & DM_DEVICE_DIRECTION_OUT)) u->loopback_args.sink = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); - else if (dm_device_direction & DM_DEVICE_DIRECTION_IN) + else if ((data->stream_type == STREAM_SOURCE_OUTPUT) && (dm_device_direction & DM_DEVICE_DIRECTION_IN)) u->loopback_args.source = pa_device_manager_get_source(device, DEVICE_ROLE_NORMAL); } -- 2.7.4 From e99a5601fac705da4722c1b5b31f5506235407ee Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Wed, 29 Jun 2016 15:28:56 +0900 Subject: [PATCH 04/16] hal-interface: Use /usr/include/tizen-audio.h instead of local tizen-audio.h removed src/tizen-audio.h file. [Version] 5.0.60 [Profile] Common [Issue Type] Clean-up Change-Id: I5bbbb5c9855e38395bb235a6deccbe2965b834ef Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 3 +- src/hal-interface.c | 2 +- src/tizen-audio.h | 139 -------------------------------- 3 files changed, 3 insertions(+), 141 deletions(-) delete mode 100644 src/tizen-audio.h diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 0e9b806..89aa328 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.59 +Version: 5.0.60 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ @@ -12,6 +12,7 @@ BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(iniparser) BuildRequires: pkgconfig(json-c) BuildRequires: pkgconfig(vconf) +BuildRequires: mm-hal-interface BuildRequires: pkgconfig(libpulse) BuildRequires: pkgconfig(pulsecore) BuildRequires: pulseaudio diff --git a/src/hal-interface.c b/src/hal-interface.c index 658a78d..f7ef786 100644 --- a/src/hal-interface.c +++ b/src/hal-interface.c @@ -24,7 +24,7 @@ #endif #include "hal-interface.h" -#include "tizen-audio.h" +#include #include #define SHARED_HAL_INTF "tizen-hal-interface" diff --git a/src/tizen-audio.h b/src/tizen-audio.h deleted file mode 100644 index 6c52e71..0000000 --- a/src/tizen-audio.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef foopulsetizenaudiofoo -#define foopulsetizenaudiofoo - -/*** - This file is part of PulseAudio. - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include - -/* Error code */ -#define AUDIO_IS_ERROR(ret) (ret < 0) -typedef enum audio_return { - AUDIO_RET_OK = 0, - AUDIO_ERR_UNDEFINED = (int32_t)0x80001000, - AUDIO_ERR_RESOURCE = (int32_t)0x80001001, - AUDIO_ERR_PARAMETER = (int32_t)0x80001002, - AUDIO_ERR_IOCTL = (int32_t)0x80001003, - AUDIO_ERR_INVALID_STATE = (int32_t)0x80001004, - AUDIO_ERR_INTERNAL = (int32_t)0x80001005, - - AUDIO_ERR_NOT_IMPLEMENTED = (int32_t)0x80001100, -} audio_return_t ; - -typedef enum audio_direction { - AUDIO_DIRECTION_IN, /**< Capture */ - AUDIO_DIRECTION_OUT, /**< Playback */ -} audio_direction_t; - -typedef struct device_info { - const char *type; - uint32_t direction; - uint32_t id; -} device_info_t; - -typedef struct audio_volume_info { - const char *type; - const char *gain; - uint32_t direction; -} audio_volume_info_t ; - -typedef struct audio_route_info { - const char *role; - device_info_t *device_infos; - uint32_t num_of_devices; -} audio_route_info_t; - -typedef struct audio_route_option { - const char *role; - const char *name; - int32_t value; -} audio_route_option_t; - -typedef struct audio_stream_info { - const char *role; - uint32_t direction; - uint32_t idx; -} audio_stream_info_t ; - -typedef void (*message_cb)(const char *name, int value, void *user_data); - -/* Overall */ -typedef struct audio_interface { - /* Initialization & de-initialization */ - audio_return_t (*init)(void **audio_handle); - audio_return_t (*deinit)(void *audio_handle); - /* Volume */ - audio_return_t (*get_volume_level_max)(void *audio_handle, audio_volume_info_t *info, uint32_t *level); - audio_return_t (*get_volume_level)(void *audio_handle, audio_volume_info_t *info, uint32_t *level); - audio_return_t (*set_volume_level)(void *audio_handle, audio_volume_info_t *info, uint32_t level); - audio_return_t (*get_volume_value)(void *audio_handle, audio_volume_info_t *info, uint32_t level, double *value); - audio_return_t (*get_volume_mute)(void *audio_handle, audio_volume_info_t *info, uint32_t *mute); - audio_return_t (*set_volume_mute)(void *audio_handle, audio_volume_info_t *info, uint32_t mute); - /* Routing */ - audio_return_t (*update_route)(void *audio_handle, audio_route_info_t *info); - audio_return_t (*update_route_option)(void *audio_handle, audio_route_option_t *option); - /* Stream */ - audio_return_t (*notify_stream_connection_changed)(void *audio_handle, audio_stream_info_t *info, uint32_t is_connected); - /* Buffer attribute */ - audio_return_t (*get_buffer_attr)(void *audio_handle, uint32_t direction, const char *latency, uint32_t samplerate, int format, uint32_t channels, - uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize); - /* PCM device */ - audio_return_t (*pcm_open)(void *audio_handle, void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods); - audio_return_t (*pcm_start)(void *audio_handle, void *pcm_handle); - audio_return_t (*pcm_stop)(void *audio_handle, void *pcm_handle); - audio_return_t (*pcm_close)(void *audio_handle, void *pcm_handle); - audio_return_t (*pcm_avail)(void *audio_handle, void *pcm_handle, uint32_t *avail); - audio_return_t (*pcm_write)(void *audio_handle, void *pcm_handle, const void *buffer, uint32_t frames); - audio_return_t (*pcm_read)(void *audio_handle, void *pcm_handle, void *buffer, uint32_t frames); - audio_return_t (*pcm_get_fd)(void *audio_handle, void *pcm_handle, int *fd); - audio_return_t (*pcm_recover)(void *audio_handle, void *pcm_handle, int revents); - audio_return_t (*pcm_get_params)(void *audio_handle, void *pcm_handle, uint32_t direction, void **sample_spec, uint32_t *period_size, uint32_t *periods); - audio_return_t (*pcm_set_params)(void *audio_handle, void *pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods); - /* Message callback (optional) */ - audio_return_t (*add_message_cb)(void *audio_handle, message_cb callback, void *user_data); - audio_return_t (*remove_message_cb)(void *audio_handle, message_cb callback); -} audio_interface_t; - -audio_return_t audio_init(void **audio_handle); -audio_return_t audio_deinit(void *audio_handle); -audio_return_t audio_get_volume_level_max(void *audio_handle, audio_volume_info_t *info, uint32_t *level); -audio_return_t audio_get_volume_level(void *audio_handle, audio_volume_info_t *info, uint32_t *level); -audio_return_t audio_set_volume_level(void *audio_handle, audio_volume_info_t *info, uint32_t level); -audio_return_t audio_get_volume_value(void *audio_handle, audio_volume_info_t *info, uint32_t level, double *value); -audio_return_t audio_get_volume_mute(void *audio_handle, audio_volume_info_t *info, uint32_t *mute); -audio_return_t audio_set_volume_mute(void *audio_handle, audio_volume_info_t *info, uint32_t mute); -audio_return_t audio_update_route(void *audio_handle, audio_route_info_t *info); -audio_return_t audio_update_route_option(void *audio_handle, audio_route_option_t *option); -audio_return_t audio_notify_stream_connection_changed(void *audio_handle, audio_stream_info_t *info, uint32_t is_connected); -audio_return_t audio_get_buffer_attr(void *audio_handle, uint32_t direction, const char *latency, uint32_t samplerate, int format, uint32_t channels, - uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize); -audio_return_t audio_pcm_open(void *audio_handle, void **pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods); -audio_return_t audio_pcm_start(void *audio_handle, void *pcm_handle); -audio_return_t audio_pcm_stop(void *audio_handle, void *pcm_handle); -audio_return_t audio_pcm_close(void *audio_handle, void *pcm_handle); -audio_return_t audio_pcm_avail(void *audio_handle, void *pcm_handle, uint32_t *avail); -audio_return_t audio_pcm_write(void *audio_handle, void *pcm_handle, const void *buffer, uint32_t frames); -audio_return_t audio_pcm_read(void *audio_handle, void *pcm_handle, void *buffer, uint32_t frames); -audio_return_t audio_pcm_get_fd(void *audio_handle, void *pcm_handle, int *fd); -audio_return_t audio_pcm_recover(void *audio_handle, void *pcm_handle, int revents); -audio_return_t audio_pcm_get_params(void *audio_handle, void *pcm_handle, uint32_t direction, void **sample_spec, uint32_t *period_size, uint32_t *periods); -audio_return_t audio_pcm_set_params(void *audio_handle, void *pcm_handle, uint32_t direction, void *sample_spec, uint32_t period_size, uint32_t periods); -audio_return_t audio_add_message_cb(void *audio_handle, message_cb callback, void *user_data); -audio_return_t audio_remove_message_cb(void *audio_handle, message_cb callback); -#endif -- 2.7.4 From f4508c51fc6256542a913426b1c7accec778bfb7 Mon Sep 17 00:00:00 2001 From: KimJeongYeon Date: Tue, 5 Jul 2016 10:47:50 +0900 Subject: [PATCH 05/16] tizenaudio-sink/source: Fix crash when access pcm handle build_pollfd() trying to access u->pcm_handle at sink_process_msg() at module loading step. But, sometimes the device wasn't open yet. (e.g factory reset, power on, ...) Therefore, null access to u->pcm_handle causes crash. I think device need to be opened prior to starting sink's message handler. [Version] 5.0.61 [Profile] Common [Issue Type] Bug fix Signed-off-by: KimJeongYeon Change-Id: I060319c261176bb46f7b1c0804322d4d8c491071 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-tizenaudio-sink.c | 12 ++++++++++-- src/module-tizenaudio-source.c | 12 ++++++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 89aa328..b88166c 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.60 +Version: 5.0.61 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-sink.c b/src/module-tizenaudio-sink.c index 095f6de..60105d1 100644 --- a/src/module-tizenaudio-sink.c +++ b/src/module-tizenaudio-sink.c @@ -517,11 +517,19 @@ int pa__init(pa_module*m) { u->sink->update_requested_latency = sink_update_requested_latency_cb; u->sink->userdata = u; + if (pa_hal_interface_pcm_open(u->hal_interface, + (void **)&u->pcm_handle, + DIRECTION_OUT, + &u->sink->sample_spec, + u->frag_size / pa_frame_size(&u->sink->sample_spec), + u->nfrags)) { + pa_log_error("Error opening PCM device"); + goto fail; + } + pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_rtpoll(u->sink, u->rtpoll); - unsuspend(u); - u->block_usec = BLOCK_USEC; u->timestamp = 0ULL; u->timestamp_written = 0ULL; diff --git a/src/module-tizenaudio-source.c b/src/module-tizenaudio-source.c index d96adb4..79a4664 100644 --- a/src/module-tizenaudio-source.c +++ b/src/module-tizenaudio-source.c @@ -468,11 +468,19 @@ int pa__init(pa_module*m) { u->source->update_requested_latency = source_update_requested_latency_cb; u->source->userdata = u; + if (pa_hal_interface_pcm_open(u->hal_interface, + (void **)&u->pcm_handle, + DIRECTION_IN, + &u->source->sample_spec, + u->frag_size / pa_frame_size(&u->source->sample_spec), + u->nfrags)) { + pa_log_error("Error opening PCM device"); + goto fail; + } + pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); pa_source_set_rtpoll(u->source, u->rtpoll); - unsuspend(u); - u->block_usec = BLOCK_USEC; u->latency_time = u->block_usec; u->timestamp = 0ULL; -- 2.7.4 From 6c4a9deaf48e577b27fc87c014d8353c4eb5c854 Mon Sep 17 00:00:00 2001 From: KimJeongYeon Date: Tue, 5 Jul 2016 18:10:13 +0900 Subject: [PATCH 06/16] tizenaudio-sink/source: Fix resource leak of pcm handle [Version] 5.0.62 [Profile] Common [Issue Type] Resource leak Signed-off-by: KimJeongYeon Change-Id: Ieab7b58bacf8e7d8707df20c11db60046d7587b6 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-tizenaudio-sink.c | 5 +++++ src/module-tizenaudio-source.c | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index b88166c..f38fd4d 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.61 +Version: 5.0.62 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-sink.c b/src/module-tizenaudio-sink.c index 60105d1..99ae7f6 100644 --- a/src/module-tizenaudio-sink.c +++ b/src/module-tizenaudio-sink.c @@ -589,5 +589,10 @@ void pa__done(pa_module*m) { if (u->rtpoll) pa_rtpoll_free(u->rtpoll); + if (u->pcm_handle) { + pa_hal_interface_pcm_stop(u->hal_interface, u->pcm_handle); + pa_hal_interface_pcm_close(u->hal_interface, u->pcm_handle); + } + pa_xfree(u); } diff --git a/src/module-tizenaudio-source.c b/src/module-tizenaudio-source.c index 79a4664..0578cc0 100644 --- a/src/module-tizenaudio-source.c +++ b/src/module-tizenaudio-source.c @@ -538,5 +538,10 @@ void pa__done(pa_module*m) { if (u->rtpoll) pa_rtpoll_free(u->rtpoll); + if (u->pcm_handle) { + pa_hal_interface_pcm_stop(u->hal_interface, u->pcm_handle); + pa_hal_interface_pcm_close(u->hal_interface, u->pcm_handle); + } + pa_xfree(u); } -- 2.7.4 From 167dca7eff9c66a9faf5f79f5b5f5949ce208e50 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Fri, 15 Jul 2016 12:18:06 +0900 Subject: [PATCH 07/16] Add module-tizenaudio-haltc for testing audio HAL [Version] 5.0.63 [Profile] Common [Issue Type] Feature enhancement Change-Id: I9ead5a70a1fb09630c0d0f02d24840f3ed71dca1 Signed-off-by: Sangchul Lee --- Makefile.am | 14 ++ configure.ac | 12 ++ packaging/pulseaudio-modules-tizen.spec | 3 +- src/module-tizenaudio-haltc.c | 263 ++++++++++++++++++++++++++++++++ 4 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 src/module-tizenaudio-haltc.c diff --git a/Makefile.am b/Makefile.am index e4992bd..bfb626c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -35,6 +35,10 @@ pulsemodlibexec_LTLIBRARIES = \ module-tizenaudio-source.la \ module-tizenaudio-policy.la \ module-sound-player.la +if ENABLE_HALTC +pulsemodlibexec_LTLIBRARIES += \ + module-tizenaudio-haltc.la +endif # These are generated by an M4 script SYMDEF_FILES = \ @@ -43,6 +47,10 @@ SYMDEF_FILES = \ module-tizenaudio-source-symdef.h \ module-tizenaudio-policy-symdef.h \ module-sound-player-symdef.h +if ENABLE_HALTC +SYMDEF_FILES += \ + module-tizenaudio-haltc-symdef.h +endif if HAVE_DBUS @@ -88,3 +96,9 @@ module_tizenaudio_policy_la_LDFLAGS = $(MODULE_LDFLAGS) $(PACORE_LDFLAGS) $(PA_L module_tizenaudio_policy_la_LIBADD = $(AM_LIBADD) $(PACORE_LIBS) $(PA_LIBS) $(DBUS_LIBS) $(VCONF_LIBS) $(INIPARSER_LIBS) $(LIBJSON_LIBS) libhal-interface.la module_tizenaudio_policy_la_CFLAGS = $(AM_CFLAGS) $(PACORE_CFLAGS) $(PA_CFLAGS) $(DBUS_CFLAGS) $(VCONF_CFLAGS) $(INIPARSER_CFLAGS) $(LIBJSON_CFLAGS) +if ENABLE_HALTC +module_tizenaudio_haltc_la_SOURCES = src/module-tizenaudio-haltc.c +module_tizenaudio_haltc_la_LDFLAGS = $(PACORE_LDFLAGS) $(PA_LDFLAGS) $(MODULE_LDFLAGS) +module_tizenaudio_haltc_la_LIBADD = $(PACORE_LIBS) $(PA_LIBS) $(MODULE_LIBADD) libhal-interface.la +module_tizenaudio_haltc_la_CFLAGS = $(PACORE_CFLAGS) $(PA_CFLAGS) $(AM_CFLAGS) +endif diff --git a/configure.ac b/configure.ac index d6b0aa4..98222a9 100644 --- a/configure.ac +++ b/configure.ac @@ -378,6 +378,18 @@ fi AM_CONDITIONAL(USE_DLOG, test "x$USE_DLOG" = "xyes") dnl end -------------------------------------------------------------------- +dnl use hal tc ------------------------------------------------------------ +AC_ARG_ENABLE(haltc, AC_HELP_STRING([--enable-haltc], [using haltc]), +[ + case "${enableval}" in + yes) ENABLE_HALTC=yes ;; + no) ENABLE_HALTC=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-haltc) ;; + esac + ],[USE_HALTC=no]) +AM_CONDITIONAL(ENABLE_HALTC, test "x$ENABLE_HALTC" = "xyes") +dnl end -------------------------------------------------------------------- + #### D-Bus support (optional) #### AC_ARG_ENABLE([dbus], diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index f38fd4d..16234be 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.62 +Version: 5.0.63 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ @@ -38,6 +38,7 @@ export LD_AS_NEEDED=0 %if %{with pulseaudio_dlog} --enable-dlog \ %endif +# --enable-haltc %__make %{?_smp_mflags} V=1 diff --git a/src/module-tizenaudio-haltc.c b/src/module-tizenaudio-haltc.c new file mode 100644 index 0000000..7b0d016 --- /dev/null +++ b/src/module-tizenaudio-haltc.c @@ -0,0 +1,263 @@ +/*** + This file is part of PulseAudio. + + Copyright 2016 Sangchul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "module-tizenaudio-haltc-symdef.h" +#include "hal-interface.h" + +PA_MODULE_AUTHOR("Sangchul Lee"); +PA_MODULE_DESCRIPTION("Tizen Audio HAL TC module"); +PA_MODULE_VERSION(PACKAGE_VERSION); +PA_MODULE_LOAD_ONCE(true); +PA_MODULE_USAGE(" "); + +struct userdata; + +struct userdata { + pa_core *core; + pa_hal_interface *hal_interface; +}; + +/* pointer to testcase functions */ +typedef int32_t (*tc_fun_ptr)(pa_hal_interface *h); + +/* struct describing specific testcase */ +typedef struct testcase_s { + const char* name; + tc_fun_ptr function; +} testcase; + + +static int32_t notify_stream_connection_changed_p(pa_hal_interface *h) +{ + int32_t ret = 0; + hal_stream_connection_info info; + + info.role = "media"; + info.direction = DIRECTION_OUT; + info.idx = 100; + info.is_connected = true; + + ret = pa_hal_interface_notify_stream_connection_changed(h, &info); + + return ret; +} + +static int32_t notify_stream_connection_changed_n(pa_hal_interface *h) +{ + int32_t ret = 0; + hal_stream_connection_info info; + + info.role = NULL; + info.direction = DIRECTION_OUT; + info.idx = 100; + info.is_connected = true; + + ret = pa_hal_interface_notify_stream_connection_changed(h, &info); + + return !ret; +} + +static int32_t update_route_p(pa_hal_interface *h) +{ + int32_t ret = 0; + hal_route_info info; + int32_t num_of_devices = 1; + + info.role = "media"; + info.device_infos = pa_xmalloc0(sizeof(hal_device_info) * num_of_devices); + info.device_infos[0].direction = DIRECTION_OUT; + info.device_infos[0].type = "builtin-speaker"; + info.device_infos[0].id = 100; + info.num_of_devices = num_of_devices; + + ret = pa_hal_interface_update_route(h, &info); + pa_xfree(info.device_infos); + + return ret; +} + +static int32_t update_route_n(pa_hal_interface *h) +{ + int32_t ret = 0; + hal_route_info info; + + info.role = NULL; + + ret = pa_hal_interface_update_route(h, &info); + + return !ret; +} + +static int32_t set_get_volume_level_p(pa_hal_interface *h) +{ + int32_t ret = 0; + uint32_t set_level = 10; + uint32_t get_level = 0; + const char *volume_type = "media"; + + if ((ret = pa_hal_interface_set_volume_level(h, volume_type, DIRECTION_OUT, set_level))) + return ret; + if ((ret = pa_hal_interface_get_volume_level(h, volume_type, DIRECTION_OUT, &get_level))) + return ret; + if (set_level != get_level) + return -1; + + return ret; +} + +static int32_t set_get_volume_level_n(pa_hal_interface *h) +{ + int32_t ret = 0; + uint32_t set_level = 20; + uint32_t get_level = 0; + const char *volume_type = "media"; + + if ((ret = pa_hal_interface_set_volume_level(h, volume_type, DIRECTION_OUT, set_level))) + return !ret; + if ((ret = pa_hal_interface_get_volume_level(h, volume_type, DIRECTION_OUT, &get_level))) + return !ret; + if (set_level != get_level) + return 0; + + return !ret; +} + +static int32_t pcm_open_close_p(pa_hal_interface *h) +{ + int32_t ret = 0; + pcm_handle pcm_h = NULL; + pa_sample_spec sample_spec; + uint32_t period_size = 0; + uint32_t periods = 0; + + sample_spec.format = PA_SAMPLE_S16LE; + sample_spec.rate = 44100; + sample_spec.channels = 2; + + periods = 5; + period_size = 6400 / pa_frame_size(&sample_spec); + + if ((ret = pa_hal_interface_pcm_open(h, &pcm_h, DIRECTION_OUT, &sample_spec, period_size, periods))) + return ret; + if ((ret = pa_hal_interface_pcm_close(h, pcm_h))) + return ret; + + return ret; +} + +static int32_t pcm_open_close_n(pa_hal_interface *h) +{ + int32_t ret = 0; + pcm_handle pcm_h = NULL; + pa_sample_spec sample_spec; + uint32_t period_size = 0; + uint32_t periods = 0; + + if ((ret = pa_hal_interface_pcm_open(h, &pcm_h, DIRECTION_OUT, &sample_spec, period_size, periods))) + return !ret; + if ((ret = pa_hal_interface_pcm_close(h, pcm_h))) + return !ret; + + return !ret; +} + + +testcase tc_array[] = { + {"notify_stream_connection_changed_p", notify_stream_connection_changed_p}, + {"notify_stream_connection_changed_n", notify_stream_connection_changed_n}, + {"update_route_p", update_route_p}, + {"update_route_n", update_route_n}, + {"set_get_volume_level_p", set_get_volume_level_p}, + {"set_get_volume_level_n", set_get_volume_level_n}, + {"pcm_open_close_p", pcm_open_close_p}, + {"pcm_open_close_n", pcm_open_close_n}, + {NULL, NULL} +}; + +static void run_test_cases(pa_hal_interface *h) +{ + int32_t i = 0; + int32_t success = 0; + int32_t result = 0; + + pa_log_info("[TizenAudioHAL_TC][START]===================================================="); + + for (i = 0; tc_array[i].name; i++) { + if (!(result = tc_array[i].function(h))) { + pa_log_info("[TizenAudioHAL_TC][SUCCESS][%s]", tc_array[i].name); + success++; + } else + pa_log_error("[TizenAudioHAL_TC][FAILURE][%s][Error:%x]", tc_array[i].name, result); + } + + pa_log_info("[TizenAudioHAL_TC][END][%d/%d] SUCCESS ======================================", success, i); + + return; +} + +int pa__init(pa_module *m) +{ + struct userdata *u; + + pa_assert(m); + + m->userdata = u = pa_xnew0(struct userdata, 1); + u->core = m->core; + + if (!(u->hal_interface = pa_hal_interface_get(u->core))) { + pa_log_error("Failed to get hal interface"); + goto fail; + } + + pa_log_info("Tizen Audio HAL TC module is loaded\n"); + + /* run TC */ + run_test_cases(u->hal_interface); + + return 0; + +fail: + pa__done(m); + + return -1; +} + +void pa__done(pa_module *m) +{ + struct userdata* u; + + pa_assert(m); + + if (!(u = m->userdata)) + return; + + if (u->hal_interface) + pa_hal_interface_unref(u->hal_interface); + + pa_xfree(u); + + pa_log_info("Tizen Audio HAL TC module is unloaded\n"); +} -- 2.7.4 From 44431f2ffeb7c05ad4c62c3ed77afa8e867c6003 Mon Sep 17 00:00:00 2001 From: Mok Jeongho Date: Tue, 26 Jul 2016 16:23:18 +0900 Subject: [PATCH 08/16] Use udev.id as a name of USB device [Version] 5.0.64 [Profile] Common [Issue Type] Feature enhancement Change-Id: I1194c4cd7f553934f4d82421b4bb8d971110093a --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 16234be..ea0e369 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.63 +Version: 5.0.64 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager.c b/src/device-manager.c index 243aabf..83b2b1e 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -1795,7 +1795,7 @@ static int pulse_device_get_device_type(void *pulse_device, pa_device_type_t pdt if (pulse_device_is_usb(prop)) { *device_type = DEVICE_TYPE_USB_AUDIO; *device_profile = NULL; - *device_name = pa_proplist_gets(prop, PA_PROP_DEVICE_SERIAL); + *device_name = pa_proplist_gets(prop, "udev.id"); } else { pa_log_warn("This is alsa device, but not usb. really unknown device"); return -1; -- 2.7.4 From 04a25a6c0263499af2d410109388f22caa603200 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Tue, 9 Aug 2016 12:03:31 +0900 Subject: [PATCH 09/16] sound-player, tizen-audio-policy, stream-manager: Adjust log level [Version] 5.0.65 [Profile] Common [Issue Type] Log Change-Id: I35d7b45d64c468f6fb5906334bb901c970cb90f8 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-sound-player.c | 8 ++++---- src/module-tizenaudio-policy.c | 8 ++++---- src/stream-manager.c | 29 +++++++++++++++-------------- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index ea0e369..abe407f 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.64 +Version: 5.0.65 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-sound-player.c b/src/module-sound-player.c index b8949c2..fb9660a 100644 --- a/src/module-sound-player.c +++ b/src/module-sound-player.c @@ -403,7 +403,7 @@ static void send_signal_for_eos(struct userdata *u, int32_t stream_idx) { pa_assert(u); - pa_log_debug("Send EOS signal for stream_idx(%d)", stream_idx); + pa_log_info("Send EOS signal for stream_idx(%d)", stream_idx); pa_assert_se(signal_msg = dbus_message_new_signal(SOUND_PLAYER_OBJECT_PATH, SOUND_PLAYER_INTERFACE, SOUND_PLAYER_SIGNAL_EOS)); pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_INT32, &stream_idx, DBUS_TYPE_INVALID)); @@ -425,7 +425,7 @@ static int init_ipc(struct userdata *u) { #endif pa_assert(u); - pa_log_info("Initialization for IPC"); + pa_log_debug("Initialization for IPC"); pre_mask = umask(0); if (mknod(KEYTONE_PATH, S_IFIFO|0660, 0) < 0) @@ -467,7 +467,7 @@ static int init_ipc(struct userdata *u) { pa_log_error("Unable to contact D-Bus system bus: %s: %s", err.name, err.message); goto fail; } else - pa_log_notice("Got dbus connection"); + pa_log_debug("Got dbus connection"); u->dbus_conn = conn; pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(conn), SOUND_PLAYER_OBJECT_PATH, &vtable, u)); @@ -559,7 +559,7 @@ static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, st pa_core_assert_ref(core); pa_sink_input_assert_ref(i); - pa_log_info("start sink_input_unlink_cb, i(%p, index:%u)", i, i->index); + pa_log_debug("start sink_input_unlink_cb, i(%p, index:%u)", i, i->index); #ifdef HAVE_DBUS PA_IDXSET_FOREACH(stream_idx, u->stream_idxs, idx) { diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index a095937..6db0eb0 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -272,7 +272,7 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre conn_devices = pa_device_manager_get_device_list(u->device_manager); if (data->route_type == STREAM_ROUTE_TYPE_AUTO || data->route_type == STREAM_ROUTE_TYPE_AUTO_ALL) { PA_IDXSET_FOREACH(device_type, data->idx_avail_devices, idx) { - pa_log_info("[SELECT][AUTO(_ALL)] avail_device[%u] for this role[%-16s]: type[%-16s]", idx, data->stream_role, device_type); + pa_log_debug("[SELECT][AUTO(_ALL)] avail_device[%u] for this role[%-16s]: type[%-16s]", idx, data->stream_role, device_type); if (cached_connected_devices[convert_device_type_str(device_type)][CONVERT_TO_DEVICE_DIRECTION(data->stream_type)-1] == 0) continue; PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { @@ -301,7 +301,7 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre } } else if (data->route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) { PA_IDXSET_FOREACH(device_type, data->idx_avail_devices, idx) { - pa_log_info("[SELECT][AUTO_LAST_CONN] avail_device[%u] for this role[%-16s]: type[%-16s]", idx, data->stream_role, device_type); + pa_log_debug("[SELECT][AUTO_LAST_CONN] avail_device[%u] for this role[%-16s]: type[%-16s]", idx, data->stream_role, device_type); if (cached_connected_devices[convert_device_type_str(device_type)][CONVERT_TO_DEVICE_DIRECTION(data->stream_type)-1] == 0) continue; PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { @@ -658,7 +658,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ conn_devices = pa_device_manager_get_device_list(u->device_manager); if (data->route_type == STREAM_ROUTE_TYPE_AUTO || data->route_type == STREAM_ROUTE_TYPE_AUTO_ALL) { PA_IDXSET_FOREACH(device_type, data->idx_avail_devices, idx) { - pa_log_info("[ROUTE][AUTO(_ALL)] avail_device[%u] for this role[%-16s]: type[%-16s]", idx, route_info.role, device_type); + pa_log_debug("[ROUTE][AUTO(_ALL)] avail_device[%u] for this role[%-16s]: type[%-16s]", idx, route_info.role, device_type); if (cached_connected_devices[convert_device_type_str(device_type)][CONVERT_TO_DEVICE_DIRECTION(data->stream_type)-1] == 0) continue; PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { @@ -794,7 +794,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ } } else if (data->route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) { PA_IDXSET_FOREACH(device_type, data->idx_avail_devices, idx) { - pa_log_info("[ROUTE][AUTO_LAST_CONN] avail_device[%u] for this role[%-16s]: type[%-16s]", idx, data->stream_role, device_type); + pa_log_debug("[ROUTE][AUTO_LAST_CONN] avail_device[%u] for this role[%-16s]: type[%-16s]", idx, data->stream_role, device_type); if (cached_connected_devices[convert_device_type_str(device_type)][CONVERT_TO_DEVICE_DIRECTION(data->stream_type)-1] == 0) continue; PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { diff --git a/src/stream-manager.c b/src/stream-manager.c index 1fa9adc..c591342 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -1693,7 +1693,7 @@ static bool check_role_to_skip(pa_stream_manager *m, const char *role) { if ((s = pa_hashmap_get(m->stream_infos, role))) ret = false; - pa_log_info("role is [%s], skip(%d)", role, ret); + pa_log_debug("role is [%s], skip(%d)", role, ret); return ret; } @@ -1902,7 +1902,7 @@ static bool update_the_highest_priority_stream(pa_stream_manager *m, process_com cur_max_stream = m->cur_highest_priority.source_output; } - pa_log_info("update_the_highest_priority_stream(), stream_type(%d), role(%s), command(%d), is_new_data(%d)", + pa_log_debug("update_the_highest_priority_stream(), stream_type(%d), role(%s), command(%d), is_new_data(%d)", type, role, command, is_new_data); if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED) { /* get focus status, route type */ @@ -2185,7 +2185,7 @@ static void fill_device_info_to_hook_data(pa_stream_manager *m, void *hook_data, else pa_log_warn(" -- failed to get the stream parent of idx(%u)", parent_idx); } else - pa_log_warn(" -- could not get the parent id of this stream, but keep going..."); + pa_log_debug(" -- could not get the parent id of this stream, but keep going..."); } } else pa_log_error(" -- could not find (%s)", route_data->stream_role); @@ -2341,7 +2341,7 @@ static void do_notify(pa_stream_manager *m, notify_command_type_t command, strea ((pa_source_output*)s)->source->outputs; fill_device_info_to_hook_data(m, &hook_call_route_data, command, type, s, is_new_data); } else { - pa_log_info("no stream for this type(%d), need to unset route", type); + pa_log_debug("no stream for this type(%d), need to unset route", type); hook_call_route_data.stream = NULL; hook_call_route_data.stream_type = type; } @@ -2425,13 +2425,13 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream if ((ch_str = pa_proplist_gets(req_format->plist, PA_PROP_FORMAT_CHANNELS))) ((pa_sink_input_new_data*)stream)->sample_spec.channels = atoi(ch_str); - pa_log_info("req rate(%s), req ch(%s), req format(%s)", rate_str, ch_str, format_str); + pa_log_debug("req rate(%s), req ch(%s), req format(%s)", rate_str, ch_str, format_str); /* set channel map if it is not set by client */ if (!((pa_sink_input_new_data*)stream)->channel_map_is_set) { pa_channel_map_init_auto(&(((pa_sink_input_new_data*)stream)->channel_map), ((pa_sink_input_new_data*)stream)->sample_spec.channels, PA_CHANNEL_MAP_ALSA); - pa_log_info("set default channel_map: channels(%u)", ((pa_sink_input_new_data*)stream)->channel_map.channels); + pa_log_debug("set default channel_map: channels(%u)", ((pa_sink_input_new_data*)stream)->channel_map.channels); ((pa_sink_input_new_data*)stream)->channel_map_is_set = true; } } @@ -2695,7 +2695,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream } FAILURE: - pa_log_info("<<< process_stream(%s): result(%d), stream(%p)", process_command_type_str[command], result, stream); + pa_log_debug("<<< process_stream(%s): result(%d), stream(%p)", process_command_type_str[command], result, stream); return result; } @@ -2719,7 +2719,7 @@ static void remove_sink_input_from_muted_streams(pa_stream_manager *m, pa_sink_i static pa_hook_result_t sink_input_new_cb(pa_core *core, pa_sink_input_new_data *new_data, pa_stream_manager *m) { pa_core_assert_ref(core); - pa_log_info("start sink_input_new_cb"); + pa_log_debug("start sink_input_new_cb"); process_stream(m, new_data, STREAM_SINK_INPUT, PROCESS_COMMAND_PREPARE, true); process_stream(m, new_data, STREAM_SINK_INPUT, PROCESS_COMMAND_UPDATE_BUFFER_ATTR, true); @@ -2733,7 +2733,7 @@ static pa_hook_result_t sink_input_put_cb(pa_core *core, pa_sink_input *i, pa_st pa_core_assert_ref(core); pa_sink_input_assert_ref(i); - pa_log_info("start sink_input_put_cb, i(%p, index:%u)", i, i->index); + pa_log_debug("start sink_input_put_cb, i(%p, index:%u)", i, i->index); process_stream(m, i, STREAM_SINK_INPUT, PROCESS_COMMAND_ADD_PARENT_ID, false); @@ -2744,7 +2744,8 @@ static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, pa pa_core_assert_ref(core); pa_sink_input_assert_ref(i); - pa_log_info("start sink_input_unlink_cb, i(%p, index:%u)", i, i->index); + pa_log_debug("start sink_input_unlink_cb, i(%p, index:%u)", i, i->index); + remove_sink_input_from_muted_streams(m, i); process_stream(m, i, STREAM_SINK_INPUT, PROCESS_COMMAND_REMOVE_PARENT_ID, false); process_stream(m, i, STREAM_SINK_INPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false); @@ -2759,7 +2760,7 @@ static pa_hook_result_t sink_input_state_changed_cb(pa_core *core, pa_sink_input pa_assert(m); state = pa_sink_input_get_state(i); - pa_log_info("start sink_input_state_changed_cb(), sink-input(%p), state(%d)", i, state); + pa_log_debug("start sink_input_state_changed_cb(), sink-input(%p), state(%d)", i, state); switch (state) { case PA_SINK_INPUT_CORKED: { @@ -3102,7 +3103,7 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro device_type = pa_device_manager_get_device_type(device); if (stream_route_type == STREAM_ROUTE_TYPE_AUTO || stream_route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) { - pa_log_info("[SM][UPDATE_SINK_SOURCE][AUTO] route_type(%d), deivce_type(%s), is_connected(%d))", + pa_log_debug("[SM][UPDATE_SINK_SOURCE][AUTO] route_type(%d), deivce_type(%s), is_connected(%d))", stream_route_type, device_type, is_connected); if (stream_type == STREAM_SINK_INPUT) sink = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); @@ -3232,7 +3233,7 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro } } else if (stream_route_type == STREAM_ROUTE_TYPE_MANUAL_EXT) { - pa_log_info("[SM][UPDATE_SINK_SOURCE][EXT] deivce_type(%s), is_connected(%d))", device_type, is_connected); + pa_log_debug("[SM][UPDATE_SINK_SOURCE][EXT] deivce_type(%s), is_connected(%d))", device_type, is_connected); if (!is_connected) { PA_IDXSET_FOREACH(s, streams, s_idx) { /* streams: source->outputs/sink->inputs */ if (!get_route_type(s, stream_type, false, &route_type) && route_type == stream_route_type) { @@ -3279,7 +3280,7 @@ static void mute_sink_inputs_as_device_disconnection(pa_stream_manager *m, uint3 pa_hashmap_put(m->muted_streams, (void*)event_id, muted_streams); } else { if (!(muted_streams = pa_hashmap_get(m->muted_streams, (void*)event_id))) { - pa_log_error("could not find muted_streams for event_id(%u)", event_id); + pa_log_debug("could not find muted_streams for event_id(%u)", event_id); return; } PA_IDXSET_FOREACH(i, muted_streams, s_idx) { -- 2.7.4 From 001604e4a1f202a649b7e55ba00437626080b108 Mon Sep 17 00:00:00 2001 From: Mok Jeongho Date: Thu, 4 Aug 2016 14:33:18 +0900 Subject: [PATCH 10/16] Modify device manager log [Version] 5.0.66 [Profile] Common [Issue Type] Log enhancement Change-Id: I72dad87226b001091fe8a7b10f70e8a6b96da975 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager.c | 322 +++++++++++++++++++------------- 2 files changed, 188 insertions(+), 136 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index abe407f..c2ed66a 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.65 +Version: 5.0.66 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager.c b/src/device-manager.c index 83b2b1e..05befca 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -960,91 +960,137 @@ static dm_device* _device_manager_get_device_with_id(pa_idxset *device_list, uin return NULL; } -static void dump_playback_device_list(pa_hashmap *playback_devices) { +static char* get_playback_list_str(pa_hashmap *playback_devices) { pa_sink *sink = NULL; void *state = NULL; const char *role; + pa_strbuf *buf; - if (!playback_devices) { - return ; - } + if (!playback_devices || !pa_hashmap_size(playback_devices)) + return NULL; - pa_log_debug(" playback device list"); - if (pa_hashmap_size(playback_devices) == 0) { - pa_log_debug(" empty"); - return; - } - PA_HASHMAP_FOREACH_KEY(sink, playback_devices, state, role) { - pa_log_debug(" %-13s -> %s", role, sink->name); - } + buf = pa_strbuf_new(); + pa_strbuf_printf(buf, " Playback device list\n"); + PA_HASHMAP_FOREACH_KEY(sink, playback_devices, state, role) + pa_strbuf_printf(buf, " %-13s -> %s\n", role, sink->name); + + return pa_strbuf_tostring_free(buf); } -static void dump_capture_device_list(pa_hashmap *capture_devices) { +static char* get_capture_list_str(pa_hashmap *capture_devices) { pa_source *source = NULL; void *state = NULL; const char *role; + pa_strbuf *buf; - if (!capture_devices) { - return ; - } + if (!capture_devices || !pa_hashmap_size(capture_devices)) + return NULL; - pa_log_debug(" capture device list"); - if (pa_hashmap_size(capture_devices) == 0) { - pa_log_debug(" empty"); - return; - } - PA_HASHMAP_FOREACH_KEY(source, capture_devices, state, role) { - pa_log_debug(" %-13s -> %s", role, source->name); - } + buf = pa_strbuf_new(); + pa_strbuf_printf(buf, " Capture device list\n"); + PA_HASHMAP_FOREACH_KEY(source, capture_devices, state, role) + pa_strbuf_printf(buf, " %-13s -> %s\n", role, source->name); + + return pa_strbuf_tostring_free(buf); } -static void dump_device_profile_info(dm_device_profile *profile_item) { +/* Returned string must be freed */ +static char* get_device_profile_info_str(dm_device_profile *profile_item) { + pa_strbuf *buf; + char *playback_str, *capture_str; if (!profile_item) - return; + return NULL; + + buf = pa_strbuf_new(); + pa_strbuf_printf(buf, " Profile : %s\n", pa_strna(profile_item->profile)); + pa_strbuf_printf(buf, " Direction : %s\n", device_direction_to_string(profile_item->direction)); + pa_strbuf_printf(buf, " Is activated : %s\n", pa_yes_no(COMPOUND_STATE(profile_item) == DM_DEVICE_STATE_ACTIVATED)); + playback_str = get_playback_list_str(profile_item->playback_devices); + capture_str = get_capture_list_str(profile_item->capture_devices); + + if (playback_str) + pa_strbuf_puts(buf, playback_str); + if (capture_str) + pa_strbuf_puts(buf, capture_str); + + pa_xfree(playback_str); + pa_xfree(capture_str); - pa_log_debug(" profile : %s", profile_item->profile); - pa_log_debug(" direction : %s", device_direction_to_string(profile_item->direction)); - pa_log_debug(" activated : %s", COMPOUND_STATE(profile_item) == DM_DEVICE_STATE_ACTIVATED ? "activated" : "not activated"); - dump_playback_device_list(profile_item->playback_devices); - dump_capture_device_list(profile_item->capture_devices); + return pa_strbuf_tostring_free(buf); } -static void dump_device_info(dm_device *device_item) { +static char* get_device_info_str(dm_device *device_item) { + pa_strbuf *buf; dm_device_profile *profile_item = NULL; uint32_t device_idx = 0; + char *profile_info; - if (!device_item) - return; - if (!device_item->profiles) { - pa_log_warn("empty device item"); - return; - } + if (!device_item || !device_item->profiles) + return NULL; - pa_log_debug(" id : %u", device_item->id); - pa_log_debug(" type : %s", device_item->type); - pa_log_debug(" name : %s", device_item->name); - pa_log_debug(" active-profile : %u", device_item->active_profile); + buf = pa_strbuf_new(); + pa_strbuf_printf(buf, "[Device #%u]\n", device_item->id); + pa_strbuf_printf(buf, " ID : %u\n", device_item->id); + pa_strbuf_printf(buf, " Type : %s\n", device_item->type); + pa_strbuf_printf(buf, " Name : %s\n", device_item->name); + pa_strbuf_printf(buf, " Active Profile : %u\n", device_item->active_profile); PA_IDXSET_FOREACH(profile_item, device_item->profiles, device_idx) { - pa_log_debug(" (Profile #%u)", device_idx); - dump_device_profile_info(profile_item); + pa_strbuf_printf(buf, " (Profile #%u)\n", device_idx); + profile_info = get_device_profile_info_str(profile_item); + if (profile_info) + pa_strbuf_puts(buf, profile_info); + pa_xfree(profile_info); } + + return pa_strbuf_tostring_free(buf); } -static void dump_device_list(pa_device_manager *dm) { +static char* get_device_list_str(pa_device_manager *dm) { dm_device *device_item = NULL; uint32_t device_idx = 0; + pa_strbuf *buf; + char *device_info; + + if (!dm || !dm->device_list) + return NULL; - if (!dm || !dm->device_list) { + buf = pa_strbuf_new(); + pa_strbuf_printf(buf, "=========== Device List ================\n"); + PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { + device_info = get_device_info_str(device_item); + if (device_info) + pa_strbuf_puts(buf, device_info); + pa_xfree(device_info); + } + pa_strbuf_printf(buf, "========================================\n"); + + return pa_strbuf_tostring_free(buf); +} + +static void dump_device_info(dm_device *device_item, pa_log_level_t log_level) { + char *info; + + if (!device_item) return; + + if ((info = get_device_info_str(device_item))) { + pa_logl(log_level, "%s", info); + pa_xfree(info); } +} - pa_log_debug("====== Device List Dump ======"); - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - pa_log_debug("[ Device #%u ]", device_item->id); - dump_device_info(device_item); +static void dump_device_list_info(pa_device_manager *dm, pa_log_level_t log_level) { + char *info; + + if (!dm || !dm->device_list) + return; + + if ((info = get_device_list_str(dm))) { + pa_logl(log_level, "%s", info); + pa_xfree(info); } - pa_log_debug("==================================="); } + static bool pulse_device_class_is_sound(pa_proplist *prop) { const char *device_class = NULL; @@ -1149,9 +1195,9 @@ static const char* build_params_to_load_device(const char *device_string, const return NULL; } args_buf = pa_strbuf_new(); - pa_strbuf_printf(args_buf, "device=hw:%s ", alsa_device_name); + pa_strbuf_printf(args_buf, "device=hw:%s \n", alsa_device_name); if (params) { - pa_strbuf_printf(args_buf, "%s", params); + pa_strbuf_printf(args_buf, "%s\n", params); } strncpy(args, pa_strbuf_tostring_free(args_buf), DEVICE_PARAM_STRING_MAX); } else { @@ -1478,7 +1524,7 @@ static dm_device* create_device_item(const char *device_type, const char *name, pa_assert(device_type); pa_assert(profile_item); - pa_log_debug("Create device item for %s", device_type); + pa_log_info("Create device item for %s", device_type); device_item = (dm_device *)pa_xmalloc(sizeof(dm_device)); device_item->id = device_id_max_g++; @@ -1512,7 +1558,7 @@ static void destroy_device_item(dm_device *device_item, pa_device_manager *dm) { return; } - pa_log_debug("Destroy device item which of type is %s", device_item->type); + pa_log_info("Destroy device item which of type is %s", device_item->type); device_item_free_func(device_item); } @@ -1576,7 +1622,7 @@ static dm_device* destroy_device_profile(dm_device_profile *profile_item, pa_dev device_item = profile_item->device_item; - pa_log_debug("Destroy device profile item which of profile is %s", profile_item->profile); + pa_log_info("Destroy device profile item which of profile is %s", profile_item->profile); if (_device_item_get_size(device_item) == 1) { destroy_device_item(device_item, dm); @@ -1900,7 +1946,7 @@ static dm_device_profile* handle_not_predefined_device_profile(void *pulse_devic dm_device_profile *profile_item = NULL; dm_device_direction_t direc; - pa_log_debug("Create device profile item %s", device_profile); + pa_log_info("Create device profile item %s", device_profile); if (pdt == PA_DEVICE_TYPE_SINK) direc = DM_DEVICE_DIRECTION_OUT; else @@ -1940,7 +1986,7 @@ static dm_device* handle_not_predefined_device(pa_device_manager *dm, void *puls pa_assert(dm); pa_assert(pulse_device); - pa_log_debug("handle_not_predefined_device"); + pa_log_info("handle_not_predefined_device"); if (pdt == PA_DEVICE_TYPE_SINK) ((pa_sink*)pulse_device)->use_internal_codec = false; @@ -2284,7 +2330,8 @@ static void handle_predefined_device_loaded(void *pulse_device, pa_device_type_t pa_assert(device_string); pa_assert(role); - pa_log_debug("Predefined device loaded, Type:%s, Class:%d, device_string:%s, role:%s", pdt == PA_DEVICE_TYPE_SINK ? "sink" : "source", device_class, device_string, role); + pa_log_info("Predefined device loaded, Type:%s, Class:%d, device_string:%s, role:%s", + pdt == PA_DEVICE_TYPE_SINK ? "sink" : "source", device_class, device_string, role); if (pdt == PA_DEVICE_TYPE_SINK) ((pa_sink*)pulse_device)->use_internal_codec = true; @@ -2362,7 +2409,7 @@ static void handle_sink_unloaded(pa_sink *sink, pa_device_manager *dm) { PA_HASHMAP_FOREACH_KEY(sink_iter, profile_item->playback_devices, state, role) { if (sink_iter == sink) { unsigned int profile_playback_size = 0, profile_capture_size = 0, item_size = 0; - pa_log_debug("device '%s' have this sink", device_item->name); + pa_log_info("device '%s' have this sink", device_item->name); _device_profile_get_size(profile_item, &profile_playback_size, &profile_capture_size); item_size = _device_item_get_size(device_item); pa_log_debug("profile playback size : %u, capture size : %u, item size : %u", profile_playback_size, profile_capture_size, item_size); @@ -2425,7 +2472,7 @@ static void handle_source_unloaded(pa_source *source, pa_device_manager *dm) { PA_HASHMAP_FOREACH_KEY(source_iter, profile_item->capture_devices, state, role) { if (source_iter == source) { unsigned int profile_playback_size = 0, profile_capture_size = 0, item_size = 0; - pa_log_debug("device '%s' have this source", device_item->name); + pa_log_info("device '%s' have this source", device_item->name); _device_profile_get_size(profile_item, &profile_playback_size, &profile_capture_size); item_size = _device_item_get_size(device_item); pa_log_debug("profile playback size : %u, capture size : %u, item size : %u", profile_playback_size, profile_capture_size, item_size); @@ -2481,15 +2528,15 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, pa_dev return PA_HOOK_OK; } - pa_log_debug("========== Sink Put Hook Callback '%s'(%d) ==========", sink->name, sink->index); + pa_log_info("========== Sink Put Hook Callback '%s'(%d) ==========", sink->name, sink->index); device_class = pulse_device_get_class(sink, PA_DEVICE_TYPE_SINK); - pa_log_debug("Device Class '%s'", device_class_to_string(device_class)); + pa_log_info("Device Class '%s'", device_class_to_string(device_class)); if (!(device_string = pulse_device_get_device_string(sink, PA_DEVICE_TYPE_SINK))) { return PA_HOOK_OK; } else { - pa_log_debug("Device String '%s'", device_string); + pa_log_info("Device String '%s'", device_string); } if (device_class == DM_DEVICE_CLASS_BT) { @@ -2512,7 +2559,7 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, pa_dev handle_not_predefined_device(dm, sink, PA_DEVICE_TYPE_SINK, device_class); } - dump_device_list(dm); + dump_device_list_info(dm, PA_LOG_INFO); return PA_HOOK_OK; } @@ -2527,9 +2574,9 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, pa_ return PA_HOOK_OK; } - pa_log_debug("=========== Sink unlink Hook Callback '%s'(%d) ==========", sink->name, sink->index); + pa_log_info("=========== Sink unlink Hook Callback '%s'(%d) ==========", sink->name, sink->index); handle_sink_unloaded(sink, dm); - dump_device_list(dm); + dump_device_list_info(dm, PA_LOG_INFO); return PA_HOOK_OK; } @@ -2603,16 +2650,16 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, return PA_HOOK_OK; } - pa_log_debug("========== Source Put Hook Callback '%s'(%d) ==========", source->name, source->index); + pa_log_info("========== Source Put Hook Callback '%s'(%d) ==========", source->name, source->index); device_class = pulse_device_get_class(source, PA_DEVICE_TYPE_SOURCE); - pa_log_debug("Device Class '%s'", device_class_to_string(device_class)); + pa_log_info("Device Class '%s'", device_class_to_string(device_class)); if (!(device_string = pulse_device_get_device_string(source, PA_DEVICE_TYPE_SOURCE))) { return PA_HOOK_OK; } else { - pa_log_debug("Device String '%s'", device_string); + pa_log_info("Device String '%s'", device_string); } if (device_class == DM_DEVICE_CLASS_BT) { @@ -2635,7 +2682,7 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, handle_not_predefined_device(dm, source, PA_DEVICE_TYPE_SOURCE, device_class); } - dump_device_list(dm); + dump_device_list_info(dm, PA_LOG_INFO); return PA_HOOK_OK; } @@ -2650,9 +2697,9 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc return PA_HOOK_OK; } - pa_log_debug("========== Source unlink Hook Callback '%s'(%d) ==========", source->name, source->index); + pa_log_info("========== Source unlink Hook Callback '%s'(%d) ==========", source->name, source->index); handle_source_unloaded(source, dm); - dump_device_list(dm); + dump_device_list_info(dm, PA_LOG_INFO); return PA_HOOK_OK; } @@ -2674,7 +2721,7 @@ static void* load_device(pa_core *c, pa_device_type_t pdt, const char *device_st pa_assert(device_string); pa_assert(device_params); - pa_log_debug("-------- load_%s_device : '%s' '%s' -------", pdt == PA_DEVICE_TYPE_SINK ? "playback" : "capture", device_string, device_params); + pa_log_info("Load %s Device : String'%s' Param'%s'", pdt == PA_DEVICE_TYPE_SINK ? "Playback" : "Capture", device_string, device_params); device_class = device_string_get_class(device_string); if (device_class <= DM_DEVICE_CLASS_NONE || device_class >= DM_DEVICE_CLASS_MAX) { @@ -2806,7 +2853,7 @@ static pa_hashmap* parse_device_role_object(json_object *device_role_o) { if (!(params = json_object_get_string(params_o))) { pa_log_debug("There is no device params for role '%s'", device_role); } - pa_log_debug("[DEBUG_PARSE] role '%s' - params '%s'", device_role, params); + pa_log_info("- Role '%s' -> '%s'", device_role, params); if (device_role_is_valid(device_role)) { if (pa_hashmap_put(roles, (void *)device_role, (void *)params)) { pa_log_error("put new role to hashmap faild"); @@ -2846,7 +2893,7 @@ static struct device_file_info* parse_device_file_object(json_object *device_fil if (json_object_object_get_ex(device_file_o, "device-string", &device_file_prop_o) && json_object_is_type(device_file_prop_o, json_type_string)) { if ((device_string = json_object_get_string(device_file_prop_o))) { - pa_log_debug("[DEBUG_PARSE] ---------------- Device File '%s' ----------------", device_string); + pa_log_info("[ Device File - %s ]", device_string); } else { pa_log_error("Get device-string failed"); return NULL; @@ -2922,7 +2969,7 @@ static struct device_file_map *parse_device_file_map() { json_object *o, *device_files_o; json_object *playback_devices_o = NULL, *capture_devices_o = NULL; - pa_log_debug("\n[DEBUG_PARSE] ==================== Parse device files ===================="); + pa_log_info("\nParse device files"); o = json_object_from_file(DEVICE_MAP_FILE); @@ -2935,11 +2982,11 @@ static struct device_file_map *parse_device_file_map() { if (json_object_object_get_ex(o, DEVICE_FILE_OBJECT, &device_files_o) && json_object_is_type(device_files_o, json_type_object)) { if (json_object_object_get_ex(device_files_o, "playback-devices", &playback_devices_o)) { - pa_log_debug("[DEBUG_PARSE] ----------------- Playback Device Files ------------------"); + pa_log_info("Playback Device Files"); file_map->playback = parse_device_file_array_object(playback_devices_o); } if (json_object_object_get_ex(device_files_o, "capture-devices", &capture_devices_o)) { - pa_log_debug("[DEBUG_PARSE] ----------------- Capture Device Files ------------------"); + pa_log_info("Capture Device Files"); file_map->capture = parse_device_file_array_object(capture_devices_o); } } else { @@ -2972,7 +3019,7 @@ static pa_hashmap* parse_device_role_map(json_object *device_role_map_o) { if (!(device_string = json_object_get_string(device_string_o))) { pa_log_debug("There is no device string for role '%s'", device_role); } - pa_log_debug("[DEBUG_PARSE] role '%s' - device_string '%s'", device_role, device_string); + pa_log_info("- Role '%s' -> '%s'", device_role, device_string); if (device_role_is_valid(device_role)) { if (pa_hashmap_put(roles, (void *)device_role, (void *)device_string)) { pa_log_error("put new role to hashmap faild"); @@ -3012,7 +3059,7 @@ static pa_idxset* parse_device_type_infos() { return NULL; } - pa_log_debug("\n[DEBUG_PARSE] ==================== Parse device types ===================="); + pa_log_info("\nParse device types"); type_infos = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); if (json_object_object_get_ex(o, DEVICE_TYPE_OBJECT, &device_array_o) && json_object_is_type(device_array_o, json_type_array)) { @@ -3029,7 +3076,7 @@ static pa_idxset* parse_device_type_infos() { if (json_object_object_get_ex(device_o, "device-type", &device_prop_o) && json_object_is_type(device_prop_o, json_type_string)) { device_type = json_object_get_string(device_prop_o); - pa_log_debug("[DEBUG_PARSE] ---------------- Parse device '%s' ----------------", device_type); + pa_log_info("[ Device - %s ]", device_type); type_info->type = device_type; } else { pa_log_error("Get device type failed"); @@ -3037,7 +3084,7 @@ static pa_idxset* parse_device_type_infos() { } if (json_object_object_get_ex(device_o, "profile", &device_prop_o) && json_object_is_type(device_prop_o, json_type_string)) { device_profile = json_object_get_string(device_prop_o); - pa_log_debug("[DEBUG_PARSE] Profile: %s", device_profile); + pa_log_info("Profile - %s", device_profile); type_info->profile = device_profile; } else { pa_log_debug("no device-profile"); @@ -3046,7 +3093,7 @@ static pa_idxset* parse_device_type_infos() { if (json_object_object_get_ex(device_o, DEVICE_TYPE_PROP_BUILTIN, &device_prop_o) && json_object_is_type(device_prop_o, json_type_boolean)) { builtin = json_object_get_boolean(device_prop_o); - pa_log_debug("[DEBUG_PARSE] builtin: %d", builtin); + pa_log_debug("Builtin : %d", builtin); type_info->builtin = builtin; } else { pa_log_error("Get device prop '%s' failed", DEVICE_TYPE_PROP_BUILTIN); @@ -3062,7 +3109,7 @@ static pa_idxset* parse_device_type_infos() { for (array_idx = 0; array_idx < array_len; array_idx++) { if ((array_item_o = json_object_array_get_idx(device_prop_o, array_idx)) && json_object_is_type(array_item_o, json_type_string)) { direction = json_object_get_string(array_item_o); - pa_log_debug("[DEBUG_PARSE] direction : %s", direction); + pa_log_debug("Direction : %s", direction); type_info->direction[array_idx] = device_direction_to_int(direction); } } @@ -3079,7 +3126,7 @@ static pa_idxset* parse_device_type_infos() { for (array_idx = 0; array_idx < array_len; array_idx++) { if ((array_item_o = json_object_array_get_idx(device_prop_o, array_idx)) && json_object_is_type(array_item_o, json_type_string)) { avail_cond = json_object_get_string(array_item_o); - pa_log_debug("[DEBUG_PARSE] avail-condition : %s", avail_cond); + pa_log_debug("avail-condition : %s", avail_cond); strncpy(type_info->avail_condition[array_idx], avail_cond, DEVICE_AVAIL_COND_STR_MAX); } } @@ -3088,12 +3135,12 @@ static pa_idxset* parse_device_type_infos() { } if (json_object_object_get_ex(device_o, "playback-devices", &device_prop_o) && json_object_is_type(device_prop_o, json_type_object)) { - pa_log_debug("[DEBUG_PARSE] ------ playback devices ------"); + pa_log_info("Playback Devices"); type_info->playback_devices = parse_device_role_map(device_prop_o); } if (json_object_object_get_ex(device_o, "capture-devices", &device_prop_o) && json_object_is_type(device_prop_o, json_type_object)) { - pa_log_debug("[DEBUG_PARSE] ------ capture devices ------"); + pa_log_info("Capture Devices"); type_info->capture_devices = parse_device_role_map(device_prop_o); } pa_idxset_put(type_infos, type_info, NULL); @@ -3129,7 +3176,7 @@ static int handle_device_connected(pa_device_manager *dm, const char *device_typ pa_assert(dm); pa_assert(dm->device_status); - pa_log_debug("Device %s connected, detected_type : %d", device_type, detected_type); + pa_log_info("Device %s connected, detected_type : %d", device_type, detected_type); if (!(status_info = _device_manager_get_status_info(dm->device_status, device_type, device_profile, identifier))) { pa_log_error("No device_status_info for %s.%s", device_type, device_profile); return -1; @@ -3168,7 +3215,7 @@ static int handle_device_disconnected(pa_device_manager *dm, const char *device_ pa_assert(dm); pa_assert(dm->device_status); - pa_log_debug("Device %s disconnected", device_type); + pa_log_info("Device %s disconnected", device_type); if (!(status_info = _device_manager_get_status_info(dm->device_status, device_type, device_profile, identifier))) { pa_log_error("No device_status_info for %s.%s", device_type, device_profile); return -1; @@ -3202,7 +3249,8 @@ static int handle_device_status_changed(pa_device_manager *dm, const char *devic pa_assert(dm); pa_assert(device_type_is_valid(device_type)); - pa_log_debug("Device Status Changed, type : '%s', profile : '%s', identifier : '%s', detected_status : %d", device_type, device_profile, identifier, detected_status); + pa_log_info("Device Status Changed, type : '%s', profile : '%s', identifier : '%s', detected_status : %d", + device_type, device_profile, identifier, detected_status); if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) { if (detected_status == EARJACK_DISCONNECTED) { handle_device_disconnected(dm, device_type, device_profile, identifier); @@ -3345,12 +3393,8 @@ static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DB if (dbus_message_get_type(s) != DBUS_MESSAGE_TYPE_SIGNAL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - pa_log_info("Dbus device detect handler received msg"); - - pa_log_debug("path : %s", dbus_message_get_path(s)); - pa_log_debug("interface : %s", dbus_message_get_interface(s)); - pa_log_debug("member : %s", dbus_message_get_member(s)); - pa_log_debug("siganature : %s", dbus_message_get_signature(s)); + pa_log_info("Device detect handler : Path(%s) Intf(%s) Member(%s) Signature(%s)", + dbus_message_get_path(s), dbus_message_get_interface(s), dbus_message_get_member(s), dbus_message_get_signature(s)); dbus_error_init(&error); @@ -3383,7 +3427,7 @@ static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DB goto fail; } dbus_message_iter_get_basic(&msg_iter, &property_name); - pa_log_debug("property name : %s", property_name); + pa_log_info("Changed Property name : %s", property_name); if (!dbus_message_iter_next(&msg_iter)) { pa_log_debug("Property value missing"); @@ -3402,7 +3446,7 @@ static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DB char *name; dbus_message_iter_get_basic(&variant_iter, &value); if (pa_streq(property_name, "Connected")) { - pa_log_debug("HFP Connection : %d", value); + pa_log_info("HFP Connection : %d", value); if (value) { method_call_bt_get_name(c, dbus_message_get_path(s), &name); status = BT_SCO_CONNECTED; @@ -3413,7 +3457,7 @@ static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DB } } } else { - pa_log_info("Unknown message, not handle it"); + pa_log_debug("Unknown message, not handle it"); dbus_error_free(&error); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } @@ -3437,7 +3481,7 @@ static int watch_signals(pa_device_manager *dm) { dbus_error_init(&error); - pa_log_debug("Watch Dbus signals"); + pa_log_info("Watch Dbus signals"); if (!dbus_connection_add_filter(pa_dbus_connection_get(dm->dbus_conn), dbus_filter_device_detect_handler, dm, NULL)) { pa_log_error("Unable to add D-Bus filter : %s: %s", error.name, error.message); @@ -3456,7 +3500,7 @@ fail: } static void unwatch_signals(pa_device_manager *dm) { - pa_log_debug("Unwatch Dbus signals"); + pa_log_info("Unwatch Dbus signals"); pa_assert(dm); pa_assert(dm->dbus_conn); @@ -3473,13 +3517,14 @@ static void send_device_connected_signal(uint32_t event_id, dm_device *device_it dbus_bool_t _connected = connected; dm_device_state_t compound_state; dbus_int32_t device_id; + const char *device_info_str; pa_assert(device_item); pa_assert(device_item->profiles); pa_assert(dm); - pa_log_debug("Send following device %s signal", connected ? "Connected" : "Disconnected"); - dump_device_info(device_item); + pa_log_info("Send following device %s signal", connected ? "Connected" : "Disconnected"); + dump_device_info(device_item, PA_LOG_INFO); pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceConnected")); dbus_message_iter_init_append(signal_msg, &msg_iter); @@ -3511,13 +3556,14 @@ static void send_device_info_changed_signal(uint32_t event_id, dm_device *device dm_device_profile *profile_item; dm_device_state_t compound_state; dbus_int32_t device_id; + const char *device_info_str; pa_assert(device_item); pa_assert(device_item->profiles); pa_assert(dm); - pa_log_debug("Send folling device info changed signal"); - dump_device_info(device_item); + pa_log_debug("Send following device info changed signal"); + dump_device_info(device_item, PA_LOG_DEBUG); pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceInfoChanged")); dbus_message_iter_init_append(signal_msg, &msg_iter); @@ -3770,7 +3816,7 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage * pa_assert(msg); pa_assert(userdata); - pa_log_debug("Get connected device list"); + pa_log_info("Get connected device list"); dm = (pa_device_manager*) userdata; @@ -3820,7 +3866,7 @@ static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, vo pa_assert(msg); pa_assert(userdata); - pa_log_debug("Get bt a2dp list"); + pa_log_info("Get BT A2DP list"); dm = (pa_device_manager*) userdata; @@ -3940,7 +3986,7 @@ static DBusHandlerResult method_call_handler(DBusConnection *c, DBusMessage *m, interface = dbus_message_get_interface(m); member = dbus_message_get_member(m); - pa_log_debug("DeviceManager Method Call Handler : path=%s, interface=%s, member=%s", path, interface, member); + pa_log_info("DeviceManager Method Call Handler : path=%s, interface=%s, member=%s", path, interface, member); if (!pa_streq(path, DBUS_OBJECT_DEVICE_MANAGER)) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -3967,7 +4013,7 @@ static void endpoint_init(pa_device_manager *dm) { .message_function = method_call_handler, }; - pa_log_debug("Device manager dbus endpoint init"); + pa_log_info("Device manager dbus endpoint init"); if (dm && dm->dbus_conn) { if (!dbus_connection_register_object_path(pa_dbus_connection_get(dm->dbus_conn), DBUS_OBJECT_DEVICE_MANAGER, &vtable_endpoint, dm)) @@ -3978,7 +4024,7 @@ static void endpoint_init(pa_device_manager *dm) { } static void endpoint_done(pa_device_manager *dm) { - pa_log_debug("Device manager dbus endpoint done"); + pa_log_info("Device manager dbus endpoint done"); if (dm && dm->dbus_conn) { if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(dm->dbus_conn), DBUS_OBJECT_DEVICE_MANAGER)) pa_log_error("Failed to unregister object path"); @@ -3992,7 +4038,7 @@ static void dbus_init(pa_device_manager *dm) { pa_dbus_connection *connection = NULL; pa_assert(dm); - pa_log_debug("Dbus init"); + pa_log_info("Dbus init"); dbus_error_init(&error); if (!(connection = pa_dbus_bus_get(dm->core, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) { @@ -4002,7 +4048,7 @@ static void dbus_init(pa_device_manager *dm) { pa_log_error("Unable to contact D-Bus system bus: %s: %s", error.name, error.message); goto fail; } else { - pa_log_debug("Got dbus connection"); + pa_log_info("Got dbus connection"); } dm->dbus_conn = connection; @@ -4021,7 +4067,7 @@ fail: static void dbus_deinit(pa_device_manager *dm) { pa_assert(dm); - pa_log_debug("Dbus deinit"); + pa_log_info("Dbus deinit"); endpoint_done(dm); unwatch_signals(dm); @@ -4060,7 +4106,7 @@ pa_sink* pa_device_manager_get_sink(dm_device *device_item, const char *role) { pa_assert(profile_item = _device_item_get_active_profile(device_item)); if (!profile_item->playback_devices) { - pa_log_warn("No playback device in %s", device_item->name); + pa_log_debug("No playback device in %s", device_item->name); return NULL; } if ((sink = pa_hashmap_get(profile_item->playback_devices, role))) @@ -4081,7 +4127,7 @@ pa_source* pa_device_manager_get_source(dm_device *device_item, const char *role pa_assert(profile_item = _device_item_get_active_profile(device_item)); if (!profile_item->capture_devices) { - pa_log_warn("No capture device in %s", device_item->name); + pa_log_debug("No capture device in %s", device_item->name); return NULL; } @@ -4113,7 +4159,7 @@ void pa_device_manager_set_device_state(dm_device *device_item, dm_device_direct pa_assert(device_item); pa_assert(profile_item = _device_item_get_active_profile(device_item)); - pa_log_debug("pa_device_manager_set_device_state : %s.%s direction %s -> %d", device_item->type, profile_item->profile, device_direction_to_string(direction), state); + pa_log_info("pa_device_manager_set_device_state : %s.%s direction %s -> %d", device_item->type, profile_item->profile, device_direction_to_string(direction), state); _device_profile_set_state(profile_item, direction, state); } @@ -4203,22 +4249,22 @@ int pa_device_manager_bt_sco_open(pa_device_manager *dm) { pa_assert(dm->dbus_conn); if (dm->bt_sco_status != DM_DEVICE_BT_SCO_STATUS_CONNECTED) { - pa_log_error("bt-sco not connected"); + pa_log_error("BT SCO Not Connected"); return -1; } if ((bt_device = _device_manager_get_device(dm->device_list, DEVICE_TYPE_BT)) == NULL) { - pa_log_error("no bt device"); + pa_log_error("No BT Device"); return -1; } - pa_log_debug("bt sco open start"); + pa_log_info("BT SCO Open - Request to BT FW"); if (method_call_bt_sco(pa_dbus_connection_get(dm->dbus_conn), true) < 0) { pa_log_error("Failed to bt sco on"); return -1; } + pa_log_info("BT SCO Open - SUCCESS"); - pa_log_debug("bt sco open end"); dm->bt_sco_status = DM_DEVICE_BT_SCO_STATUS_OPENED; handle_device_connected(dm, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, NULL, NULL, DEVICE_DETECTED_BT_SCO); @@ -4229,6 +4275,7 @@ void pa_device_manager_bt_sco_get_status(pa_device_manager *dm, dm_device_bt_sco pa_assert(dm); pa_assert(status); + pa_log_info("BT SCO get status %d", dm->bt_sco_status); *status = dm->bt_sco_status; return; @@ -4240,26 +4287,27 @@ int pa_device_manager_bt_sco_close(pa_device_manager *dm) { pa_assert(dm); pa_assert(dm->dbus_conn); + if (dm->bt_sco_status != DM_DEVICE_BT_SCO_STATUS_OPENED) { - pa_log_error("bt-sco not opened"); + pa_log_error("BT SCO Not Opened"); return -1; } if ((bt_device = _device_manager_get_device(dm->device_list, DEVICE_TYPE_BT)) == NULL) { - pa_log_error("no bt device"); + pa_log_error("No BT Device"); return -1; } - pa_log_debug("bt sco close start"); + pa_log_info("BT SCO Close - Request to BT FW"); if (method_call_bt_sco(pa_dbus_connection_get(dm->dbus_conn), false) < 0) { - pa_log_error("Failed to bt sco close"); + pa_log_error("Failed to BT SCO Close"); return -1; } + pa_log_info("BT SCO Close - Success"); dm->bt_sco_status = DM_DEVICE_BT_SCO_STATUS_CONNECTED; handle_device_disconnected(dm, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, NULL); - pa_log_debug("bt sco close end"); return 0; } @@ -4268,14 +4316,14 @@ int pa_device_manager_bt_sco_get_property(pa_device_manager *dm, bool *is_wide_b pa_assert(dm); pa_assert(dm->dbus_conn); - pa_log_debug("bt sco get property start"); + pa_log_info("BT SCO Get Property - Request to BT FW"); if (method_call_bt_sco_get_property(pa_dbus_connection_get(dm->dbus_conn), is_wide_band, nrec) < 0) { - pa_log_error("Failed to get bt property"); + pa_log_error("Failed to get BT SCO Property"); return -1; } - pa_log_debug("bt sco get property end"); + pa_log_info("BT SCO Get Property - Success, is wide band : %s, nrec : %s", pa_yes_no(is_wide_band), pa_yes_no(nrec)); return 0; } @@ -4292,12 +4340,12 @@ int pa_device_manager_load_sink(pa_device_manager *dm, const char *device_type, pa_assert(dm); pa_assert(dm->device_list); - pa_log_debug("load sink for '%s,%s'", device_type, role); + pa_log_info("Load Sink for '%s.%s.%s'", device_type, device_profile, role); PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { if (pa_streq(device_type, device_item->type)) { if ((profile_item = _device_item_get_profile(device_item, device_profile))) { if (pa_hashmap_get(profile_item->playback_devices, role)) { - pa_log_warn("Proper sink for '%s:%s' already loaded", device_type, role); + pa_log_warn("Proper sink for '%s.%s.%s' already loaded", device_type, device_profile, role); return -1; } } @@ -4310,7 +4358,7 @@ int pa_device_manager_load_sink(pa_device_manager *dm, const char *device_type, } if (!(device_string = pa_hashmap_get(type_info->playback_devices, role))) { - pa_log_error("No device-string for '%s:%s'", device_type, role); + pa_log_error("No device-string for '%s.%s.%s'", device_type, device_profile, role); goto failed; } @@ -4348,13 +4396,13 @@ int pa_device_manager_load_source(pa_device_manager *dm, const char *device_type pa_assert(dm); - pa_log_debug("load source for '%s,%s'", device_type, role); + pa_log_info("Load Source for '%s.%s.%s'", device_type, device_profile, role); PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { if (pa_streq(device_type, device_item->type)) { if ((profile_item = _device_item_get_profile(device_item, device_profile))) { if (pa_hashmap_get(profile_item->capture_devices, role)) { - pa_log_warn("Proper source for '%s:%s' already loaded", device_type, role); + pa_log_warn("Proper source for '%s.%s.%s' already loaded", device_type, device_profile, role); return -1; } } @@ -4368,7 +4416,7 @@ int pa_device_manager_load_source(pa_device_manager *dm, const char *device_type } if (!(device_string = pa_hashmap_get(type_info->capture_devices, role))) { - pa_log_error("No device-string for '%s:%s'", device_type, role); + pa_log_error("No device-string for '%s.%s.%s'", device_type, device_profile, role); goto failed; } @@ -4400,6 +4448,8 @@ pa_device_manager* pa_device_manager_get(pa_core *c) { pa_assert(c); + pa_log_info("pa_device_manager_get"); + if ((dm = pa_shared_get(c, SHARED_DEVICE_MANAGER))) return pa_device_manager_ref(dm); @@ -4460,6 +4510,7 @@ pa_device_manager* pa_device_manager_ref(pa_device_manager *dm) { pa_assert(dm); pa_assert(PA_REFCNT_VALUE(dm) > 0); + pa_log_info("pa_device_manager_ref"); PA_REFCNT_INC(dm); return dm; @@ -4469,6 +4520,7 @@ void pa_device_manager_unref(pa_device_manager *dm) { pa_assert(dm); pa_assert(PA_REFCNT_VALUE(dm) > 0); + pa_log_info("pa_device_manager_unref"); if (PA_REFCNT_DEC(dm) > 0) return; -- 2.7.4 From f20dfc0182d814ac388635547d1d0864ca47b765 Mon Sep 17 00:00:00 2001 From: Seungbae Shin Date: Fri, 29 Apr 2016 21:23:45 +0900 Subject: [PATCH 11/16] Add module-hw-keysound to handle h/w touch key event this feature is moved from sound-server [Version] 5.0.67 [Profile] Common [Issue Type] Feature enhancement Change-Id: I3fef49a79b5121d3ce9a7482fae0fc925042637e --- Makefile.am | 47 +++--- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-hw-keysound.c | 257 ++++++++++++++++++++++++++++++++ 3 files changed, 285 insertions(+), 21 deletions(-) create mode 100644 src/module-hw-keysound.c diff --git a/Makefile.am b/Makefile.am index bfb626c..157bfac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,16 +25,17 @@ AM_CFLAGS = \ AM_LIBADD = $(PTHREAD_LIBS) $(INTLLIBS) AM_LDFLAGS = $(NODELETE_LDFLAGS) -MODULE_CFLAGS = $(AM_CFLAGS) -MODULE_LDFLAGS = $(AM_LDFLAGS) -module -disable-static -avoid-version -MODULE_LIBADD = $(AM_LIBADD) $(LIBLTDL) +MODULE_CFLAGS = $(AM_CFLAGS) $(PACORE_CFLAGS) $(PA_CFLAGS) +MODULE_LDFLAGS = $(AM_LDFLAGS) $(PACORE_LDFLAGS) $(PA_LDFLAGS) -module -disable-static -avoid-version +MODULE_LIBADD = $(AM_LIBADD) $(PACORE_LIBS) $(PA_LIBS) pulsemodlibexec_LTLIBRARIES = \ libhal-interface.la \ module-tizenaudio-sink.la \ module-tizenaudio-source.la \ module-tizenaudio-policy.la \ - module-sound-player.la + module-sound-player.la \ + module-hw-keysound.la if ENABLE_HALTC pulsemodlibexec_LTLIBRARIES += \ module-tizenaudio-haltc.la @@ -46,7 +47,8 @@ SYMDEF_FILES = \ module-tizenaudio-sink-symdef.h \ module-tizenaudio-source-symdef.h \ module-tizenaudio-policy-symdef.h \ - module-sound-player-symdef.h + module-sound-player-symdef.h \ + module-hw-keysound-symdef.h if ENABLE_HALTC SYMDEF_FILES += \ module-tizenaudio-haltc-symdef.h @@ -70,19 +72,19 @@ libhal_interface_la_LIBADD = $(AM_LIBADD) $(PACORE_LIBS) $(PA_LIBS) libhal_interface_la_CFLAGS = $(AM_CFLAGS) $(PACORE_CFLAGS) $(PA_CFLAGS) module_tizenaudio_sink_la_SOURCES = src/module-tizenaudio-sink.c -module_tizenaudio_sink_la_LDFLAGS = $(PACORE_LDFLAGS) $(PA_LDFLAGS) $(MODULE_LDFLAGS) -module_tizenaudio_sink_la_LIBADD = $(PACORE_LIBS) $(PA_LIBS) $(MODULE_LIBADD) libhal-interface.la -module_tizenaudio_sink_la_CFLAGS = $(PACORE_CFLAGS) $(PA_CFLAGS) $(AM_CFLAGS) +module_tizenaudio_sink_la_LDFLAGS = $(MODULE_LDFLAGS) +module_tizenaudio_sink_la_LIBADD = $(MODULE_LIBADD) libhal-interface.la +module_tizenaudio_sink_la_CFLAGS = $(MODULE_CFLAGS) module_tizenaudio_source_la_SOURCES = src/module-tizenaudio-source.c -module_tizenaudio_source_la_LDFLAGS = $(PACORE_LDFLAGS) $(PA_LDFLAGS) $(MODULE_LDFLAGS) -module_tizenaudio_source_la_LIBADD = $(PACORE_LIBS) $(PA_LIBS) $(MODULE_LIBADD) libhal-interface.la -module_tizenaudio_source_la_CFLAGS = $(PACORE_CFLAGS) $(PA_CFLAGS) $(AM_CFLAGS) +module_tizenaudio_source_la_LDFLAGS = $(MODULE_LDFLAGS) +module_tizenaudio_source_la_LIBADD = $(MODULE_LIBADD) libhal-interface.la +module_tizenaudio_source_la_CFLAGS = $(MODULE_CFLAGS) module_sound_player_la_SOURCES = src/module-sound-player.c -module_sound_player_la_LDFLAGS = $(MODULE_LDFLAGS) $(PACORE_LDFLAGS) $(PA_LDFLAGS) -module_sound_player_la_LIBADD = $(MODULE_LIBADD) $(PACORE_LIBS) $(PA_LIBS) $(AM_LIBADD) $(DBUS_LIBS) -module_sound_player_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) $(PACORE_CFLAGS) $(PA_CFLAGS) +module_sound_player_la_LDFLAGS = $(MODULE_LDFLAGS) +module_sound_player_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) +module_sound_player_la_CFLAGS = $(MODULE_CFLAGS) $(DBUS_CFLAGS) module_tizenaudio_policy_la_SOURCES = \ src/module-tizenaudio-policy.c \ @@ -92,13 +94,18 @@ module_tizenaudio_policy_la_SOURCES = \ src/stream-manager-restriction.c src/stream-manager-restriction-priv.h \ src/device-manager.c src/device-manager.h \ src/subscribe-observer.c src/subscribe-observer.h -module_tizenaudio_policy_la_LDFLAGS = $(MODULE_LDFLAGS) $(PACORE_LDFLAGS) $(PA_LDFLAGS) -L$(pulsemodlibexecdir) -module_tizenaudio_policy_la_LIBADD = $(AM_LIBADD) $(PACORE_LIBS) $(PA_LIBS) $(DBUS_LIBS) $(VCONF_LIBS) $(INIPARSER_LIBS) $(LIBJSON_LIBS) libhal-interface.la -module_tizenaudio_policy_la_CFLAGS = $(AM_CFLAGS) $(PACORE_CFLAGS) $(PA_CFLAGS) $(DBUS_CFLAGS) $(VCONF_CFLAGS) $(INIPARSER_CFLAGS) $(LIBJSON_CFLAGS) +module_tizenaudio_policy_la_LDFLAGS = $(MODULE_LDFLAGS) -L$(pulsemodlibexecdir) +module_tizenaudio_policy_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(VCONF_LIBS) $(INIPARSER_LIBS) $(LIBJSON_LIBS) libhal-interface.la +module_tizenaudio_policy_la_CFLAGS = $(MODULE_CFLAGS) $(DBUS_CFLAGS) $(VCONF_CFLAGS) $(INIPARSER_CFLAGS) $(LIBJSON_CFLAGS) if ENABLE_HALTC module_tizenaudio_haltc_la_SOURCES = src/module-tizenaudio-haltc.c -module_tizenaudio_haltc_la_LDFLAGS = $(PACORE_LDFLAGS) $(PA_LDFLAGS) $(MODULE_LDFLAGS) -module_tizenaudio_haltc_la_LIBADD = $(PACORE_LIBS) $(PA_LIBS) $(MODULE_LIBADD) libhal-interface.la -module_tizenaudio_haltc_la_CFLAGS = $(PACORE_CFLAGS) $(PA_CFLAGS) $(AM_CFLAGS) +module_tizenaudio_haltc_la_LDFLAGS = $(MODULE_LDFLAGS) +module_tizenaudio_haltc_la_LIBADD = $(MODULE_LIBADD) libhal-interface.la +module_tizenaudio_haltc_la_CFLAGS = $(MODULE_CFLAGS) endif + +module_hw_keysound_la_SOURCES = src/module-hw-keysound.c +module_hw_keysound_la_LDFLAGS = $(MODULE_LDFLAGS) +module_hw_keysound_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(VCONF_LIBS) +module_hw_keysound_la_CFLAGS = $(MODULE_CFLAGS) $(DBUS_CFLAGS) $(VCONF_CFLAGS) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index c2ed66a..fd64630 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.66 +Version: 5.0.67 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-hw-keysound.c b/src/module-hw-keysound.c new file mode 100644 index 0000000..eac87c2 --- /dev/null +++ b/src/module-hw-keysound.c @@ -0,0 +1,257 @@ +/*** + This file is part of PulseAudio. + + Copyright 2016 Seungbae Shin + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "module-hw-keysound-symdef.h" + +PA_MODULE_AUTHOR("Seungbae Shin"); +PA_MODULE_DESCRIPTION("H/W Keysound play module"); +PA_MODULE_VERSION(PACKAGE_VERSION); +PA_MODULE_LOAD_ONCE(true); + +#define INTERFACE_NAME "org.tizen.system.deviced.Key" +#define SIGNAL_NAME "ChangeHardkey" +#define DBUS_HW_KEYTONE "/usr/share/sounds/sound-server/Tizen_HW_Touch.ogg" +#define FILTER_HARDKEY "type='signal', interface='"INTERFACE_NAME"', member='"SIGNAL_NAME"'" +#define MAX_NAME_LEN 256 +#define DEFAULT_ROLE "system" +#define DEFAULT_VOLUME_GAIN "touch" + +struct userdata { + pa_module *module; + pa_dbus_connection *dbus_conn; +}; + +static void _hw_keysound_play(struct userdata *u, const char *file_path) { + int ret = 0; + pa_proplist *p = NULL; + const char *name_prefix = "HWKEY"; + char name[MAX_NAME_LEN] = {0}; + uint32_t stream_idx = 0; + uint32_t scache_idx = 0; + + /* Load if not cached */ + pa_snprintf(name, sizeof(name), "%s_%s", name_prefix, file_path); + + scache_idx = pa_scache_get_id_by_name(u->module->core, name); + if (scache_idx != PA_IDXSET_INVALID) { + pa_log_debug("found cached index [%u] for name [%s]", scache_idx, file_path); + } else { + /* for more precision, need to update volume value here */ + if ((ret = pa_scache_add_file_lazy(u->module->core, name, file_path, &scache_idx)) != 0) { + pa_log_error("failed to add file [%s]", file_path); + return; + } + pa_log_debug("success to add file [%s], index [%u]", file_path, scache_idx); + } + + /* Set role type / volume gain of stream */ + p = pa_proplist_new(); + if (!p) { + pa_log_error("failed to create proplist..."); + return; + } + pa_proplist_sets(p, PA_PROP_MEDIA_ROLE, DEFAULT_ROLE); + pa_proplist_sets(p, PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE, DEFAULT_VOLUME_GAIN); + pa_log_debug("role[%s], volume_gain_type[%s]", DEFAULT_ROLE, DEFAULT_VOLUME_GAIN); + + /* Play sample */ + pa_log_debug("pa_scache_play_item() start"); + ret = pa_scache_play_item(u->module->core, name, pa_namereg_get_default_sink(u->module->core), PA_VOLUME_NORM, p, &stream_idx); + if (ret < 0) + pa_log_error("pa_scache_play_item fail, ret[%d]", ret); + else + pa_log_info("pa_scache_play_item() end, stream_idx(%u)", stream_idx); + + /* clean-up */ + pa_proplist_free(p); +} + +static bool _is_mute_sound () { + int setting_sound_status = true; + int setting_touch_sound = true; + + vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &setting_sound_status); + vconf_get_bool(VCONFKEY_SETAPPL_TOUCH_SOUNDS_BOOL, &setting_touch_sound); + + return !(setting_sound_status & setting_touch_sound); +} + +static DBusHandlerResult _dbus_filter_device_detect_handler(DBusConnection *c, DBusMessage *s, void *userdata) { + struct userdata *u = (struct userdata *)userdata; + + pa_assert(u); + + if (dbus_message_get_type(s) != DBUS_MESSAGE_TYPE_SIGNAL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + pa_log_debug("DBus device detect handler received msg"); + pa_log_debug("path : %s", dbus_message_get_path(s)); + pa_log_debug("interface : %s", dbus_message_get_interface(s)); + pa_log_debug("member : %s", dbus_message_get_member(s)); + pa_log_debug("signature : %s", dbus_message_get_signature(s)); + + if (dbus_message_is_signal(s, INTERFACE_NAME, SIGNAL_NAME)) { + if (!_is_mute_sound()) + _hw_keysound_play(u, DBUS_HW_KEYTONE); + else + pa_log_debug("Skip playing keytone due to mute sound mode"); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + pa_log_info("Unknown message, do not handle this"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static int _watch_signals(struct userdata *u) { + DBusError error; + + pa_assert(u); + pa_assert(u->dbus_conn); + + dbus_error_init(&error); + + pa_log_debug("Watch Dbus signals"); + + if (!dbus_connection_add_filter(pa_dbus_connection_get(u->dbus_conn), _dbus_filter_device_detect_handler, u, NULL)) { + pa_log_error("Unable to add D-Bus filter"); + return -1; + } + + if (pa_dbus_add_matches(pa_dbus_connection_get(u->dbus_conn), &error, FILTER_HARDKEY, NULL) < 0) { + pa_log_error("Unable to subscribe to signals: %s: %s", error.name, error.message); + dbus_error_free(&error); + return -1; + } + + return 0; +} + +static void _unwatch_signals(struct userdata *u) { + pa_log_debug("Unwatch Dbus signals"); + + pa_assert(u); + pa_assert(u->dbus_conn); + + pa_dbus_remove_matches(pa_dbus_connection_get(u->dbus_conn), FILTER_HARDKEY, NULL); + dbus_connection_remove_filter(pa_dbus_connection_get(u->dbus_conn), _dbus_filter_device_detect_handler, u); +} + +static int _dbus_init(struct userdata *u) { + DBusError error; + pa_dbus_connection *connection = NULL; + + pa_assert(u); + + dbus_error_init(&error); + + pa_log_debug("Dbus init"); + + if (!(connection = pa_dbus_bus_get(u->module->core, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) { + if (connection) + pa_dbus_connection_unref(connection); + + pa_log_error("Unable to contact D-Bus system bus: %s: %s", error.name, error.message); + dbus_error_free(&error); + return -1; + } + pa_log_debug("Got dbus connection %p", connection); + u->dbus_conn = connection; + + if (_watch_signals(u) < 0) + pa_log_error("dbus watch signals failed"); + else + pa_log_debug("dbus ready to get signals"); + + return 0; +} + +static void _dbus_deinit(struct userdata *u) { + pa_assert(u); + + pa_log_debug("Dbus deinit"); + + _unwatch_signals(u); + + if (u->dbus_conn) { + pa_dbus_connection_unref(u->dbus_conn); + u->dbus_conn = NULL; + } +} + +int pa__init(pa_module *m) { + struct userdata *u; + + pa_assert(m); + + m->userdata = u = pa_xnew0(struct userdata, 1); + u->module = m; + u->dbus_conn = NULL; + + if (_dbus_init(u) == -1) { + pa__done(m); + return -1; + } + return 0; +} + +void pa__done(pa_module *m) { + struct userdata *u; + + pa_assert(m); + + if (!(u = m->userdata)) + return; + + _dbus_deinit(u); + + pa_xfree(u); +} -- 2.7.4 From c395171e391dcf1e5ed0350e8d28d686283e53a6 Mon Sep 17 00:00:00 2001 From: Mok Jeongho Date: Thu, 21 Jul 2016 14:30:12 +0900 Subject: [PATCH 12/16] Do not read unnecessary config Change-Id: Id0cdd6b8f8ab701f878c4e875232dc2a90ce02a7 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager.c | 222 ++++++++++++-------------------- 2 files changed, 81 insertions(+), 143 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index fd64630..03629e3 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.67 +Version: 5.0.68 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager.c b/src/device-manager.c index 05befca..bdef6ac 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -64,13 +64,9 @@ #define DEVICE_TYPE_OBJECT "device-types" #define DEVICE_FILE_OBJECT "device-files" #define DEVICE_TYPE_PROP_DEVICE_TYPE "device-type" -#define DEVICE_TYPE_PROP_BUILTIN "builtin" -#define DEVICE_TYPE_PROP_DIRECTION "direction" -#define DEVICE_TYPE_PROP_AVAIL_CONDITION "avail-conditioin" #define DEVICE_TYPE_PROP_PLAYBACK_DEVICES "playback-devices" #define DEVICE_TYPE_PROP_CAPTURE_DEVICES "capture-devices" #define DEVICE_TYPE_PROP_DEVICE_STRING "device-string" -#define DEVICE_TYPE_PROP_DEFAULT_PARAMS "default-params" #define DEVICE_TYPE_PROP_ROLE "role" #define DEVICE_TYPE_STR_MAX 20 @@ -80,9 +76,6 @@ #define DEVICE_DIRECTION_STR_IN "in" #define DEVICE_DIRECTION_STR_BOTH "both" -#define DEVICE_AVAIL_CONDITION_STR_PULSE "pulse" -#define DEVICE_AVAIL_CONDITION_STR_DBUS "dbus" - /* Properties of sink/sources */ #define DEVICE_API_BLUEZ "bluez" #define DEVICE_API_ALSA "alsa" @@ -423,19 +416,6 @@ struct device_file_info { struct device_type_info { const char *type; const char *profile; - bool builtin; - /* - Possible directions of this device. - ex) speaker is always out, but earjack can be both or out. - */ - dm_device_direction_t direction[DEVICE_DIRECTION_MAX]; - /* - Conditions for make device available. - ex) Speaker be available, only if proper pcm-device exists. - but audio-jack is available, if pcm-device exists and got detected status. - */ - char avail_condition[DEVICE_AVAIL_COND_NUM_MAX][DEVICE_AVAIL_COND_STR_MAX]; - int num; /* For save supported roles and related device-file. { key:role -> value:device_string ] @@ -517,6 +497,19 @@ static uint32_t _new_event_id() { return event_id_max_g++; } +static bool device_type_is_builtin(const char *device_type) { + if (!device_type) + return false; + else if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_MIC)) + return true; + else + return false; +} + static bool device_type_is_valid(const char *device_type) { if (!device_type) return false; @@ -540,6 +533,34 @@ static bool device_type_is_valid(const char *device_type) { return false; } +/* Check whether 'direction' is valid for 'device_type' + * This is static device-type availability, not for runtime checking */ +static bool device_type_is_valid_direction(const char *device_type, const char *device_profile, dm_device_direction_t direction) { + if (!device_type || direction == DM_DEVICE_DIRECTION_NONE) + return false; + + if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) + return direction == DM_DEVICE_DIRECTION_OUT; + else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) + return direction == DM_DEVICE_DIRECTION_OUT; + else if (pa_streq(device_type, DEVICE_TYPE_MIC)) + return direction == DM_DEVICE_DIRECTION_IN; + else if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) + return direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_BOTH; + else if (pa_streq(device_type, DEVICE_TYPE_BT) && pa_streq(device_profile, DEVICE_PROFILE_BT_SCO)) + return direction == DM_DEVICE_DIRECTION_BOTH; + else if (pa_streq(device_type, DEVICE_TYPE_BT) && pa_streq(device_profile, DEVICE_PROFILE_BT_A2DP)) + return direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_IN; + else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) + return direction == DM_DEVICE_DIRECTION_OUT; + else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) + return direction == DM_DEVICE_DIRECTION_BOTH; + else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) + return direction == DM_DEVICE_DIRECTION_BOTH || direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_IN; + else + return false; +} + static const char* device_direction_to_string(dm_device_direction_t direction) { if (direction <= DM_DEVICE_DIRECTION_NONE || direction > DM_DEVICE_DIRECTION_BOTH) { return NULL; @@ -1775,49 +1796,45 @@ static void _device_profile_set_state(dm_device_profile *profile_item, dm_devic static int device_type_get_direction(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *identifier) { struct device_type_info *type_info = NULL; struct device_status_info *status_info; - dm_device_direction_t direction = 0, d_num = 0, d_idx = 0, correct_d_idx = 0; if (!dm || !device_type) { pa_log_error("Invalid Parameter"); return -1; } - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_type, device_profile))) { - pa_log_error("No type map for %s", device_type); + if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) { + return DM_DEVICE_DIRECTION_OUT; + } else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) { + return DM_DEVICE_DIRECTION_OUT; + } else if (pa_streq(device_type, DEVICE_TYPE_MIC)) { + return DM_DEVICE_DIRECTION_IN; + } else if (pa_streq(device_type, DEVICE_TYPE_BT) && pa_streq(device_profile, DEVICE_PROFILE_BT_A2DP)) { return -1; - } - - if (pa_streq(type_info->type, DEVICE_TYPE_FORWARDING)) + } else if (pa_streq(device_type, DEVICE_TYPE_BT) && pa_streq(device_profile, DEVICE_PROFILE_BT_SCO)) { return DM_DEVICE_DIRECTION_BOTH; - - for (d_idx = 0; d_idx < DEVICE_DIRECTION_MAX; d_idx++) { - if (type_info->direction[d_idx] != DM_DEVICE_DIRECTION_NONE) { - correct_d_idx = d_idx; - d_num++; + } else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) { + return DM_DEVICE_DIRECTION_OUT; + } else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) { + return -1; + } else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) { + return DM_DEVICE_DIRECTION_BOTH; + } else if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) { + if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_type, device_profile))) { + pa_log_error("No type map for %s", device_type); + return -1; } - } - - if (d_num == 1) { - direction = type_info->direction[correct_d_idx]; - } else { - /* Actually, only 'audio-jack' should come here */ - if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) { - status_info = _device_manager_get_status_info(dm->device_status, type_info->type, type_info->profile, identifier); - if (status_info->detected_type == DEVICE_DETECTED_AUDIO_JACK_BOTH_DIREC) { - direction = DM_DEVICE_DIRECTION_BOTH; - } else if (status_info->detected_type == DEVICE_DETECTED_AUDIO_JACK_OUT_DIREC) { - direction = DM_DEVICE_DIRECTION_OUT; - } else { - pa_log_debug("Cannot get audio jack device direction"); - return -1; - } + status_info = _device_manager_get_status_info(dm->device_status, type_info->type, type_info->profile, identifier); + if (status_info->detected_type == DEVICE_DETECTED_AUDIO_JACK_BOTH_DIREC) { + return DM_DEVICE_DIRECTION_BOTH; + } else if (status_info->detected_type == DEVICE_DETECTED_AUDIO_JACK_OUT_DIREC) { + return DM_DEVICE_DIRECTION_OUT; } else { - pa_log_error("Weird case, '%s' is not expected to have multiple direction", device_type); + pa_log_debug("Cannot get audio jack device direction"); return -1; } } - return direction; + return -1; } static int pulse_device_get_device_type(void *pulse_device, pa_device_type_t pdt, dm_device_class_t device_class, const char **device_type, const char **device_profile, const char **device_name) { @@ -2258,8 +2275,6 @@ static dm_device* handle_device_type_available(struct device_type_info *type_inf pa_log_debug("handle_device_type_available, type:%s, profile:%s, name:%s", type_info->type, type_info->profile, name); - - /* Directions of some types are not statically defined, ex) earjack */ if ((direction = device_type_get_direction(dm, type_info->type, type_info->profile, NULL)) < 0) { pa_log_error("Failed to get direction of %s.%s", type_info->type, type_info->profile); @@ -2372,21 +2387,8 @@ static void handle_predefined_device_loaded(void *pulse_device, pa_device_type_t } } -static bool _device_type_direction_available(struct device_type_info *type_info, dm_device_direction_t direction) { - int direc_idx; - - for (direc_idx = 0; direc_idx < DEVICE_DIRECTION_MAX; direc_idx++) { - if (type_info->direction[direc_idx] == direction) { - return true; - } - } - - return false; -} - static void handle_sink_unloaded(pa_sink *sink, pa_device_manager *dm) { dm_device_profile *profile_item = NULL; - struct device_type_info *type_info; dm_device *device_item; uint32_t device_idx = 0, profile_idx; pa_sink *sink_iter = NULL; @@ -2428,8 +2430,7 @@ static void handle_sink_unloaded(pa_sink *sink, pa_device_manager *dm) { profile_item->playback_devices = NULL; if (profile_item->direction == DM_DEVICE_DIRECTION_BOTH) { - type_info = _device_manager_get_type_info(dm->type_infos, profile_item->device_item->type, profile_item->profile); - if (_device_type_direction_available(type_info, DM_DEVICE_DIRECTION_IN)) { + if (device_type_is_valid_direction(profile_item->device_item->type, profile_item->profile, DM_DEVICE_DIRECTION_IN)) { profile_item->direction = DM_DEVICE_DIRECTION_IN; } else { if (!destroy_device_profile(profile_item, dm)) @@ -2449,7 +2450,6 @@ static void handle_sink_unloaded(pa_sink *sink, pa_device_manager *dm) { static void handle_source_unloaded(pa_source *source, pa_device_manager *dm) { dm_device_profile *profile_item = NULL; - struct device_type_info *type_info; dm_device *device_item; uint32_t device_idx = 0, profile_idx; pa_source *source_iter = NULL; @@ -2493,8 +2493,7 @@ static void handle_source_unloaded(pa_source *source, pa_device_manager *dm) { profile_item->capture_devices = NULL; if (profile_item->direction == DM_DEVICE_DIRECTION_BOTH) { - type_info = _device_manager_get_type_info(dm->type_infos, profile_item->device_item->type, profile_item->profile); - if (_device_type_direction_available(type_info, DM_DEVICE_DIRECTION_OUT)) { + if (device_type_is_valid_direction(profile_item->device_item->type, profile_item->profile, DM_DEVICE_DIRECTION_OUT)) { profile_item->direction = DM_DEVICE_DIRECTION_OUT; } else { if (!destroy_device_profile(profile_item, dm)) @@ -2504,7 +2503,6 @@ static void handle_source_unloaded(pa_source *source, pa_device_manager *dm) { if (!destroy_device_profile(profile_item, dm)) break; } - } else { _device_profile_update_direction(profile_item); } @@ -2799,8 +2797,6 @@ static int load_builtin_devices(pa_device_manager *dm) { } } - - if (dm->file_map->capture) { PA_IDXSET_FOREACH(file_info, dm->file_map->capture, file_idx) { pa_log_debug("---------------- load source for '%s' ------------------", file_info->device_string); @@ -2891,7 +2887,7 @@ static struct device_file_info* parse_device_file_object(json_object *device_fil pa_assert(device_string_key); pa_assert(json_object_is_type(device_file_o, json_type_object)); - if (json_object_object_get_ex(device_file_o, "device-string", &device_file_prop_o) && json_object_is_type(device_file_prop_o, json_type_string)) { + if (json_object_object_get_ex(device_file_o, DEVICE_TYPE_PROP_DEVICE_STRING, &device_file_prop_o) && json_object_is_type(device_file_prop_o, json_type_string)) { if ((device_string = json_object_get_string(device_file_prop_o))) { pa_log_info("[ Device File - %s ]", device_string); } else { @@ -2981,11 +2977,11 @@ static struct device_file_map *parse_device_file_map() { file_map = pa_xmalloc0(sizeof(struct device_file_map)); if (json_object_object_get_ex(o, DEVICE_FILE_OBJECT, &device_files_o) && json_object_is_type(device_files_o, json_type_object)) { - if (json_object_object_get_ex(device_files_o, "playback-devices", &playback_devices_o)) { + if (json_object_object_get_ex(device_files_o, DEVICE_TYPE_PROP_PLAYBACK_DEVICES, &playback_devices_o)) { pa_log_info("Playback Device Files"); file_map->playback = parse_device_file_array_object(playback_devices_o); } - if (json_object_object_get_ex(device_files_o, "capture-devices", &capture_devices_o)) { + if (json_object_object_get_ex(device_files_o, DEVICE_TYPE_PROP_CAPTURE_DEVICES, &capture_devices_o)) { pa_log_info("Capture Device Files"); file_map->capture = parse_device_file_array_object(capture_devices_o); } @@ -3069,12 +3065,10 @@ static pa_idxset* parse_device_type_infos() { if ((device_o = json_object_array_get_idx(device_array_o, device_type_idx)) && json_object_is_type(device_o, json_type_object)) { json_object *device_prop_o; - json_object *array_item_o; - int array_len, array_idx; const char *device_type = NULL, *device_profile = NULL; type_info = pa_xmalloc0(sizeof(struct device_type_info)); - if (json_object_object_get_ex(device_o, "device-type", &device_prop_o) && json_object_is_type(device_prop_o, json_type_string)) { + if (json_object_object_get_ex(device_o, DEVICE_TYPE_PROP_DEVICE_TYPE, &device_prop_o) && json_object_is_type(device_prop_o, json_type_string)) { device_type = json_object_get_string(device_prop_o); pa_log_info("[ Device - %s ]", device_type); type_info->type = device_type; @@ -3090,56 +3084,12 @@ static pa_idxset* parse_device_type_infos() { pa_log_debug("no device-profile"); } - - if (json_object_object_get_ex(device_o, DEVICE_TYPE_PROP_BUILTIN, &device_prop_o) && json_object_is_type(device_prop_o, json_type_boolean)) { - builtin = json_object_get_boolean(device_prop_o); - pa_log_debug("Builtin : %d", builtin); - type_info->builtin = builtin; - } else { - pa_log_error("Get device prop '%s' failed", DEVICE_TYPE_PROP_BUILTIN); - } - - if (json_object_object_get_ex(device_o, DEVICE_TYPE_PROP_DIRECTION, &device_prop_o) && json_object_is_type(device_prop_o, json_type_array)) { - const char *direction; - array_len = json_object_array_length(device_prop_o); - if ((array_len = json_object_array_length(device_prop_o)) > DEVICE_DIRECTION_MAX) { - pa_log_error("Invalid case, The number of direction is too big (%d)", array_len); - goto failed; - } - for (array_idx = 0; array_idx < array_len; array_idx++) { - if ((array_item_o = json_object_array_get_idx(device_prop_o, array_idx)) && json_object_is_type(array_item_o, json_type_string)) { - direction = json_object_get_string(array_item_o); - pa_log_debug("Direction : %s", direction); - type_info->direction[array_idx] = device_direction_to_int(direction); - } - } - } else { - pa_log_error("Get device prop '%s' failed", DEVICE_TYPE_PROP_DIRECTION); - } - - if (json_object_object_get_ex(device_o, "avail-condition", &device_prop_o) && json_object_is_type(device_prop_o, json_type_array)) { - const char *avail_cond; - if ((array_len = json_object_array_length(device_prop_o)) > DEVICE_AVAIL_COND_NUM_MAX) { - pa_log_error("Invalid case, The number of avail-condition is too big (%d)", array_len); - goto failed; - } - for (array_idx = 0; array_idx < array_len; array_idx++) { - if ((array_item_o = json_object_array_get_idx(device_prop_o, array_idx)) && json_object_is_type(array_item_o, json_type_string)) { - avail_cond = json_object_get_string(array_item_o); - pa_log_debug("avail-condition : %s", avail_cond); - strncpy(type_info->avail_condition[array_idx], avail_cond, DEVICE_AVAIL_COND_STR_MAX); - } - } - } else { - pa_log_error("Get device prop 'avail-condition' failed"); - } - - if (json_object_object_get_ex(device_o, "playback-devices", &device_prop_o) && json_object_is_type(device_prop_o, json_type_object)) { + if (json_object_object_get_ex(device_o, DEVICE_TYPE_PROP_PLAYBACK_DEVICES, &device_prop_o) && json_object_is_type(device_prop_o, json_type_object)) { pa_log_info("Playback Devices"); type_info->playback_devices = parse_device_role_map(device_prop_o); } - if (json_object_object_get_ex(device_o, "capture-devices", &device_prop_o) && json_object_is_type(device_prop_o, json_type_object)) { + if (json_object_object_get_ex(device_o, DEVICE_TYPE_PROP_CAPTURE_DEVICES, &device_prop_o) && json_object_is_type(device_prop_o, json_type_object)) { pa_log_info("Capture Devices"); type_info->capture_devices = parse_device_role_map(device_prop_o); } @@ -3339,6 +3289,9 @@ static pa_idxset* device_type_status_init(pa_idxset *type_infos) { pa_log_warn("Unknown earjack status : %d", earjack_status); } } else if (!compare_device_type(status_info->type, status_info->profile, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO)) { + status_info->detected = DEVICE_NOT_DETECTED; + } else if (!compare_device_type(status_info->type, status_info->profile, DEVICE_TYPE_HDMI, NULL)) { + status_info->detected = DEVICE_NOT_DETECTED; } else if (!compare_device_type(status_info->type, status_info->profile, DEVICE_TYPE_FORWARDING, NULL)) { int miracast_wfd_status = 0; if (vconf_get_bool(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, &miracast_wfd_status) < 0) { @@ -3354,17 +3307,7 @@ static pa_idxset* device_type_status_init(pa_idxset *type_infos) { pa_log_warn("Unknown mirroring status : %d", miracast_wfd_status); } } else { - for (avail_cond_idx = 0, avail_cond_num = 0; avail_cond_idx < DEVICE_AVAIL_COND_NUM_MAX; avail_cond_idx++) { - if (pa_streq(type_info->avail_condition[avail_cond_idx], "")) { - avail_cond_num++; - } - } - if (avail_cond_num == 1 && pa_streq(type_info->avail_condition[correct_avail_cond], DEVICE_AVAIL_CONDITION_STR_PULSE)) { - /* device types which don't need to be detected from other-side, let's just set 'detected'*/ - status_info->detected = DEVICE_DETECTED; - } else { - status_info->detected = DEVICE_NOT_DETECTED; - } + status_info->detected = DEVICE_DETECTED; } pa_log_debug("Set %-17s %s detected", type_info->type, (status_info->detected == DEVICE_DETECTED) ? "" : "not"); @@ -3653,14 +3596,9 @@ static bool device_item_match_for_mask(dm_device *device_item, int device_flags, } } if (need_to_check_for_type) { - struct device_type_info *type_info; - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_item->type, profile_item->profile))) { - pa_log_error("No type_info for %s.%s", device_item->type, profile_item->profile); - return false; - } - if (type_info->builtin && (device_flags & DEVICE_TYPE_INTERNAL_FLAG)) + if (device_type_is_builtin(device_item->type) && (device_flags & DEVICE_TYPE_INTERNAL_FLAG)) return true; - else if (!type_info->builtin && (device_flags & DEVICE_TYPE_EXTERNAL_FLAG)) + else if (!device_type_is_builtin(device_item->type) && (device_flags & DEVICE_TYPE_EXTERNAL_FLAG)) return true; } -- 2.7.4 From 8ad6e26003b768b9350750751027db1264acf47b Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Thu, 11 Aug 2016 13:54:57 +0900 Subject: [PATCH 13/16] tizenaudio-policy, stream-manager: Revise label name for goto statement [Version] 5.0.69 [Profile] Common [Issue Type] Naming Change-Id: If716c01b4f2b94b0f279253f75aa8b1f7ecfed31 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager-volume.c | 8 +-- src/stream-manager.c | 120 ++++++++++++++++---------------- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 03629e3..e8c2c2a 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.68 +Version: 5.0.69 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager-volume.c b/src/stream-manager-volume.c index 6cc6ff0..e1d922f 100644 --- a/src/stream-manager-volume.c +++ b/src/stream-manager-volume.c @@ -94,7 +94,7 @@ static int load_out_volume_conf_file(pa_stream_manager *m) { if (!dict) { pa_log_warn("Loading default volume & gain table from ini file failed"); ret = -1; - goto FAILURE; + goto finish; } } @@ -124,7 +124,7 @@ static int load_out_volume_conf_file(pa_stream_manager *m) { } else { pa_log_error("failed to pa_xmalloc0()"); ret = -1; - goto FAILURE; + goto finish; } if (key) { free(key); @@ -152,7 +152,7 @@ static int load_out_volume_conf_file(pa_stream_manager *m) { } else { pa_log_error("failed to pa_xmalloc0()"); ret = -1; - goto FAILURE; + goto finish; } if (key) { free(key); @@ -160,7 +160,7 @@ static int load_out_volume_conf_file(pa_stream_manager *m) { } } -FAILURE: +finish: if (key) free(key); if (dict) diff --git a/src/stream-manager.c b/src/stream-manager.c index c591342..e9f168b 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -680,7 +680,7 @@ static void handle_set_stream_route_devices(DBusConnection *conn, DBusMessage *m if (sp) { if (!in_device_list && !out_device_list) { pa_log_error("invalid arguments"); - goto FAILURE; + goto fail; } if (sp->idx_route_in_devices) { @@ -717,7 +717,7 @@ static void handle_set_stream_route_devices(DBusConnection *conn, DBusMessage *m } } else { pa_log_error("failed to update, idx_route_in_devices[%p]", sp->idx_route_in_devices); - goto FAILURE; + goto fail; } if (sp->idx_route_out_devices) { @@ -754,18 +754,18 @@ static void handle_set_stream_route_devices(DBusConnection *conn, DBusMessage *m } } else { pa_log_error("failed to update, idx_route_out_devices[%p]", sp->idx_route_out_devices); - goto FAILURE; + goto fail; } pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); } else { pa_log_error("could not find matching client for this parent_id[%u]", id); - goto FAILURE; + goto fail; } pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); return; -FAILURE: +fail: pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); @@ -867,7 +867,7 @@ static void handle_set_volume_level(DBusConnection *conn, DBusMessage *msg, void else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); ret = -1; - goto FAILURE; + goto finish; } if ((ret = set_volume_level_by_type(m, stream_type, type, level))) @@ -875,7 +875,7 @@ static void handle_set_volume_level(DBusConnection *conn, DBusMessage *msg, void else pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); -FAILURE: +finish: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); @@ -912,7 +912,7 @@ static void handle_get_volume_level(DBusConnection *conn, DBusMessage *msg, void else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; + goto finish; } if (get_volume_level_by_type(m, GET_VOLUME_CURRENT_LEVEL, stream_type, type, &level)) { @@ -923,7 +923,7 @@ static void handle_get_volume_level(DBusConnection *conn, DBusMessage *msg, void pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); } -FAILURE: +finish: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); return; @@ -956,7 +956,7 @@ static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg, else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; + goto finish; } if (get_volume_level_by_type(m, GET_VOLUME_MAX_LEVEL, stream_type, type, &level)) { @@ -966,7 +966,7 @@ static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg, pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, &level, DBUS_TYPE_INVALID)); pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); } -FAILURE: +finish: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); return; @@ -999,7 +999,7 @@ static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void stream_type = STREAM_SINK_INPUT; else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; + goto finish; } if (set_volume_mute_by_type(m, stream_type, type, (bool)do_mute)) @@ -1007,7 +1007,7 @@ static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void else pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); -FAILURE: +finish: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); return; @@ -1040,7 +1040,7 @@ static void handle_get_volume_mute(DBusConnection *conn, DBusMessage *msg, void else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; + goto fail; } if (get_volume_mute_by_type(m, stream_type, type, (bool*)&is_muted)) { @@ -1051,7 +1051,7 @@ static void handle_get_volume_mute(DBusConnection *conn, DBusMessage *msg, void pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); } -FAILURE: +fail: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); return; @@ -1084,7 +1084,7 @@ static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *ms else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &dbus_str_none, DBUS_TYPE_INVALID)); pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; + goto fail; } if ((s = (stream_type == STREAM_SINK_INPUT) ? (void*)(m->cur_highest_priority.sink_input) : (void*)(m->cur_highest_priority.source_output))) @@ -1106,7 +1106,7 @@ static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *ms pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR_NO_STREAM], DBUS_TYPE_INVALID)); } -FAILURE: +fail: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); return; @@ -1163,10 +1163,10 @@ static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, v } else { pa_log_error("could not find matching client for this parent_id[%u]", id); pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; + goto fail; } pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); -FAILURE: +fail: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); return; @@ -1192,11 +1192,11 @@ static void handle_update_restriction(DBusConnection *conn, DBusMessage *msg, vo if (handle_restrictions(m, name, value) < 0) { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; + goto fail; } pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); -FAILURE: +fail: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); return; @@ -1409,42 +1409,42 @@ static int init_stream_map(pa_stream_manager *m) { pa_log_debug(" - type : %s", type); } else { pa_log_error("Get type failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_FRAGSIZE_MS, &item_o) && json_object_is_type(item_o, json_type_int)) { l->fragsize_ms = json_object_get_int(item_o); pa_log_debug(" - fragsize-ms : %d", l->fragsize_ms); } else { pa_log_error("Get fragsize-ms failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_TLENGTH_MS, &item_o) && json_object_is_type(item_o, json_type_int)) { l->tlength_ms = json_object_get_int(item_o); pa_log_debug(" - tlength-ms : %d", l->tlength_ms); } else { pa_log_error("Get tlength-ms failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_MINREQ_MS, &item_o) && json_object_is_type(item_o, json_type_int)) { l->minreq_ms = json_object_get_int(item_o); pa_log_debug(" - minreq-ms : %d", l->minreq_ms); } else { pa_log_error("Get minreq-ms failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_PREBUF_MS, &item_o) && json_object_is_type(item_o, json_type_int)) { l->prebuf_ms = json_object_get_int(item_o); pa_log_debug(" - prebuf-ms : %d", l->prebuf_ms); } else { pa_log_error("Get prebuf-ms failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_LATENCY_MAXLENGTH, &item_o) && json_object_is_type(item_o, json_type_int)) { l->maxlength = json_object_get_int(item_o); pa_log_debug(" - maxlength : %d", l->maxlength); } else { pa_log_error("Get maxlength failed"); - goto failed; + goto fail; } pa_hashmap_put(m->latency_infos, (void*)type, l); } @@ -1464,14 +1464,14 @@ static int init_stream_map(pa_stream_manager *m) { pa_log_debug(" - type : %s", type); } else { pa_log_error("Get volume type failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_VOLUME_IS_FOR_HAL, &item_o) && json_object_is_type(item_o, json_type_int)) { v->is_hal_volume_type = (bool)json_object_get_int(item_o); pa_log_debug(" - is-hal-volume : %d", v->is_hal_volume_type); } else { pa_log_error("Get is-hal-volume failed"); - goto failed; + goto fail; } pa_hashmap_put(m->volume_infos, (void*)type, v); } @@ -1492,42 +1492,42 @@ static int init_stream_map(pa_stream_manager *m) { pa_log_debug(" - role : %s", role); } else { pa_log_error("Get stream role failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_PRIORITY, &item_o) && json_object_is_type(item_o, json_type_int)) { s->priority = json_object_get_int(item_o); pa_log_debug(" - priority : %d", s->priority); } else { pa_log_error("Get stream priority failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_ROUTE_TYPE, &item_o) && json_object_is_type(item_o, json_type_string)) { if (convert_route_type(&(s->route_type), json_object_get_string(item_o))) { pa_log_error("convert stream route-type failed"); - goto failed; + goto fail; } pa_log_debug(" - route-type : %d", s->route_type); } else { pa_log_error("Get stream route-type failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_VOLUME_TYPES, &sub_array_o) && json_object_is_type(sub_array_o, json_type_object)) { if (json_object_object_get_ex(sub_array_o, STREAM_MAP_STREAM_VOLUME_TYPE_IN, &item_o) && json_object_is_type(item_o, json_type_string)) s->volume_types[STREAM_DIRECTION_IN] = json_object_get_string(item_o); else { pa_log_error("Get stream volume-type-in failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(sub_array_o, STREAM_MAP_STREAM_VOLUME_TYPE_OUT, &item_o) && json_object_is_type(item_o, json_type_string)) s->volume_types[STREAM_DIRECTION_OUT] = json_object_get_string(item_o); else { pa_log_error("Get stream volume-type-out failed"); - goto failed; + goto fail; } pa_log_debug(" - volume-types : in[%s], out[%s]", s->volume_types[STREAM_DIRECTION_IN], s->volume_types[STREAM_DIRECTION_OUT]); } else { pa_log_error("Get stream volume-types failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_AVAIL_IN_DEVICES, &sub_array_o) && json_object_is_type(sub_array_o, json_type_array)) { j = 0; @@ -1542,7 +1542,7 @@ static int init_stream_map(pa_stream_manager *m) { } } else { pa_log_error("Get stream avail-in-devices failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_AVAIL_OUT_DEVICES, &sub_array_o) && json_object_is_type(sub_array_o, json_type_array)) { j = 0; @@ -1557,7 +1557,7 @@ static int init_stream_map(pa_stream_manager *m) { } } else { pa_log_error("Get stream avail-out-devices failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(array_item_o, STREAM_MAP_STREAM_AVAIL_FRAMEWORKS, &sub_array_o) && json_object_is_type(sub_array_o, json_type_array)) { j = 0; @@ -1572,20 +1572,20 @@ static int init_stream_map(pa_stream_manager *m) { } } else { pa_log_error("Get stream avail-frameworks failed"); - goto failed; + goto fail; } pa_hashmap_put(m->stream_infos, (void*)role, s); } } } else { pa_log_error("Get streams object failed"); - goto failed; + goto fail; } dump_stream_map(m); return 0; -failed: +fail: pa_log_error("failed to initialize stream-map"); if (m->stream_infos) { PA_HASHMAP_FOREACH(s, m->stream_infos, state) { @@ -2408,7 +2408,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream /* set it to null sink/source */ if (is_new_data) SET_NEW_DATA_STREAM_TO_NULL_SINK_SOURCE(m, stream, type); - goto FAILURE; + goto finish; } if (command == PROCESS_COMMAND_PREPARE) { @@ -2449,7 +2449,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream /* skip roles */ if (check_role_to_skip(m, role)) { result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } } /* update the priority of this stream */ @@ -2457,14 +2457,14 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream if (ret == false) { pa_log_error("could not update the priority of '%s' role.", role); result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; + goto finish; } /* update the route type of this stream */ ret = update_route_type_of_stream(m, stream, type, role); if (ret == false) { pa_log_error("could not update the route type of '%s' role.", role); result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; + goto finish; } /* update the volume type of this stream */ ret = update_volume_type_of_stream(m, stream, type, role); @@ -2475,7 +2475,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream if ((route_type_str = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE))) { if (check_route_type_to_skip(command, route_type_str)) { result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } } @@ -2503,13 +2503,13 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream /* skip roles */ if (check_role_to_skip(m, role)) { result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } /* skip route types */ if (check_route_type_to_skip(command, route_type_str)) { result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } if (!is_new_data) { @@ -2518,7 +2518,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream if (ret == false) { pa_log_error("could not update the priority of '%s' role.", role); result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; + goto finish; } } @@ -2532,7 +2532,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream if (ret == false) { pa_log_error("could not update the highest priority stream"); result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } /* need to skip if this stream does not belong to internal device */ @@ -2565,14 +2565,14 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream /* skip roles */ if (check_role_to_skip(m, role)) { result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } /* skip route types */ if ((route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE))) { if (check_route_type_to_skip(command, route_type_str)) { result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } } @@ -2580,7 +2580,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream if (pa_proplist_get(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_PRIORITY, (const void**)&prior_priority, &size)) { pa_log_debug("it has already been processed for PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, skip it.."); result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } pa_proplist_unset(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_PRIORITY); @@ -2588,7 +2588,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream if (ret == false) { pa_log_error("could not update the highest priority stream"); result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; + goto finish; } do_notify(m, NOTIFY_COMMAND_INFORM_STREAM_DISCONNECTED, type, false, stream); @@ -2608,14 +2608,14 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream /* skip roles */ if (check_role_to_skip(m, role)) { result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } /* skip route types */ if ((route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE))) { if (check_route_type_to_skip(command, route_type_str)) { result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } } @@ -2623,7 +2623,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream if (ret == false) { pa_log_error("could not update the highest priority stream"); result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; + goto finish; } /* need to skip if this stream does not belong to internal device */ @@ -2656,14 +2656,14 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream /* skip roles */ if (check_role_to_skip(m, role)) { result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } /* skip route types */ if ((route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE))) { if (check_route_type_to_skip(command, route_type_str)) { result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; + goto finish; } } @@ -2694,7 +2694,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream update_buffer_attribute(m, stream, type, is_new_data); } -FAILURE: +finish: pa_log_debug("<<< process_stream(%s): result(%d), stream(%p)", process_command_type_str[command], result, stream); return result; } -- 2.7.4 From e232cdcd1c391e977a68143ed314f5cf32b7bfdb Mon Sep 17 00:00:00 2001 From: Seungbae Shin Date: Wed, 7 Sep 2016 20:48:07 +0900 Subject: [PATCH 14/16] Fix for SVACE defects [Version] 5.0.70 [Profile] Common [Issue Type] SVACE Change-Id: I1ad7cb0d45ed01dd2f9f522b0ed911609218af4b --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager.c | 6 ++---- src/module-tizenaudio-policy.c | 5 ++++- src/subscribe-observer.c | 6 ++---- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index e8c2c2a..df84175 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.69 +Version: 5.0.70 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager.c b/src/device-manager.c index bdef6ac..3ca5831 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -4071,10 +4071,8 @@ pa_source* pa_device_manager_get_source(dm_device *device_item, const char *role if ((source = pa_hashmap_get(profile_item->capture_devices, role))) pa_log_debug("Got source[%s] for [%s] role", source->name, role); - else { - source = pa_hashmap_get(profile_item->capture_devices, DEVICE_ROLE_NORMAL); - pa_log_debug("Could not get source for [%s] role. so get source[%s] for normal role", role, source->name); - } + else + pa_log_warn("Could not get source for [%s] role", role); return source; } diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index 6db0eb0..9caedc7 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -740,7 +740,10 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ pa_log_info("[ROUTE][AUTO_ALL] found the combine_sink already existed"); } else if (data->stream_type == STREAM_SINK_INPUT && !combine_sink_arg1) { sink = combine_sink_arg1 = pa_device_manager_get_sink(device, data->device_role); - pa_log_debug("[ROUTE][AUTO_ALL] combine_sink_arg1[%s], combine_sink_arg2[%p]", sink->name, combine_sink_arg2); + if (sink) + pa_log_debug("[ROUTE][AUTO_ALL] combine_sink_arg1[%s], combine_sink_arg2[%p]", sink->name, combine_sink_arg2); + else + pa_log_error("[ROUTE][AUTO_ALL] could not get sink from pa_device_manager_get_sink"); } else if (data->stream_type == STREAM_SINK_INPUT && !combine_sink_arg2) { sink = combine_sink_arg2 = pa_device_manager_get_sink(device, data->device_role); if (sink && !pa_streq(sink->name, combine_sink_arg1->name)) { diff --git a/src/subscribe-observer.c b/src/subscribe-observer.c index 21a6576..5db7fa9 100644 --- a/src/subscribe-observer.c +++ b/src/subscribe-observer.c @@ -98,12 +98,10 @@ static int convert_event_type_to_name(pa_tizen_event_t event_type, const char ** if (event_type < 0 || event_type >= PA_TIZEN_EVENT_MAX) return -1; - if (event_type == PA_TIZEN_EVENT_DEVICE_CONNECTION_CHANGED) { + if (event_type == PA_TIZEN_EVENT_DEVICE_CONNECTION_CHANGED) *event_name = EVENT_NAME_DEVICE_DISCONNECTED; - return 0; - } - return -1; + return 0; } uint32_t subscriber_hash_func(const void *p) { -- 2.7.4 From 7d81af38e5f0fc406edb1baaa569d2a130c0b6de Mon Sep 17 00:00:00 2001 From: Mok Jeongho Date: Thu, 11 Aug 2016 17:35:38 +0900 Subject: [PATCH 15/16] device manager refactoring and enhancement device manager refactoring - divide pa_tz_device and it's interfaces to tizen-device - adopt new_data concept for pa_tz_device - divide some definitions and static property of device-types to tizen-device-def bt enhancement - support multi-device per profile - deal with call/media option on/off - sco control(open/close/etc) on pa_tz_device(type=bt) [Version] 5.0.71 [Profile] Common [Issue Type] Refactoring Change-Id: I06c07eaf67e0662b97a26dd9fa874d83c37f5ba2 --- Makefile.am | 2 +- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager.c | 3948 +++++++++++-------------------- src/device-manager.h | 95 +- src/module-tizenaudio-policy.c | 251 +- src/stream-manager.c | 46 +- src/subscribe-observer.c | 3 +- src/subscribe-observer.h | 2 + src/tizen-device-def.c | 262 ++ src/tizen-device-def.h | 70 + src/tizen-device.c | 1365 +++++++++++ src/tizen-device.h | 208 ++ 12 files changed, 3485 insertions(+), 2769 deletions(-) create mode 100644 src/tizen-device-def.c create mode 100644 src/tizen-device-def.h create mode 100644 src/tizen-device.c create mode 100644 src/tizen-device.h diff --git a/Makefile.am b/Makefile.am index 157bfac..7421ffb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -92,7 +92,7 @@ module_tizenaudio_policy_la_SOURCES = \ src/stream-manager.c src/stream-manager.h src/stream-manager-priv.h \ src/stream-manager-volume.c src/stream-manager-volume.h src/stream-manager-volume-priv.h \ src/stream-manager-restriction.c src/stream-manager-restriction-priv.h \ - src/device-manager.c src/device-manager.h \ + src/device-manager.c src/device-manager.h src/tizen-device.c src/tizen-device.h src/tizen-device-def.c src/tizen-device-def.h \ src/subscribe-observer.c src/subscribe-observer.h module_tizenaudio_policy_la_LDFLAGS = $(MODULE_LDFLAGS) -L$(pulsemodlibexecdir) module_tizenaudio_policy_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(VCONF_LIBS) $(INIPARSER_LIBS) $(LIBJSON_LIBS) libhal-interface.la diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index df84175..54d30b1 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.70 +Version: 5.0.71 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager.c b/src/device-manager.c index 3ca5831..4cd9abb 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include #include @@ -60,6 +62,9 @@ #define DEVICE_AVAIL_COND_STR_MAX 6 #define DEVICE_FILE_PER_TYPE_MAX 4 #define DEVICE_FILE_STRING_MAX 4 +#define DEVICE_TYPE_STR_MAX 20 +#define DEVICE_PROFILE_STR_MAX 5 +#define DEVICE_ROLE_STR_MAX 15 #define DEVICE_TYPE_OBJECT "device-types" #define DEVICE_FILE_OBJECT "device-files" @@ -71,11 +76,6 @@ #define DEVICE_TYPE_STR_MAX 20 -#define DEVICE_DIRECTION_STR_NONE "none" -#define DEVICE_DIRECTION_STR_OUT "out" -#define DEVICE_DIRECTION_STR_IN "in" -#define DEVICE_DIRECTION_STR_BOTH "both" - /* Properties of sink/sources */ #define DEVICE_API_BLUEZ "bluez" #define DEVICE_API_ALSA "alsa" @@ -209,23 +209,10 @@ static const char* const valid_alsa_device_modargs[] = { NULL }; - - /* A macro to ease iteration through all entries */ #define PA_HASHMAP_FOREACH_KEY(e, h, state, key) \ for ((state) = NULL, (e) = pa_hashmap_iterate((h), &(state), (const void**)&(key)); (e); (e) = pa_hashmap_iterate((h), &(state), (const void**)&(key))) -#define PA_DEVICE(pulse_device, pdt) \ - pdt == PA_DEVICE_TYPE_SINK ? ((pa_sink *) pulse_device) : ((pa_source *) pulse_device) - -#define PA_DEVICES(core, pdt) \ - pdt == PA_DEVICE_TYPE_SINK ? (((pa_core *) core)->sinks) : (((pa_core *) core)->sources) - -#define MAKE_SINK(s) ((pa_sink*) (s)) -#define MAKE_SOURCE(s) ((pa_source*) (s)) - -#define COMPOUND_STATE(d) (((dm_device_profile*)d)->playback_state | ((dm_device_profile*)d)->capture_state) - #define BT_CVSD_CODEC_ID 1 // narrow-band #define BT_MSBC_CODEC_ID 2 // wide-band /* @@ -261,17 +248,14 @@ typedef enum external_value_hdmi_type { device_detected_type_t is needed to distinguish detected device-types ( ex. earjack which can be out or both way) So If you just want to know whether detected or not, can device_detected_t as mask. */ -typedef enum device_detected { - DEVICE_NOT_DETECTED = 0x00, - DEVICE_DETECTED = 0x01, -} device_detected_t; typedef enum device_detected_type { - DEVICE_DETECTED_BT_SCO = DEVICE_DETECTED, - DEVICE_DETECTED_FORWARDING = DEVICE_DETECTED, - DEVICE_DETECTED_HDMI = DEVICE_DETECTED, - DEVICE_DETECTED_AUDIO_JACK_BOTH_DIREC = DEVICE_DETECTED | 0x2, - DEVICE_DETECTED_AUDIO_JACK_OUT_DIREC = DEVICE_DETECTED | 0x4, + DEVICE_DISCONNECTED = 0x0, + DEVICE_CONNECTED = 0x1, + DEVICE_CONNECTED_AUDIO_JACK_4P = DEVICE_CONNECTED | 0x2, + DEVICE_CONNECTED_AUDIO_JACK_3P = DEVICE_CONNECTED | 0x4, + DEVICE_CONNECTED_SCO = DEVICE_CONNECTED | 0x8, + DEVICE_OPENED_SCO = DEVICE_CONNECTED | 0xF, } device_detected_type_t; typedef enum dm_device_class_type { @@ -302,56 +286,6 @@ typedef enum { } device_flags_type_t; -/************* structures for represent device items can be connected/disconnected */ -/* - Before beginning, There are two structure(dm_device, dm_device_profile) - for represent device by following reasons. - When bt-a2dp and bt-sco are on physically same device ,it is of course same device. - So those physically same device item are represended by dm_device, - and each profile is represented by dm_device_profile. -*/ - - -/* - Structure to represent physicall device. - This is profile known data-structure, which means it can have multiple profiles ( ex. bt-a2dp and sco) -*/ -struct dm_device { - uint32_t id; - char *type; - char *name; - const char *identifier; - - /* Indicate currently activated profile */ - uint32_t active_profile; - /* include profile_items(dm_device_profile) , currently has only one item except bt case*/ - pa_idxset *profiles; - - pa_device_manager *dm; -}; - -/* - Structure to represent each device profile (subtype). - Even if both-way device(earjack, sco..) , one device_profile. -*/ -typedef struct dm_device_profile { - char *profile; - dm_device_direction_t direction; - dm_device_state_t playback_state; - dm_device_state_t capture_state; - - /* Can get proper sink/source in hashmaps with key(=device_role) */ - pa_hashmap *playback_devices; - pa_hashmap *capture_devices; - - /* device belongs to */ - dm_device *device_item; - - /* creation time */ - pa_usec_t creation_time; - -} dm_device_profile; - /* Structure to save parsed information about device-file. */ @@ -361,33 +295,6 @@ struct device_file_map { pa_idxset *capture; }; -struct pa_device_manager { - PA_REFCNT_DECLARE; - - pa_core *core; - pa_hook_slot *sink_put_hook_slot, *sink_state_changed_slot, *sink_unlink_hook_slot; - pa_hook_slot *source_put_hook_slot, *source_state_changed_slot, *source_unlink_hook_slot; - pa_communicator *comm; - - /* - Idxset for save parsed information about device-type. - { device_type_info } - */ - pa_idxset *type_infos; - /* For save Parsed information about device-file */ - struct device_file_map *file_map; - - /* device list */ - pa_idxset *device_list; - /* - Hashmap for save statuses got through dbus. - { key:device_type -> value:(audio_detected_type_t or device_detected_t) } - */ - pa_idxset *device_status; - pa_dbus_connection *dbus_conn; - dm_device_bt_sco_status_t bt_sco_status; -}; - /***************** structures for static information get from json *********/ /* @@ -425,12 +332,12 @@ struct device_type_info { }; struct device_status_info { - const char *type; - const char *profile; + char *type; + char *profile; + char *name; /* Identify devices among same device-types (for multi-device), currently not works*/ - const char *identifier; - device_detected_t detected; - device_detected_type_t detected_type; + char *system_id; + device_detected_type_t detected; }; struct pulse_device_prop { @@ -440,9 +347,39 @@ struct pulse_device_prop { int status; }; /******************************************************************************/ +struct pa_device_manager { + PA_REFCNT_DECLARE; + + pa_core *core; + pa_hook_slot *sink_put_hook_slot, *sink_state_changed_slot, *sink_unlink_hook_slot; + pa_hook_slot *source_put_hook_slot, *source_state_changed_slot, *source_unlink_hook_slot; + pa_hook_slot *comm_hook_device_connection_changed_slot, *comm_hook_device_info_changed_slot; + pa_communicator *comm; + + /* + Idxset for save parsed information about device-type. + { device_type_info } + */ + pa_idxset *type_infos; + /* For save Parsed information about device-file */ + struct device_file_map *file_map; + + /* device list */ + pa_idxset *device_list; + /* + Hashmap for save statuses got through dbus. + { key:device_type -> value:(audio_detected_type_t or device_detected_t) } + */ + pa_idxset *device_status; + pa_dbus_connection *dbus_conn; +}; -int device_id_max_g = 1; -uint32_t event_id_max_g = 1; + +struct composite_type { + const char *type; + const char *profile; + const char *role; +}; #ifdef HAVE_DBUS @@ -453,11 +390,6 @@ static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, vo static void handle_load_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void notify_device_connection_changed(dm_device *device_item, bool connected, pa_device_manager *dm); -static void notify_device_info_changed(dm_device *device_item, dm_device_changed_info_t changed_type, pa_device_manager *dm); - -static int method_call_bt_sco(DBusConnection *conn, bool onoff); -static int method_call_bt_sco_get_property(DBusConnection *conn, bool *is_wide_band, bool *nrec); static int method_call_bt_get_name(DBusConnection *conn, const char *device_path, char **name); enum method_handler_index { @@ -493,130 +425,6 @@ enum signal_index { #endif -static uint32_t _new_event_id() { - return event_id_max_g++; -} - -static bool device_type_is_builtin(const char *device_type) { - if (!device_type) - return false; - else if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) - return true; - else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) - return true; - else if (pa_streq(device_type, DEVICE_TYPE_MIC)) - return true; - else - return false; -} - -static bool device_type_is_valid(const char *device_type) { - if (!device_type) - return false; - else if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) - return true; - else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) - return true; - else if (pa_streq(device_type, DEVICE_TYPE_MIC)) - return true; - else if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) - return true; - else if (pa_streq(device_type, DEVICE_TYPE_BT)) - return true; - else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) - return true; - else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) - return true; - else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) - return true; - else - return false; -} - -/* Check whether 'direction' is valid for 'device_type' - * This is static device-type availability, not for runtime checking */ -static bool device_type_is_valid_direction(const char *device_type, const char *device_profile, dm_device_direction_t direction) { - if (!device_type || direction == DM_DEVICE_DIRECTION_NONE) - return false; - - if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) - return direction == DM_DEVICE_DIRECTION_OUT; - else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) - return direction == DM_DEVICE_DIRECTION_OUT; - else if (pa_streq(device_type, DEVICE_TYPE_MIC)) - return direction == DM_DEVICE_DIRECTION_IN; - else if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) - return direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_BOTH; - else if (pa_streq(device_type, DEVICE_TYPE_BT) && pa_streq(device_profile, DEVICE_PROFILE_BT_SCO)) - return direction == DM_DEVICE_DIRECTION_BOTH; - else if (pa_streq(device_type, DEVICE_TYPE_BT) && pa_streq(device_profile, DEVICE_PROFILE_BT_A2DP)) - return direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_IN; - else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) - return direction == DM_DEVICE_DIRECTION_OUT; - else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) - return direction == DM_DEVICE_DIRECTION_BOTH; - else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) - return direction == DM_DEVICE_DIRECTION_BOTH || direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_IN; - else - return false; -} - -static const char* device_direction_to_string(dm_device_direction_t direction) { - if (direction <= DM_DEVICE_DIRECTION_NONE || direction > DM_DEVICE_DIRECTION_BOTH) { - return NULL; - } - - if (direction == DM_DEVICE_DIRECTION_NONE) - return DEVICE_DIRECTION_STR_NONE; - else if (direction == DM_DEVICE_DIRECTION_OUT) - return DEVICE_DIRECTION_STR_OUT; - else if (direction == DM_DEVICE_DIRECTION_IN) - return DEVICE_DIRECTION_STR_IN; - else if (direction == DM_DEVICE_DIRECTION_BOTH) - return DEVICE_DIRECTION_STR_BOTH; - else - return NULL; -} - -static bool device_role_is_valid(const char *device_role) { - if (!device_role) - return false; - else if (pa_streq(device_role, DEVICE_ROLE_NORMAL)) - return true; - else if (pa_streq(device_role, DEVICE_ROLE_CALL_VOICE)) - return true; - else if (pa_streq(device_role, DEVICE_ROLE_CALL_VIDEO)) - return true; - else if (pa_streq(device_role, DEVICE_ROLE_VOIP)) - return true; - else if (pa_streq(device_role, DEVICE_ROLE_LOW_LATENCY)) - return true; - else if (pa_streq(device_role, DEVICE_ROLE_HIGH_LATENCY)) - return true; - else if (pa_streq(device_role, DEVICE_ROLE_UHQA)) - return true; - else - return false; -} - -static dm_device_direction_t device_direction_to_int(const char *device_direction) { - if (!device_direction) { - return -1; - } - - if (pa_streq(device_direction, DEVICE_DIRECTION_STR_NONE)) { - return DM_DEVICE_DIRECTION_NONE; - } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_OUT)) { - return DM_DEVICE_DIRECTION_OUT; - } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_IN)) { - return DM_DEVICE_DIRECTION_IN; - } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_BOTH)) { - return DM_DEVICE_DIRECTION_BOTH; - } else { - return -1; - } -} - static void type_info_free_func(struct device_type_info *type_info) { if (!type_info) return; @@ -636,74 +444,56 @@ static void file_info_free_func(struct device_file_info *file_info) { pa_hashmap_free(file_info->roles); } -static void profile_item_free_func(dm_device_profile *profile_item) { - if (!profile_item) - return; - - if (profile_item->profile) { - pa_xfree(profile_item->profile); +static dm_device_class_t device_string_get_class(const char *device_string) { + if (!device_string) { + return DM_DEVICE_CLASS_NONE; } - if (profile_item->playback_devices) { - pa_hashmap_free(profile_item->playback_devices); - } - if (profile_item->capture_devices) { - pa_hashmap_free(profile_item->capture_devices); + if (device_string == strstr(device_string, "alsa")) { + return DM_DEVICE_CLASS_ALSA; + } else if (device_string == strstr(device_string, "null")) { + return DM_DEVICE_CLASS_NULL; + } else if (device_string == strstr(device_string, "tizen")) { + return DM_DEVICE_CLASS_TIZEN; + } else { + return DM_DEVICE_CLASS_NONE; } - - profile_item->device_item = NULL; - - pa_xfree(profile_item); } -static void device_item_free_func(dm_device *device_item) { - if (!device_item) - return; - - if (device_item->type) - pa_xfree(device_item->type); - if (device_item->name) - pa_xfree(device_item->name); - if (device_item->profiles) - pa_idxset_free(device_item->profiles, (pa_free_cb_t)profile_item_free_func); - - pa_xfree(device_item); -} +static const char* device_string_get_value(const char *device_string) { + int len; + const char *end_p, *value_p; -static pa_proplist* pulse_device_get_proplist(void *pulse_device, pa_device_type_t pdt) { - if (pdt == PA_DEVICE_TYPE_SINK) - return MAKE_SINK(pulse_device)->proplist; - else - return MAKE_SOURCE(pulse_device)->proplist; -} + if (!device_string) { + return NULL; + } -static pa_core* pulse_device_get_core(void *pulse_device, pa_device_type_t pdt) { - if (pdt == PA_DEVICE_TYPE_SINK) - return MAKE_SINK(pulse_device)->core; - else - return MAKE_SOURCE(pulse_device)->core; -} + len = strlen(device_string); + end_p = device_string + len -1; -static char* pulse_device_get_name(void *pulse_device, pa_device_type_t pdt) { - if (pdt == PA_DEVICE_TYPE_SINK) - return MAKE_SINK(pulse_device)->name; - else - return MAKE_SOURCE(pulse_device)->name; + if (!(value_p = strchr(device_string, ':'))) { + return NULL; + } + if (value_p < end_p) { + return value_p + 1; + } else { + return NULL; + } } -static pa_idxset* pulse_core_get_device_list(pa_core *core, pa_device_type_t pdt) { - if (pdt == PA_DEVICE_TYPE_SINK) - return core->sinks; +static pa_proplist* pulse_device_get_proplist(pa_object *pdevice) { + if (pa_sink_isinstance(pdevice)) + return PA_SINK(pdevice)->proplist; else - return core->sources; + return PA_SOURCE(pdevice)->proplist; } -static bool pulse_device_is_alsa(pa_proplist *prop) { +static bool pulse_device_is_alsa(pa_object *pdevice) { const char *api_name = NULL; + pa_proplist *prop; - if (!prop) { + if ((prop = pulse_device_get_proplist(pdevice)) == NULL) return false; - } if ((api_name = pa_proplist_gets(prop, PA_PROP_DEVICE_API))) { if (pa_streq(api_name, DEVICE_API_ALSA)) { @@ -717,12 +507,12 @@ static bool pulse_device_is_alsa(pa_proplist *prop) { } -static bool pulse_device_is_bluez(pa_proplist *prop) { +static bool pulse_device_is_bluez(pa_object *pdevice) { const char *api_name = NULL; + pa_proplist *prop; - if (!prop) { + if ((prop = pulse_device_get_proplist(pdevice)) == NULL) return false; - } if ((api_name = pa_proplist_gets(prop, PA_PROP_DEVICE_API))) { if (pa_streq(api_name, DEVICE_API_BLUEZ)) { @@ -735,23 +525,25 @@ static bool pulse_device_is_bluez(pa_proplist *prop) { } } -static bool pulse_device_is_tizenaudio(void *pulse_device, pa_device_type_t pdt) { - pa_sink *sink; - - if (!pulse_device) { +static bool pulse_device_is_tizenaudio(pa_object *pdevice) { + if (!pdevice) return false; - } - if (pdt == PA_DEVICE_TYPE_SOURCE) { - return false; + if (pa_sink_isinstance(pdevice)) { + pa_sink *sink = PA_SINK(pdevice); + return pa_streq(sink->module->name, "module-tizenaudio-sink"); + } else { + pa_source *source = PA_SOURCE(pdevice); + return pa_streq(source->module->name, "module-tizenaudio-source"); } - - sink = (pa_sink *) pulse_device; - return pa_streq(sink->module->name, "module-tizenaudio-sink"); } -static bool pulse_device_is_usb(pa_proplist *prop) { +static bool pulse_device_is_usb(pa_object *pdevice) { const char *bus_name = NULL; + pa_proplist *prop; + + if ((prop = pulse_device_get_proplist(pdevice)) == NULL) + return false; if ((bus_name = pa_proplist_gets(prop, PA_PROP_DEVICE_BUS))) { if (pa_streq(bus_name, DEVICE_BUS_USB)) { @@ -765,147 +557,165 @@ static bool pulse_device_is_usb(pa_proplist *prop) { } } -static bool pulse_device_is_null(void *pulse_device, pa_device_type_t pdt) { +static bool pulse_device_is_null(pa_object *pdevice) { pa_sink *sink; pa_source *source; - if (!pulse_device) + if (!pdevice) return false; - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; + if (pa_sink_isinstance(pdevice)) { + sink = PA_SINK(pdevice); return pa_streq(sink->module->name, "module-null-sink"); } else { - source = (pa_source *) pulse_device; - + source = PA_SOURCE(pdevice); return pa_streq(source->module->name, "module-null-source"); } } -static const char* device_class_to_string(dm_device_class_t device_class) { - if (device_class == DM_DEVICE_CLASS_ALSA) { - return "alsa"; - } else if (device_class == DM_DEVICE_CLASS_TIZEN) { - return "tizen"; - } else if (device_class == DM_DEVICE_CLASS_BT) { - return "bt"; - } else if (device_class == DM_DEVICE_CLASS_NULL) { - return "null"; - } else if (device_class == DM_DEVICE_CLASS_NONE) { - return "none"; - } else { - return NULL; - } -} - -static dm_device_class_t device_string_get_class(const char *device_string) { - if (!device_string) { - return DM_DEVICE_CLASS_NONE; - } +static const char* pulse_device_get_device_string_removed_argument(pa_object *pdevice) { + static char removed_param[DEVICE_PARAM_STRING_MAX] = {0,}; + char *device_string_p = NULL; + char *next_p = NULL; + const char *params_p, *params; + char *end_p = NULL; + int len = 0, prev_len = 0; + pa_sink *sink; + pa_source *source; - if (device_string == strstr(device_string, "alsa")) { - return DM_DEVICE_CLASS_ALSA; - } else if (device_string == strstr(device_string, "null")) { - return DM_DEVICE_CLASS_NULL; - } else if (device_string == strstr(device_string, "tizen")) { - return DM_DEVICE_CLASS_TIZEN; + if (pa_sink_isinstance(pdevice)) { + sink = PA_SINK(pdevice); + params = sink->module->argument; } else { - return DM_DEVICE_CLASS_NONE; + source = PA_SOURCE(pdevice); + params = source->module->argument; } -} -static const char* device_string_get_value(const char *device_string) { - int len; - const char *end_p, *value_p; + params_p = params; - if (!device_string) { + if (!params) { return NULL; } + if (!(device_string_p = strstr(params, "device="))) { + return params; + } - len = strlen(device_string); - end_p = device_string + len -1; - - if (!(value_p = strchr(device_string, ':'))) { - return NULL; + next_p = device_string_p; + while (!isblank(*next_p)) { + next_p++; } - if (value_p < end_p) { - return value_p + 1; - } else { - return NULL; + while (isblank(*next_p)) { + next_p++; + } + + strncpy(removed_param, next_p, DEVICE_PARAM_STRING_MAX); + + if (device_string_p > params_p) { + prev_len = device_string_p - params_p; + len = strlen(removed_param); + end_p = removed_param + len; + *end_p = ' '; + end_p++; + strncpy(end_p, params_p, prev_len); } + + return removed_param; } -static dm_device_class_t pulse_device_get_class(void *pulse_device, pa_device_type_t pdt) { - pa_sink *sink = NULL; - pa_source *source = NULL; +static dm_device_class_t pulse_device_get_class(pa_object *pdevice) { - if (!pulse_device) { - pa_log_error("pulse_device null"); + if (!pdevice) { + pa_log_error("pdevice null"); return DM_DEVICE_CLASS_NONE; } - if (pdt == PA_DEVICE_TYPE_SINK) - sink = (pa_sink *) pulse_device; - else - source = (pa_source *) pulse_device; - - if (pulse_device_is_null(pulse_device, pdt)) { + if (pulse_device_is_null(pdevice)) { return DM_DEVICE_CLASS_NULL; - } else if (pulse_device_is_alsa(pdt == PA_DEVICE_TYPE_SINK ? sink->proplist : source->proplist)) { + } else if (pulse_device_is_alsa(pdevice)) { return DM_DEVICE_CLASS_ALSA; - } else if (pulse_device_is_tizenaudio(pulse_device, pdt)) { + } else if (pulse_device_is_tizenaudio(pdevice)) { return DM_DEVICE_CLASS_TIZEN; - } else if (pulse_device_is_bluez(pdt == PA_DEVICE_TYPE_SINK ? sink->proplist : source->proplist)) { + } else if (pulse_device_is_bluez(pdevice)) { return DM_DEVICE_CLASS_BT; } else { return DM_DEVICE_CLASS_NONE; } } -static const char* device_class_get_module_name(dm_device_class_t device_class, pa_device_type_t pdt) { - if (device_class == DM_DEVICE_CLASS_NONE) { - return NULL; - } else if (device_class == DM_DEVICE_CLASS_ALSA) { - return pdt == PA_DEVICE_TYPE_SINK ? "module-alsa-sink" : "module-alsa-source"; - } else if (device_class == DM_DEVICE_CLASS_TIZEN) { - return pdt == PA_DEVICE_TYPE_SINK ? "module-tizenaudio-sink" : NULL; - } else if (device_class == DM_DEVICE_CLASS_BT) { - return pdt == PA_DEVICE_TYPE_SINK ? "module-bluez5-device" : NULL; - } else if (device_class == DM_DEVICE_CLASS_NULL) { - return pdt == PA_DEVICE_TYPE_SINK ? "module-null-sink" : "module-null-source"; - } else { - return NULL; - } +static dm_device_direction_t pulse_device_get_direction(pa_object *pdevice) { + if (pa_sink_isinstance(pdevice)) + return DM_DEVICE_DIRECTION_OUT; + else + return DM_DEVICE_DIRECTION_IN; } -static int compare_device_profile(const char *device_profile1, const char *device_profile2) { - if (!device_profile1 && !device_profile2) { - return 0; - } else if (!device_profile1 || !device_profile2) { - return 1; - } else if (pa_streq(device_profile1, device_profile2)) { - return 0; +static bool pulse_device_is_monitor(pa_object *pdevice) { + const char *device_class = NULL; + pa_proplist *prop; + + prop = pulse_device_get_proplist(pdevice); + + if ((device_class = pa_proplist_gets(prop, PA_PROP_DEVICE_CLASS))) { + if (device_class && pa_streq(device_class, DEVICE_CLASS_MONITOR)) { + return true; + } else { + return false; + } } else { - return 1; + return false; } } -static int compare_device_type(const char *device_type1, const char *device_profile1, const char *device_type2, const char *device_profile2) { - if (!device_type1 || !device_type2) { +static int pulse_device_get_alsa_device_string(pa_proplist *prop, char **device_string) { + const char *device_string_prop = NULL; + char *device_string_tmp; + + if (!prop || !device_string) { + pa_log_error("Invalid Parameter"); + return -1; + } + + if (!(device_string_prop = pa_proplist_gets(prop, "device.string"))) { + pa_log_error("failed to get property 'device.string'"); + return -1; + } + if (!(device_string_tmp = strchr(device_string_prop, ':'))) { + pa_log_error("failed to parse device string"); + return -1; + } + + if (((device_string_tmp + 1) == '\0')) { + pa_log_error("no device string value"); return -1; } - if (pa_streq(device_type1, device_type2)) { - return compare_device_profile(device_profile1, device_profile2); + + *device_string = device_string_tmp + 1; + + return 0; +} + +static const char* device_class_get_module_name(dm_device_class_t device_class, bool is_sink) { + if (device_class == DM_DEVICE_CLASS_NONE) { + return NULL; + } else if (device_class == DM_DEVICE_CLASS_ALSA) { + return is_sink ? "module-alsa-sink" : "module-alsa-source"; + } else if (device_class == DM_DEVICE_CLASS_TIZEN) { + return is_sink ? "module-tizenaudio-sink" : NULL; + } else if (device_class == DM_DEVICE_CLASS_BT) { + return is_sink ? "module-bluez5-device" : NULL; + } else if (device_class == DM_DEVICE_CLASS_NULL) { + return is_sink ? "module-null-sink" : "module-null-source"; + } else { + return NULL; } - return 1; } -static struct device_type_info* _device_manager_get_type_info(pa_idxset *type_infos, const char *device_type, const char *device_profile) { +static struct device_type_info* _device_manager_get_type_info(pa_idxset *type_infos, const char *type, const char *device_profile) { struct device_type_info *type_info; uint32_t type_idx; PA_IDXSET_FOREACH(type_info, type_infos, type_idx) { - if (!compare_device_type(type_info->type, type_info->profile, device_type, device_profile)) { + if (device_type_is_equal(type_info->type, type_info->profile, type, device_profile)) { return type_info; } } @@ -913,32 +723,11 @@ static struct device_type_info* _device_manager_get_type_info(pa_idxset *type_in return NULL; } -static struct device_status_info* _device_manager_get_status_info(pa_idxset *status_infos, const char *device_type, const char *device_profile, const char *identifier) { - struct device_status_info *status_info; - uint32_t status_idx; - - PA_IDXSET_FOREACH(status_info, status_infos, status_idx) { - if (!compare_device_type(status_info->type, status_info->profile, device_type, device_profile)) { - if (!status_info->identifier && !identifier) { - return status_info; - } else if (!status_info->identifier || !identifier) { - continue; - } else if (pa_streq(status_info->identifier, identifier)) { - return status_info; - } else { - continue; - } - } - } - - return NULL; -} - static struct device_file_info* _device_manager_get_file_info(pa_idxset *file_infos, const char *device_string) { struct device_file_info *file_info; uint32_t file_idx; - if (!file_infos) - return NULL; + + pa_assert(file_infos); PA_IDXSET_FOREACH(file_info, file_infos, file_idx) { if (file_info->device_string) { @@ -951,251 +740,218 @@ static struct device_file_info* _device_manager_get_file_info(pa_idxset *file_in return NULL; } -static dm_device* _device_manager_get_device(pa_idxset *device_list, const char *device_type) { - dm_device *device_item; - uint32_t device_idx; - - if (!device_list || !device_type) - return NULL; +static struct device_status_info* _device_status_new(const char *type, const char *profile, + const char *name, const char *system_id) { + struct device_status_info *status_info; - PA_IDXSET_FOREACH(device_item, device_list, device_idx) { - if (pa_streq(device_item->type, device_type)) { - return device_item; - } - } + status_info = (struct device_status_info *) pa_xmalloc0(sizeof(struct device_status_info)); + status_info->type = pa_xstrdup(type); + status_info->profile = pa_xstrdup(profile); + status_info->name = pa_xstrdup(name); + status_info->system_id = pa_xstrdup(system_id); + status_info->detected = DEVICE_DISCONNECTED; - return NULL; + return status_info; } -static dm_device* _device_manager_get_device_with_id(pa_idxset *device_list, uint32_t id) { - dm_device *device_item; - uint32_t idx; - - pa_assert(device_list); +static void _device_status_free(struct device_status_info *status_info) { + if (!status_info) + return ; - PA_IDXSET_FOREACH(device_item, device_list, idx) { - if (device_item->id == id) { - return device_item; - } - } - return NULL; + pa_xfree(status_info->type); + pa_xfree(status_info->profile); + pa_xfree(status_info->name); + pa_xfree(status_info->system_id); + pa_xfree(status_info); } -static char* get_playback_list_str(pa_hashmap *playback_devices) { - pa_sink *sink = NULL; - void *state = NULL; - const char *role; - pa_strbuf *buf; +static struct device_status_info* _get_device_status(pa_device_manager *manager, const char *type, + const char *device_profile, const char *system_id) { + struct device_status_info *status_info = NULL; + uint32_t status_idx; - if (!playback_devices || !pa_hashmap_size(playback_devices)) - return NULL; + pa_assert(manager); + pa_assert(manager->device_status); - buf = pa_strbuf_new(); - pa_strbuf_printf(buf, " Playback device list\n"); - PA_HASHMAP_FOREACH_KEY(sink, playback_devices, state, role) - pa_strbuf_printf(buf, " %-13s -> %s\n", role, sink->name); + PA_IDXSET_FOREACH(status_info, manager->device_status, status_idx) { + if (device_type_is_equal(status_info->type, status_info->profile, type, device_profile)) { + if (device_type_is_avail_multi_device(type)) { + /* if system_id is null, just compare type */ + if (system_id == NULL) + return status_info; + else if (status_info->system_id == NULL) + continue; + else if (pa_streq(status_info->system_id, system_id)) + return status_info; + else + continue; + } else { + return status_info; + } + } + } - return pa_strbuf_tostring_free(buf); + return NULL; } -static char* get_capture_list_str(pa_hashmap *capture_devices) { - pa_source *source = NULL; - void *state = NULL; - const char *role; - pa_strbuf *buf; - - if (!capture_devices || !pa_hashmap_size(capture_devices)) - return NULL; - - buf = pa_strbuf_new(); - pa_strbuf_printf(buf, " Capture device list\n"); - PA_HASHMAP_FOREACH_KEY(source, capture_devices, state, role) - pa_strbuf_printf(buf, " %-13s -> %s\n", role, source->name); - - return pa_strbuf_tostring_free(buf); -} +static const char* _file_infos_get_param(pa_idxset *file_infos, const char *device_string, const char *role) { + struct device_file_info *file_info; + const char *params; -/* Returned string must be freed */ -static char* get_device_profile_info_str(dm_device_profile *profile_item) { - pa_strbuf *buf; - char *playback_str, *capture_str; - if (!profile_item) + if (!(file_info = _device_manager_get_file_info(file_infos, device_string))) { + pa_log_error("No file map for '%s'", device_string); return NULL; + } - buf = pa_strbuf_new(); - pa_strbuf_printf(buf, " Profile : %s\n", pa_strna(profile_item->profile)); - pa_strbuf_printf(buf, " Direction : %s\n", device_direction_to_string(profile_item->direction)); - pa_strbuf_printf(buf, " Is activated : %s\n", pa_yes_no(COMPOUND_STATE(profile_item) == DM_DEVICE_STATE_ACTIVATED)); - playback_str = get_playback_list_str(profile_item->playback_devices); - capture_str = get_capture_list_str(profile_item->capture_devices); - - if (playback_str) - pa_strbuf_puts(buf, playback_str); - if (capture_str) - pa_strbuf_puts(buf, capture_str); - - pa_xfree(playback_str); - pa_xfree(capture_str); + if (!(params = pa_hashmap_get(file_info->roles, role))) + pa_log_error("No params for '%s:%s'", device_string, role); - return pa_strbuf_tostring_free(buf); + return params; } -static char* get_device_info_str(dm_device *device_item) { - pa_strbuf *buf; - dm_device_profile *profile_item = NULL; - uint32_t device_idx = 0; - char *profile_info; - - if (!device_item || !device_item->profiles) - return NULL; - - buf = pa_strbuf_new(); - pa_strbuf_printf(buf, "[Device #%u]\n", device_item->id); - pa_strbuf_printf(buf, " ID : %u\n", device_item->id); - pa_strbuf_printf(buf, " Type : %s\n", device_item->type); - pa_strbuf_printf(buf, " Name : %s\n", device_item->name); - pa_strbuf_printf(buf, " Active Profile : %u\n", device_item->active_profile); - PA_IDXSET_FOREACH(profile_item, device_item->profiles, device_idx) { - pa_strbuf_printf(buf, " (Profile #%u)\n", device_idx); - profile_info = get_device_profile_info_str(profile_item); - if (profile_info) - pa_strbuf_puts(buf, profile_info); - pa_xfree(profile_info); - } - - return pa_strbuf_tostring_free(buf); -} +static device_detected_type_t _device_get_detected(pa_device_manager *manager, const char *type, const char *device_profile, + const char *system_id) { + struct device_status_info *status_info; -static char* get_device_list_str(pa_device_manager *dm) { - dm_device *device_item = NULL; - uint32_t device_idx = 0; - pa_strbuf *buf; - char *device_info; + pa_assert(manager); + pa_assert(manager->device_status); + pa_assert(type); - if (!dm || !dm->device_list) - return NULL; + if (!device_type_is_need_detect(type, device_profile)) + return DEVICE_CONNECTED; - buf = pa_strbuf_new(); - pa_strbuf_printf(buf, "=========== Device List ================\n"); - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - device_info = get_device_info_str(device_item); - if (device_info) - pa_strbuf_puts(buf, device_info); - pa_xfree(device_info); + status_info = _get_device_status(manager, type, device_profile, system_id); + if (!status_info) { + pa_log_info("No status info for type(%s) profile(%s) system_id(%s)", + type, pa_strempty(device_profile), pa_strempty(system_id)); + return DEVICE_DISCONNECTED; } - pa_strbuf_printf(buf, "========================================\n"); - - return pa_strbuf_tostring_free(buf); -} - -static void dump_device_info(dm_device *device_item, pa_log_level_t log_level) { - char *info; - if (!device_item) - return; + pa_log_debug("Get device detected, type(%s) profile(%s) system_id(%s) : %s(%d)", + type, pa_strempty(device_profile), pa_strempty(system_id), + (status_info->detected & DEVICE_CONNECTED) ? "Connected" : "Disconnected", status_info->detected); - if ((info = get_device_info_str(device_item))) { - pa_logl(log_level, "%s", info); - pa_xfree(info); - } + return status_info->detected; } -static void dump_device_list_info(pa_device_manager *dm, pa_log_level_t log_level) { - char *info; +static void _device_set_detected(pa_device_manager *manager, const char *type, const char *device_profile, + const char *name, const char *system_id, device_detected_type_t detected_type) { + struct device_status_info *status_info; - if (!dm || !dm->device_list) - return; + pa_assert(manager); + pa_assert(manager->device_status); + pa_assert(type); - if ((info = get_device_list_str(dm))) { - pa_logl(log_level, "%s", info); - pa_xfree(info); - } -} + if (!device_type_is_need_detect(type, device_profile)) + return ; -static bool pulse_device_class_is_sound(pa_proplist *prop) { - const char *device_class = NULL; + pa_log_info("Set device detected, type(%s) profile(%s) system_id(%s) -> %s(%d)", + type, pa_strempty(device_profile), pa_strempty(system_id), + (detected_type & DEVICE_CONNECTED) ? "Connected" : "Disconnected", detected_type); - if ((device_class = pa_proplist_gets(prop, PA_PROP_DEVICE_CLASS))) { - if (device_class && pa_streq(device_class, DEVICE_CLASS_SOUND)) { - return true; - } else { - return false; + if (detected_type & DEVICE_CONNECTED) { + status_info = _get_device_status(manager, type, device_profile, system_id); + if (!status_info) { + status_info = _device_status_new(type, device_profile, name, system_id); + pa_idxset_put(manager->device_status, status_info, NULL); } + status_info->detected = detected_type; } else { - return false; + status_info = _get_device_status(manager, type, device_profile, system_id); + if (status_info) { + pa_idxset_remove_by_data(manager->device_status, status_info, NULL); + _device_status_free(status_info); + } } } -static bool pulse_device_class_is_monitor(pa_proplist *prop) { - const char *device_class = NULL; +/* return system_id of sco connected/opened bt device */ +static int _device_get_detected_sco(pa_device_manager *manager, device_detected_type_t detected, + char **system_id, char **name) { + struct device_status_info *status_info; + uint32_t status_idx; - if (!prop) { - return false; - } + pa_assert(manager); + pa_assert(manager->device_status); - if ((device_class = pa_proplist_gets(prop, PA_PROP_DEVICE_CLASS))) { - if (device_class && pa_streq(device_class, DEVICE_CLASS_MONITOR)) { - return true; - } else { - return false; - } - } else { - return false; + if (detected != DEVICE_CONNECTED_SCO && detected != DEVICE_OPENED_SCO) { + pa_log_warn("Invalid detected type for sco"); + return -1; } -} -static void* pulse_device_get_opposite_sibling_device(void *pulse_device, pa_device_type_t pdt) { - const char *sysfs_path, *sysfs_path_tmp; - uint32_t device_idx; - void *pulse_device_tmp; - pa_core *core; - pa_assert(pulse_device); - - if (!(sysfs_path = pa_proplist_gets(pulse_device_get_proplist(pulse_device, pdt), "sysfs.path"))) { - pa_log_warn("No sysfs.path for '%s'", pulse_device_get_name(pulse_device, pdt)); - return NULL; + PA_IDXSET_FOREACH(status_info, manager->device_status, status_idx) { + if (device_type_is_equal(status_info->type, status_info->profile, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO)) { + if (status_info->detected == detected) { + if (system_id) + *system_id = status_info->system_id; + if (name) + *name = status_info->name; + return 0; + } + } } - core = pulse_device_get_core(pulse_device, pdt); + return -1; +} - PA_IDXSET_FOREACH(pulse_device_tmp, pulse_core_get_device_list(core, !pdt), device_idx) { - if (!pulse_device_class_is_sound(pulse_device_get_proplist(pulse_device_tmp, !pdt))) - continue; - sysfs_path_tmp = pa_proplist_gets(pulse_device_get_proplist(pulse_device_tmp, !pdt), "sysfs.path"); - if (sysfs_path_tmp && pa_streq(sysfs_path_tmp, sysfs_path)) { - return pulse_device_tmp; +static pa_tz_device* _device_list_get_device(pa_device_manager *manager, const char *type, const char *system_id) { + pa_tz_device *device; + uint32_t idx; + char *_type, *_system_id; + + pa_assert(manager); + pa_assert(manager->device_list); + pa_assert(type); + + PA_IDXSET_FOREACH(device, manager->device_list, idx) { + _type = pa_tz_device_get_type(device); + _system_id = pa_tz_device_get_system_id(device); + if (pa_streq(_type, type)) { + if (device_type_is_avail_multi_device(type)) { + if (system_id == NULL) + return device; + else if (_system_id == NULL) + continue; + else if (pa_streq(_system_id, system_id)) + return device; + else + continue; + } else { + return device; + } } } return NULL; } -static int pulse_device_get_alsa_device_string(pa_proplist *prop, char **device_string) { - const char *device_string_prop = NULL; - char *device_string_tmp; - if (!prop || !device_string) { - pa_log_error("Invalid Parameter"); - return -1; - } +static pa_tz_device* _device_list_get_device_with_id(pa_device_manager *manager, uint32_t id) { + pa_tz_device *device; + uint32_t idx; - if (!(device_string_prop = pa_proplist_gets(prop, "device.string"))) { - pa_log_error("failed to get property 'device.string'"); - return -1; - } - if (!(device_string_tmp = strchr(device_string_prop, ':'))) { - pa_log_error("failed to parse device string"); - return -1; - } + pa_assert(manager); + pa_assert(manager->device_list); - if (((device_string_tmp + 1) == '\0')) { - pa_log_error("no device string value"); - return -1; + PA_IDXSET_FOREACH(device, manager->device_list, idx) { + if (pa_tz_device_get_id(device) == id) { + return device; + } } + return NULL; +} - *device_string = device_string_tmp + 1; +static void dump_device_list_info(pa_device_manager *dm, pa_log_level_t log_level) { + pa_tz_device *device; + uint32_t device_idx; - return 0; + if (!dm || !dm->device_list) + return; + + pa_logl(log_level, "=========== Device List ================\n"); + PA_IDXSET_FOREACH(device, dm->device_list, device_idx) + pa_tz_device_dump_info(device, log_level); + pa_logl(log_level, "========================================\n"); } static const char* build_params_to_load_device(const char *device_string, const char *params, dm_device_class_t device_class) { @@ -1228,93 +984,45 @@ static const char* build_params_to_load_device(const char *device_string, const return (const char*) args; } -static const char* pulse_device_get_device_string_removed_argument(void *pulse_device, pa_device_type_t pdt) { - static char removed_param[DEVICE_PARAM_STRING_MAX] = {0,}; - char *device_string_p = NULL; - char *next_p = NULL; - const char *params_p, *params; - char *end_p = NULL; - int len = 0, prev_len = 0; - pa_sink *sink; - pa_source *source; +static bool device_params_is_equal(const char *params1, const char *params2) { + const char *key = NULL; + const char *value1, *value2; + pa_modargs *modargs1, *modargs2; + void *state = NULL; + bool equal = true; - if (pdt == PA_DEVICE_TYPE_SINK) - sink = (pa_sink *) pulse_device; - else - source = (pa_source *) pulse_device; + if (!params1 && !params2) + return true; + if (!params1 || !params2) + return false; - params = pdt == PA_DEVICE_TYPE_SINK ? sink->module->argument : source->module->argument; - params_p = params; + modargs1 = pa_modargs_new(params1, valid_alsa_device_modargs); + modargs2 = pa_modargs_new(params2, valid_alsa_device_modargs); - if (!params) { - return NULL; - } - if (!(device_string_p = strstr(params, "device="))) { - return params; + if (!modargs1 || !modargs2) { + equal = false; + goto finish; } - next_p = device_string_p; - while (!isblank(*next_p)) { - next_p++; - } - while (isblank(*next_p)) { - next_p++; - } - - strncpy(removed_param, next_p, DEVICE_PARAM_STRING_MAX); - - if (device_string_p > params_p) { - prev_len = device_string_p - params_p; - len = strlen(removed_param); - end_p = removed_param + len; - *end_p = ' '; - end_p++; - strncpy(end_p, params_p, prev_len); - } - - return removed_param; -} - - -static int compare_device_params(const char *params1, const char *params2) { - const char *key = NULL; - const char *value1, *value2; - pa_modargs *modargs1, *modargs2; - void *state = NULL; - int ret = 0; - - if (!params1 && !params2) - return 0; - if (!params1 || !params2) - return -1; - - modargs1 = pa_modargs_new(params1, valid_alsa_device_modargs); - modargs2 = pa_modargs_new(params2, valid_alsa_device_modargs); - - if (!modargs1 || !modargs2) { - ret = 1; - goto end; - } - - for (state = NULL, key = pa_modargs_iterate(modargs1, &state); key; key = pa_modargs_iterate(modargs1, &state)) { - value1 = pa_modargs_get_value(modargs1, key, NULL); - value2 = pa_modargs_get_value(modargs2, key, NULL); - if (!value1 || !value2 || !pa_streq(value1, value2)) { - ret = 1; - goto end; - } + for (state = NULL, key = pa_modargs_iterate(modargs1, &state); key; key = pa_modargs_iterate(modargs1, &state)) { + value1 = pa_modargs_get_value(modargs1, key, NULL); + value2 = pa_modargs_get_value(modargs2, key, NULL); + if (!value1 || !value2 || !pa_streq(value1, value2)) { + equal = false; + goto finish; + } } for (state = NULL, key = pa_modargs_iterate(modargs2, &state); key; key = pa_modargs_iterate(modargs2, &state)) { value1 = pa_modargs_get_value(modargs1, key, NULL); value2 = pa_modargs_get_value(modargs2, key, NULL); if (!value1 || !value2 || !pa_streq(value1, value2)) { - ret = 1; - goto end; + equal = false; + goto finish; } } -end: +finish: if (modargs1) pa_modargs_free(modargs1); @@ -1322,20 +1030,22 @@ end: pa_modargs_free(modargs2); - return ret; + return equal; } -static int compare_device_params_with_module_args(void *pulse_device, pa_device_type_t pdt, const char *params) { +static bool pulse_device_params_is_equal(pa_object *pdevice, const char *params) { const char *removed_module_args; const char *module_args; pa_sink *sink; pa_source *source; - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; + pa_assert(pdevice); + + if (pa_sink_isinstance(pdevice)) { + sink = PA_SINK(pdevice); module_args = sink->module->argument; } else { - source = (pa_source *) pulse_device; + source = PA_SOURCE(pdevice); module_args = source->module->argument; } @@ -1344,31 +1054,23 @@ static int compare_device_params_with_module_args(void *pulse_device, pa_device_ if (!params || !module_args) return -1; - removed_module_args = pulse_device_get_device_string_removed_argument(pulse_device, pdt); - return compare_device_params(params, removed_module_args); + removed_module_args = pulse_device_get_device_string_removed_argument(pdevice); + return device_params_is_equal(params, removed_module_args); } -static const char* pulse_device_get_device_string(void *pulse_device, pa_device_type_t pdt) { +static const char* pulse_device_get_device_string(pa_object *pdevice) { dm_device_class_t device_class; static char device_string[DEVICE_STR_MAX] = {0,}; char *device_string_val = NULL; - pa_sink *sink; - pa_source *source; - - if (!pulse_device) { - pa_log_error("pulse_device null"); - return NULL; - } + pa_proplist *prop; - device_class = pulse_device_get_class(pulse_device, pdt); + pa_assert(pdevice); - if (pdt == PA_DEVICE_TYPE_SINK) - sink = (pa_sink *) pulse_device; - else - source = (pa_source *) pulse_device; + device_class = pulse_device_get_class(pdevice); + prop = pulse_device_get_proplist(pdevice); if (device_class == DM_DEVICE_CLASS_ALSA) { - if (pulse_device_get_alsa_device_string(pdt == PA_DEVICE_TYPE_SINK ? sink->proplist : source->proplist, &device_string_val) < 0) + if (pulse_device_get_alsa_device_string(prop, &device_string_val) < 0) return NULL; snprintf(device_string, DEVICE_STR_MAX, "alsa:%s", device_string_val); return device_string; @@ -1383,1446 +1085,971 @@ static const char* pulse_device_get_device_string(void *pulse_device, pa_device_ } } -/* pulse_device is sink or source */ -static bool pulse_device_same_device_string(void *pulse_device, pa_device_type_t pdt, const char *device_string) { - const char *pulse_device_string; +/* pdevice is sink or source */ +static bool pulse_device_same_device_string(pa_object *pdevice, const char *device_string) { + const char *_device_string; - if (!pulse_device || !device_string) { - return false; - } + pa_assert(pdevice); + pa_assert(device_string); - if (!(pulse_device_string = pulse_device_get_device_string(pulse_device, pdt))) { + if (!(_device_string = pulse_device_get_device_string(pdevice))) return false; - } - return pa_streq(pulse_device_string, device_string); + return pa_streq(_device_string, device_string); } -static int get_profile_priority(const char *device_profile) { - if (!device_profile) { - return 0; - } else if (pa_streq(device_profile, DEVICE_PROFILE_BT_A2DP)) { - return 1; - } else if (pa_streq(device_profile, DEVICE_PROFILE_BT_SCO)) { - return 2; - } else { - return -1; - } -} +static const char* device_type_info_get_role(struct device_type_info *type_info, bool is_playback, const char *device_string) { + pa_hashmap *pcm_devices; + void *state; + const char *role, *_device_string; + dm_device_direction_t direction; -static int compare_profile_priority(const char *device_profile1, const char *device_profile2) { - int priority1, priority2; + pa_assert(type_info); + pa_assert(device_string); - priority1 = get_profile_priority(device_profile1); - priority2 = get_profile_priority(device_profile2); + direction = device_type_get_static_direction(type_info->type, type_info->profile); + if (direction == DM_DEVICE_DIRECTION_NONE) { + pa_log_debug("Not static direction"); + return NULL; + } - if (priority1 > priority2) { - return 1; - } else if (priority1 == priority2) { - return 0; + if (is_playback) { + if (direction == DM_DEVICE_DIRECTION_IN) { + pa_log_debug("Invalid direction"); + return NULL; + } + pcm_devices = type_info->playback_devices; } else { - return -1; + if (direction == DM_DEVICE_DIRECTION_OUT) { + pa_log_debug("Invalid direction"); + return NULL; + } + pcm_devices = type_info->capture_devices; } -} -static dm_device* _device_item_set_active_profile_auto(dm_device *device_item) { - dm_device_profile *profile_item = NULL, *prev_profile_item = NULL; - uint32_t idx, prev_active_profile; - unsigned int device_size; - - if (!device_item || !device_item->profiles) { - pa_log_error("Invalid Parameter"); + if (!pcm_devices) { + pa_log_warn("No %s pcm devices for %s %s", is_playback ? "playback" : "capture", + type_info->type, pa_strempty(type_info->profile)); return NULL; } - prev_active_profile = device_item->active_profile; - - device_size = pa_idxset_size(device_item->profiles); - if (device_size == 1) { - pa_idxset_first(device_item->profiles, &idx); - device_item->active_profile = idx; - } else if (device_size == 0) { - device_item->active_profile = PA_INVALID_INDEX; - return device_item; - } else { - PA_IDXSET_FOREACH(profile_item, device_item->profiles, idx) { - if (prev_profile_item) { - if (compare_profile_priority(profile_item->profile, prev_profile_item->profile) > 0) { - device_item->active_profile = idx; - } - } - prev_profile_item = profile_item; + PA_HASHMAP_FOREACH_KEY(_device_string, pcm_devices, state, role) { + if (pa_streq(_device_string, device_string)) { + return role; } } - /* notify direction changed, if only new added profile is active */ - if ((prev_active_profile != PA_INVALID_INDEX) && (prev_active_profile != device_item->active_profile)) { - pa_log_debug("%s's active profile : %u", device_item->name, device_item->active_profile); - notify_device_info_changed(device_item, DM_DEVICE_CHANGED_INFO_IO_DIRECTION, device_item->dm); - } - - return device_item; + return NULL; } -static dm_device* _device_item_add_profile(dm_device *device_item, dm_device_profile *profile_item, uint32_t *idx, pa_device_manager *dm) { - uint32_t profile_idx; +pa_dynarray* pulse_device_get_belongs_type(pa_object *pdevice, pa_device_manager *dm) { + pa_dynarray *ctypes; + struct composite_type *ctype; + struct device_type_info *type_info; + const char *device_string, *role; + uint32_t type_idx; + pa_device_type_t pdt; - pa_assert(device_item); - pa_assert(device_item->profiles); - pa_assert(profile_item); - pa_assert(dm); + pa_assert(pdevice); + + if (pulse_device_is_monitor(pdevice)) + return NULL; + if (pulse_device_is_usb(pdevice)) + return NULL; + if (pulse_device_is_bluez(pdevice)) + return NULL; - pa_idxset_put(device_item->profiles, profile_item, &profile_idx); - _device_item_set_active_profile_auto(device_item); - profile_item->device_item = device_item; + ctypes = pa_dynarray_new(pa_xfree); - return device_item; -} + if (pa_sink_isinstance(pdevice)) + pdt = PA_DEVICE_TYPE_SINK; + else + pdt = PA_DEVICE_TYPE_SOURCE; + + PA_IDXSET_FOREACH(type_info, dm->type_infos, type_idx) { + device_string = pulse_device_get_device_string(pdevice); + role = device_type_info_get_role(type_info, pdt, device_string); + /* Found type_info which is matching with pulse_device */ + if (role) { + ctype = pa_xmalloc0(sizeof(struct composite_type)); + ctype->type = type_info->type; + ctype->profile = type_info->profile; + ctype->role = role; + pa_dynarray_append(ctypes, ctype); + } + } + if (pa_dynarray_size(ctypes) == 0) { + pa_dynarray_free(ctypes); + ctypes = NULL; + } -static int _device_list_add_device(pa_idxset *device_list, dm_device *device_item, pa_device_manager *dm) { - pa_assert(device_list); - pa_assert(device_item); + return ctypes; +} - if (pa_idxset_put(device_list, device_item, NULL) < 0) - return -1; +static const char* pulse_device_get_device_name(pa_object *pdevice, const char *type) { + pa_proplist *prop; - pa_log_debug("Notify Device connected"); + pa_assert(pdevice); + pa_assert(device_type_is_valid(type)); - return 0; + prop = pulse_device_get_proplist(pdevice); + + if (pa_streq(type, DEVICE_TYPE_USB_AUDIO)) + return pa_proplist_gets(prop, "udev.id"); + else if (pa_streq(type, DEVICE_TYPE_BT)) + return pa_proplist_gets(prop, "bluez.alias"); + else + return NULL; } +static void pulse_device_set_use_internal_codec(pa_object *pdevice, bool use_internal_codec) { + pa_assert(pdevice); -static int _device_list_remove_device(pa_idxset *device_list, dm_device *device_item, pa_device_manager *dm) { - pa_assert(device_list); - pa_assert(device_item); + if (pa_sink_isinstance(pdevice)) { + pa_sink *sink = PA_SINK(pdevice); + sink->use_internal_codec = use_internal_codec; + } else { + pa_source *source = PA_SOURCE(pdevice); + source->use_internal_codec = use_internal_codec; + } +} - if (!pa_idxset_remove_by_data(device_list, device_item, NULL)) - return -1; +/* Get system_id of physical device, if external device */ +static const char* pulse_device_get_system_id(pa_object *pdevice) { + pa_proplist *prop; - return 0; + prop = pulse_device_get_proplist(pdevice); + if (pulse_device_is_usb(pdevice)) + return pa_proplist_gets(prop, "sysfs.path"); + else if (pulse_device_is_bluez(pdevice)) + return pa_proplist_gets(prop, "bluez.path"); + else + return NULL; } -static pa_sink* _device_profile_get_sink(dm_device_profile *profile_item, const char *role) { +static pa_sink* _device_manager_set_default_sink(pa_device_manager *dm, const char *type, const char *device_profile, const char *role) { + pa_tz_device *device; pa_sink *sink; - if (!profile_item || !role || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); + if (!type || !role) { + pa_log_warn("Argument for set_default_sink invalid"); + return NULL; + } + + if (!(device = _device_list_get_device(dm, type, NULL))) { + pa_log_warn("cannot get device item for %s", type); return NULL; } - if (!profile_item->playback_devices) { - pa_log_error("No playback devices"); + if (!(sink = pa_tz_device_get_sink(device, role))) { + pa_log_warn("cannot get sink for %s", role); return NULL; } - sink = pa_hashmap_get(profile_item->playback_devices, role); + sink = pa_namereg_set_default_sink(dm->core, sink); return sink; } -static pa_source* _device_profile_get_source(dm_device_profile *profile_item, const char *role) { +static pa_source* _device_manager_set_default_source(pa_device_manager *dm, const char *type, const char *device_profile, const char *role) { + pa_tz_device *device; pa_source *source; - if (!profile_item || !role || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); + if (!type || !role) { + pa_log_warn("Argument for set_default_source invalid"); + return NULL; + } + + if (!(device = _device_list_get_device(dm, type, NULL))) { + pa_log_warn("cannot get device item for %s", type); return NULL; } - if (!profile_item->capture_devices) { - pa_log_error("No capture devices"); + if (!(source = pa_tz_device_get_source(device, role))) { + pa_log_warn("cannot get source for %s", role); return NULL; } - source = pa_hashmap_get(profile_item->capture_devices, role); + source = pa_namereg_set_default_source(dm->core, source); return source; } -static dm_device* create_device_item(const char *device_type, const char *name, dm_device_profile *profile_item, pa_device_manager *dm) { - dm_device *device_item = NULL; - pa_sink *sink = NULL; - pa_source *source = NULL; - - pa_assert(device_type); - pa_assert(profile_item); +static void handle_usb_pulse_device(pa_object *pdevice, bool is_loaded, pa_device_manager *manager) { + const char *name, *system_id; + dm_device_direction_t direction; + pa_tz_device *device; - pa_log_info("Create device item for %s", device_type); + pa_assert(pdevice); + pa_assert(manager); - device_item = (dm_device *)pa_xmalloc(sizeof(dm_device)); - device_item->id = device_id_max_g++; - device_item->type = strdup(device_type); - device_item->active_profile = PA_INVALID_INDEX; - device_item->profiles = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - device_item->dm = dm; + pa_log_info("Handle usb pulse device"); - if (name) { - device_item->name = strdup(name); - } else { - device_item->name = strdup(device_type); - } + system_id = pulse_device_get_system_id(pdevice); + direction = pulse_device_get_direction(pdevice); - _device_item_add_profile(device_item, profile_item, NULL, dm); - _device_list_add_device(dm->device_list, device_item, dm); + if (is_loaded) { + pa_tz_device_new_data data; - // just for external device - if ((sink = _device_profile_get_sink(profile_item, DEVICE_ROLE_NORMAL))) - sink->device_item = device_item; - if ((source = _device_profile_get_source(profile_item, DEVICE_ROLE_NORMAL))) - source->device_item = device_item; + name = pulse_device_get_device_name(pdevice, DEVICE_TYPE_USB_AUDIO); - notify_device_connection_changed(device_item, true, dm); + pa_tz_device_new_data_init(&data, manager->device_list, manager->comm, NULL); + pa_tz_device_new_data_set_type(&data, DEVICE_TYPE_USB_AUDIO); + pa_tz_device_new_data_set_name(&data, name); + pa_tz_device_new_data_set_direction(&data, direction); + pa_tz_device_new_data_set_system_id(&data, system_id); + pa_tz_device_new_data_set_use_internal_codec(&data, false); + if (direction == DM_DEVICE_DIRECTION_OUT) + pa_tz_device_new_data_add_sink(&data, DEVICE_ROLE_NORMAL, PA_SINK(pdevice)); + else + pa_tz_device_new_data_add_source(&data, DEVICE_ROLE_NORMAL, PA_SOURCE(pdevice)); - return device_item; + pa_tz_device_new(&data); + pa_tz_device_new_data_done(&data); + } else { + if (!(device = _device_list_get_device(manager, DEVICE_TYPE_USB_AUDIO, system_id))) + pa_log_warn("Can't get usb device for %s", system_id); + else + pa_tz_device_free(device); + } } -static void destroy_device_item(dm_device *device_item, pa_device_manager *dm) { - if (!device_item) { - return; - } +static void handle_bt_pulse_device(pa_object *pdevice, bool is_loaded, pa_device_manager *manager) { + dm_device_direction_t direction; + pa_tz_device *device; + const char *system_id; - pa_log_info("Destroy device item which of type is %s", device_item->type); + pa_assert(pdevice); + pa_assert(manager); - device_item_free_func(device_item); -} + pa_log_info("Handle bt pulse device"); -static unsigned _device_item_get_size(dm_device *device_item) { - unsigned int profile_num; - pa_assert(device_item); + direction = pulse_device_get_direction(pdevice); + system_id = pulse_device_get_system_id(pdevice); - profile_num = pa_idxset_size(device_item->profiles); - return profile_num; -} + if (is_loaded) { + pa_tz_device_new_data data; + pa_tz_profile_new_data profile_data; -static dm_device* _device_item_remove_profile(dm_device *device_item, dm_device_profile *profile_item, pa_device_manager *dm) { - unsigned int profile_num; + /* Use profile_new_data, because BT is multi profile type */ + pa_tz_profile_new_data_init(&profile_data); + pa_tz_profile_new_data_set_profile(&profile_data, DEVICE_PROFILE_BT_A2DP); + pa_tz_profile_new_data_set_direction(&profile_data, direction); + pa_tz_profile_new_data_set_use_internal_codec(&profile_data, false); + if (direction == DM_DEVICE_DIRECTION_OUT) + pa_tz_profile_new_data_add_sink(&profile_data, DEVICE_ROLE_NORMAL, PA_SINK(pdevice)); + else + pa_tz_profile_new_data_add_source(&profile_data, DEVICE_ROLE_NORMAL, PA_SOURCE(pdevice)); + + device = _device_list_get_device(manager, DEVICE_TYPE_BT, system_id); + /* Just add profile, if already exists */ + if (device) { + dm_device_bt_sco_status_t sco_status; + if (pa_tz_device_sco_get_status(device, &sco_status) < 0) { + pa_log_error("Failed to get sco status"); + return ; + } + if (sco_status == DM_DEVICE_BT_SCO_STATUS_OPENED) + pa_tz_device_add_profile(device, &profile_data, false); + else + pa_tz_device_add_profile(device, &profile_data, true); + } else { + /* Create new device with profile */ + const char *name; + name = pulse_device_get_device_name(pdevice, DEVICE_TYPE_BT); - pa_assert(device_item); - pa_assert(device_item->profiles); - pa_assert(profile_item); - pa_assert(dm); + pa_tz_device_new_data_init(&data, manager->device_list, manager->comm, manager->dbus_conn); + pa_tz_device_new_data_set_type(&data, DEVICE_TYPE_BT); + pa_tz_device_new_data_set_name(&data, name); + pa_tz_device_new_data_set_system_id(&data, system_id); + pa_tz_device_new_data_add_profile(&data, &profile_data, true); - profile_num = pa_idxset_size(device_item->profiles); + pa_tz_device_new(&data); + pa_tz_device_new_data_done(&data); + } + pa_tz_profile_new_data_done(&profile_data); + } else { - if (profile_num == 0) { - pa_log_error("Already Empty device_item"); - return NULL; + if (!(device = _device_list_get_device(manager, DEVICE_TYPE_BT, system_id))) + pa_log_warn("Can't get bt device for %s", system_id); + else { + if (pa_tz_device_get_profile_num(device) > 1) + pa_tz_device_remove_profile(device, DEVICE_PROFILE_BT_A2DP); + else + pa_tz_device_free(device); + } } +} + +static void handle_internal_pulse_device(pa_object *pdevice, bool is_loaded, pa_device_manager *manager) { + pa_tz_device *device; + struct composite_type *ctype; + pa_dynarray *ctypes; + dm_device_direction_t direction; - pa_idxset_remove_by_data(device_item->profiles, profile_item, NULL); - _device_item_set_active_profile_auto(device_item); + pa_assert(pdevice); + pa_assert(manager); + + pa_log_info("Handle internal pulse device"); + direction = pulse_device_get_direction(pdevice); + + /* Get types which this pulse_device belongs to */ + if ((ctypes = pulse_device_get_belongs_type(pdevice, manager)) == NULL) { + pa_log_debug("Failed to get device type. Skip this"); + return ; + } + + if (is_loaded) { + /* Put this pulse_device to already loaded devices */ + for (int i = 0; i < pa_dynarray_size(ctypes); i++) { + ctype = pa_dynarray_get(ctypes, i); + pa_log_info("Found belongs type %s %s %s", ctype->type, pa_strempty(ctype->profile), ctype->role); + if ((device = _device_list_get_device(manager, ctype->type, NULL))) { + pa_log_info("Add this pulse_device to device(%u)", pa_tz_device_get_id(device)); + if (direction == DM_DEVICE_DIRECTION_OUT) + pa_tz_device_profile_add_sink(device, ctype->profile, ctype->role, PA_SINK(pdevice)); + else + pa_tz_device_profile_add_source(device, ctype->profile, ctype->role, PA_SOURCE(pdevice)); + } else { + pa_log_info("No device for %s", ctype->type); + } + } + } else { + /* Remove this pulse_device from already loaded devices */ + for (int i = 0; i < pa_dynarray_size(ctypes); i++) { + ctype = pa_dynarray_get(ctypes, i); + pa_log_info("Found belongs type %s %s %s", ctype->type, ctype->profile, ctype->role); + if ((device = _device_list_get_device(manager, ctype->type, NULL))) { + pa_log_info("Remove this pulse_device from device(%u)", pa_tz_device_get_id(device)); + if (direction == DM_DEVICE_DIRECTION_OUT) + pa_tz_device_remove_sink(device, PA_SINK(pdevice)); + else + pa_tz_device_remove_source(device, PA_SOURCE(pdevice)); + } else { + pa_log_info("No device for %s", ctype->type); + } + } + } - return device_item; + pa_dynarray_free(ctypes); } -static dm_device_profile* create_device_profile(const char *device_profile, dm_device_direction_t direction, pa_hashmap *playback, pa_hashmap *capture) { - dm_device_profile *profile_item = NULL; +static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, pa_device_manager *dm) { + pa_assert(c); + pa_assert(sink); + pa_assert(dm); - pa_assert(direction >= DM_DEVICE_DIRECTION_IN && direction <= DM_DEVICE_DIRECTION_BOTH); + pa_log_info("========== Sink Put Hook Callback '%s'(%d) ==========", sink->name, sink->index); - pa_log_debug("Create device profile for %s, direction:%s", device_profile, device_direction_to_string(direction)); + if (pulse_device_is_monitor(PA_OBJECT(sink))) + return PA_HOOK_OK; - if (!(profile_item = (dm_device_profile *)pa_xmalloc(sizeof(dm_device_profile)))) { - pa_log_error("Cannot alloc for device item"); - return NULL; + if (pulse_device_is_usb(PA_OBJECT(sink))) { + pulse_device_set_use_internal_codec(PA_OBJECT(sink), false); + handle_usb_pulse_device(PA_OBJECT(sink), true, dm); + return PA_HOOK_OK; + } else if (pulse_device_is_bluez(PA_OBJECT(sink))) { + pulse_device_set_use_internal_codec(PA_OBJECT(sink), false); + handle_bt_pulse_device(PA_OBJECT(sink), true, dm); + return PA_HOOK_OK; + } else if (pulse_device_is_alsa(PA_OBJECT(sink)) || pulse_device_is_tizenaudio(PA_OBJECT(sink))) { + pulse_device_set_use_internal_codec(PA_OBJECT(sink), true); + handle_internal_pulse_device(PA_OBJECT(sink), true, dm); + return PA_HOOK_OK; + } else { + pa_log_debug("Don't care this sink"); } - profile_item->profile = device_profile ? strdup(device_profile) : NULL; - profile_item->direction = direction; - profile_item->playback_state = DM_DEVICE_STATE_DEACTIVATED; - profile_item->capture_state = DM_DEVICE_STATE_DEACTIVATED; - profile_item->playback_devices = playback; - profile_item->capture_devices = capture; - profile_item->creation_time = pa_rtclock_now(); - return profile_item; + return PA_HOOK_OK; } -static dm_device* destroy_device_profile(dm_device_profile *profile_item, pa_device_manager *dm) { - dm_device *device_item; - - pa_assert(profile_item); - pa_assert(profile_item->device_item); +static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, pa_device_manager *dm) { + pa_assert(c); + pa_assert(sink); + pa_assert(dm); - device_item = profile_item->device_item; + pa_log_info("=========== Sink unlink Hook Callback '%s'(%d) ==========", sink->name, sink->index); - pa_log_info("Destroy device profile item which of profile is %s", profile_item->profile); + if (pulse_device_is_monitor(PA_OBJECT(sink))) + return PA_HOOK_OK; - if (_device_item_get_size(device_item) == 1) { - destroy_device_item(device_item, dm); - return NULL; + if (pulse_device_is_usb(PA_OBJECT(sink))) { + handle_usb_pulse_device(PA_OBJECT(sink), false, dm); + return PA_HOOK_OK; + } else if (pulse_device_is_bluez(PA_OBJECT(sink))) { + handle_bt_pulse_device(PA_OBJECT(sink), false, dm); + return PA_HOOK_OK; + } else if (pulse_device_is_alsa(PA_OBJECT(sink)) || pulse_device_is_tizenaudio(PA_OBJECT(sink))) { + handle_internal_pulse_device(PA_OBJECT(sink), false, dm); + return PA_HOOK_OK; } else { - _device_item_remove_profile(device_item, profile_item, dm); - profile_item_free_func(profile_item); - return device_item; + pa_log_debug("Don't care this sink"); } -} -static void _device_profile_update_direction(dm_device_profile *profile_item) { - int prev_direction; - bool playback_exist = false, capture_exist = false; + return PA_HOOK_OK; +} - if (!profile_item) - return; +static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, pa_device_manager *dm) { + pa_assert(c); + pa_assert(source); + pa_assert(dm); - prev_direction = profile_item->direction; + pa_log_info("========== source Put Hook Callback '%s'(%d) ==========", source->name, source->index); - if (profile_item->playback_devices) { - if (pa_hashmap_size(profile_item->playback_devices) > 0) { - playback_exist = true; - } - } - if (profile_item->capture_devices) { - if (pa_hashmap_size(profile_item->capture_devices) > 0) { - capture_exist = true; - } - } + if (pulse_device_is_monitor(PA_OBJECT(source))) + return PA_HOOK_OK; - if (playback_exist && capture_exist) { - profile_item->direction = DM_DEVICE_DIRECTION_BOTH; - } else if (playback_exist) { - profile_item->direction = DM_DEVICE_DIRECTION_OUT; - } else if (capture_exist) { - profile_item->direction = DM_DEVICE_DIRECTION_IN; + if (pulse_device_is_usb(PA_OBJECT(source))) { + pulse_device_set_use_internal_codec(PA_OBJECT(source), false); + handle_usb_pulse_device(PA_OBJECT(source), true, dm); + return PA_HOOK_OK; + } else if (pulse_device_is_bluez(PA_OBJECT(source))) { + pulse_device_set_use_internal_codec(PA_OBJECT(source), false); + handle_bt_pulse_device(PA_OBJECT(source), true, dm); + return PA_HOOK_OK; + } else if (pulse_device_is_alsa(PA_OBJECT(source)) || pulse_device_is_tizenaudio(PA_OBJECT(source))) { + pulse_device_set_use_internal_codec(PA_OBJECT(source), true); + handle_internal_pulse_device(PA_OBJECT(source), true, dm); + return PA_HOOK_OK; } else { - profile_item->direction = DM_DEVICE_DIRECTION_NONE; + pa_log_debug("Don't care this source"); } - pa_log_debug("direction updated '%s'->'%s'", device_direction_to_string(prev_direction), device_direction_to_string(profile_item->direction)); + return PA_HOOK_OK; } -static dm_device_profile* _device_profile_add_pulse_device(dm_device_profile *profile_item, const char *role, void *pulse_device, pa_device_type_t pdt) { - if (!profile_item || !pulse_device || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); - return NULL; - } +static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, pa_device_manager *dm) { + pa_assert(c); + pa_assert(source); + pa_assert(dm); - if (pdt == PA_DEVICE_TYPE_SINK) { - if (!(profile_item->playback_devices)) - profile_item->playback_devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if (pa_hashmap_put(profile_item->playback_devices, (void *)role, pulse_device) < 0) - return NULL; + pa_log_info("=========== source unlink Hook Callback '%s'(%d) ==========", source->name, source->index); + + if (pulse_device_is_monitor(PA_OBJECT(source))) + return PA_HOOK_OK; + + if (pulse_device_is_usb(PA_OBJECT(source))) { + handle_usb_pulse_device(PA_OBJECT(source), false, dm); + return PA_HOOK_OK; + } else if (pulse_device_is_bluez(PA_OBJECT(source))) { + handle_bt_pulse_device(PA_OBJECT(source), false, dm); + return PA_HOOK_OK; + } else if (pulse_device_is_alsa(PA_OBJECT(source)) || pulse_device_is_tizenaudio(PA_OBJECT(source))) { + handle_internal_pulse_device(PA_OBJECT(source), false, dm); + return PA_HOOK_OK; } else { - if (!(profile_item->capture_devices)) - profile_item->capture_devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if (pa_hashmap_put(profile_item->capture_devices, (void *)role, pulse_device) < 0) - return NULL; + pa_log_debug("Don't care this source"); } - return profile_item; + return PA_HOOK_OK; } -static dm_device_profile* _device_profile_add_sink(dm_device_profile *profile_item, const char *role, pa_sink *sink) { - if (!profile_item || !sink || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); - return NULL; - } - if (!(profile_item->playback_devices)) - profile_item->playback_devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if (pa_hashmap_put(profile_item->playback_devices, (void *)role, sink) < 0) - return NULL; - return profile_item; -} +static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *pdevice, pa_device_manager *dm) { + pa_tz_device *device; + bool use_internal_codec = false; + uint32_t idx = 0; -static dm_device_profile* _device_profile_remove_sink(dm_device_profile *profile_item, const char *role) { - if (!profile_item || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); - return NULL; - } - pa_hashmap_remove(profile_item->playback_devices, role); - return profile_item; -} + pa_assert(c); + pa_object_assert_ref(pdevice); + pa_assert(dm); -static dm_device_profile* _device_profile_add_source(dm_device_profile *profile_item, const char *role, pa_source *source) { - if (!profile_item || !source || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); - return NULL; + if (pa_sink_isinstance(pdevice)) { + pa_sink *s = PA_SINK(pdevice); + pa_sink_state_t state = pa_sink_get_state(s); + pa_log_debug("=========== Sink(%p,%s) state has been changed to [%d](0:RUNNING, 1:IDLE, 2:SUSPEND) ==========", s, s->name, state); + if (s->use_internal_codec) { + if (state == PA_SINK_SUSPENDED) { + PA_IDXSET_FOREACH(device, dm->device_list, idx) { + use_internal_codec = pa_tz_device_is_use_internal_codec(device); + if (use_internal_codec) + pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_OUT, DM_DEVICE_STATE_DEACTIVATED); + } + } + } else { + if ((device = pa_device_manager_get_device_with_sink(s))) { + if (state == PA_SINK_RUNNING) + pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_OUT, DM_DEVICE_STATE_ACTIVATED); + else if (state == PA_SINK_SUSPENDED) + pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_OUT, DM_DEVICE_STATE_DEACTIVATED); + } + } + } else if (pa_source_isinstance(pdevice)) { + pa_source *s = PA_SOURCE(pdevice); + pa_source_state_t state = pa_source_get_state(s); + pa_log_debug("=========== Source(%p,%s) state has been changed to [%d](0:RUNNING, 1:IDLE, 2:SUSPEND) ==========", s, s->name, state); + if (s->use_internal_codec) { + if (state == PA_SOURCE_SUSPENDED) { + PA_IDXSET_FOREACH(device, dm->device_list, idx) { + use_internal_codec = pa_tz_device_is_use_internal_codec(device); + if (use_internal_codec) + pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_IN, DM_DEVICE_STATE_DEACTIVATED); + } + } + } else { + if ((device = pa_device_manager_get_device_with_source(s))) { + if (state == PA_SOURCE_RUNNING) + pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_IN, DM_DEVICE_STATE_ACTIVATED); + else if (state == PA_SOURCE_SUSPENDED) + pa_tz_device_set_state(device, DM_DEVICE_DIRECTION_IN, DM_DEVICE_STATE_DEACTIVATED); + } + } } + pa_log_debug("========= device_state_changed_hook_cb END ====="); - if (!(profile_item->capture_devices)) - profile_item->capture_devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if (pa_hashmap_put(profile_item->capture_devices, (void *)role, source) < 0) - return NULL; - - return profile_item; + return PA_HOOK_OK; } -static int _device_profile_get_size(dm_device_profile *profile_item, unsigned int *playback_num, unsigned int *capture_num) { - if (!profile_item || !playback_num || !capture_num) { - pa_log_error("Invalid Parameter"); - return -1; - } +/* + Build params for load sink or source, and load it. +*/ - if (!(profile_item->playback_devices)) - *playback_num = 0; - else - *playback_num = pa_hashmap_size(profile_item->playback_devices); - - if (!(profile_item->capture_devices)) - *capture_num = 0; - else - *capture_num = pa_hashmap_size(profile_item->capture_devices); - - return 0; -} - - -static dm_device_profile* _device_profile_remove_source(dm_device_profile *profile_item, const char *role) { - if (!profile_item || !(profile_item->capture_devices) || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); - return NULL; - } - pa_hashmap_remove(profile_item->capture_devices, role); - return profile_item; -} - -static void _device_profile_set_state(dm_device_profile *profile_item, dm_device_direction_t direction, dm_device_state_t state) { - dm_device_state_t prev_state, new_state; - pa_assert(profile_item); - - prev_state = COMPOUND_STATE(profile_item); - pa_log_debug("previous playback_state : %d, capture_state : %d => state %d", profile_item->playback_state, profile_item->capture_state, prev_state); - if (direction & DM_DEVICE_DIRECTION_IN) - profile_item->capture_state = state; - if (direction & DM_DEVICE_DIRECTION_OUT) - profile_item->playback_state = state; - new_state = COMPOUND_STATE(profile_item); - pa_log_debug("new playback_state : %d, capture_state : %d => state %d", profile_item->playback_state, profile_item->capture_state, new_state); - - if (prev_state != new_state) { - notify_device_info_changed(profile_item->device_item, DM_DEVICE_CHANGED_INFO_STATE, profile_item->device_item->dm); - } -} - -static int device_type_get_direction(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *identifier) { - struct device_type_info *type_info = NULL; - struct device_status_info *status_info; - - if (!dm || !device_type) { - pa_log_error("Invalid Parameter"); - return -1; - } - - if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) { - return DM_DEVICE_DIRECTION_OUT; - } else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) { - return DM_DEVICE_DIRECTION_OUT; - } else if (pa_streq(device_type, DEVICE_TYPE_MIC)) { - return DM_DEVICE_DIRECTION_IN; - } else if (pa_streq(device_type, DEVICE_TYPE_BT) && pa_streq(device_profile, DEVICE_PROFILE_BT_A2DP)) { - return -1; - } else if (pa_streq(device_type, DEVICE_TYPE_BT) && pa_streq(device_profile, DEVICE_PROFILE_BT_SCO)) { - return DM_DEVICE_DIRECTION_BOTH; - } else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) { - return DM_DEVICE_DIRECTION_OUT; - } else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) { - return -1; - } else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) { - return DM_DEVICE_DIRECTION_BOTH; - } else if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) { - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_type, device_profile))) { - pa_log_error("No type map for %s", device_type); - return -1; - } - status_info = _device_manager_get_status_info(dm->device_status, type_info->type, type_info->profile, identifier); - if (status_info->detected_type == DEVICE_DETECTED_AUDIO_JACK_BOTH_DIREC) { - return DM_DEVICE_DIRECTION_BOTH; - } else if (status_info->detected_type == DEVICE_DETECTED_AUDIO_JACK_OUT_DIREC) { - return DM_DEVICE_DIRECTION_OUT; - } else { - pa_log_debug("Cannot get audio jack device direction"); - return -1; - } - } - - return -1; -} - -static int pulse_device_get_device_type(void *pulse_device, pa_device_type_t pdt, dm_device_class_t device_class, const char **device_type, const char **device_profile, const char **device_name) { - pa_proplist *prop; +static void* load_device(pa_core *c, bool is_sink, const char *device_string, const char *device_params) { + const char *args = NULL; + const char *module_name; + pa_module *module; pa_sink *sink; pa_source *source; + uint32_t device_idx; + dm_device_class_t device_class; - pa_assert(pulse_device); - pa_assert(device_type); - pa_assert(device_profile); - - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; - prop = sink->proplist; - } else { - source = (pa_source*) pulse_device; - prop = source->proplist; - } - - if (device_class == DM_DEVICE_CLASS_ALSA) { - if (pulse_device_is_usb(prop)) { - *device_type = DEVICE_TYPE_USB_AUDIO; - *device_profile = NULL; - *device_name = pa_proplist_gets(prop, "udev.id"); - } else { - pa_log_warn("This is alsa device, but not usb. really unknown device"); - return -1; - } - } else if (device_class == DM_DEVICE_CLASS_BT) { - *device_type = DEVICE_TYPE_BT; - *device_profile = DEVICE_PROFILE_BT_A2DP; - *device_name = pa_proplist_gets(prop, "bluez.alias"); - } else { - pa_log_warn("Invalid device type, neither alsa nor bluez"); - return -1; - } - - return 0; -} - -static dm_device_profile* _device_item_get_profile(dm_device *device_item, const char *profile) { - dm_device_profile *profile_item; - uint32_t profile_idx; - - if (!device_item || !device_item->profiles) - return NULL; - - PA_IDXSET_FOREACH(profile_item, device_item->profiles, profile_idx) { - if (!compare_device_profile(profile_item->profile, profile)) { - return profile_item; - } - } - return NULL; -} - -static dm_device_profile* _device_item_get_active_profile(dm_device *device_item) { - dm_device_profile *profile_item; - - if (!device_item || !device_item->profiles) - return NULL; - - if ((profile_item = pa_idxset_get_by_index(device_item->profiles, device_item->active_profile))) - return profile_item; - - - return NULL; -} - -static pa_sink* _device_manager_set_default_sink(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *role) { - dm_device *device_item; - dm_device_profile *profile_item; - pa_sink *sink; - - if (!device_type || !role) { - pa_log_warn("Argument for set_default_sink invalid"); - return NULL; - } - - if (!(device_item = _device_manager_get_device(dm->device_list, device_type))) { - pa_log_warn("cannot get device item for %s", device_type); - return NULL; - } - if (!(profile_item = _device_item_get_profile(device_item, device_profile))) { - pa_log_warn("cannot get profile item for %s", device_profile); - return NULL; - } - - if (!(sink = pa_hashmap_get(profile_item->playback_devices, role))) { - pa_log_warn("cannot get sink for %s", role); - return NULL; - } - - sink = pa_namereg_set_default_sink(dm->core, sink); - return sink; -} + pa_assert(c); + pa_assert(device_string); + pa_assert(device_params); -static pa_source* _device_manager_set_default_source(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *role) { - dm_device *device_item; - dm_device_profile *profile_item; - pa_source *source; + pa_log_info("Load %s Device : String'%s' Param'%s'", is_sink ? "Playback" : "Capture", device_string, device_params); - if (!device_type || !role) { - pa_log_warn("Argument for set_default_source invalid"); + device_class = device_string_get_class(device_string); + if (device_class <= DM_DEVICE_CLASS_NONE || device_class >= DM_DEVICE_CLASS_MAX) { + pa_log_warn("Invalid device_string '%s'", device_string); return NULL; } - if (!(device_item = _device_manager_get_device(dm->device_list, device_type))) { - pa_log_warn("cannot get device item for %s", device_type); + if (!(module_name = device_class_get_module_name(device_class, is_sink))) { + pa_log_error("Get proper module name to load failed"); return NULL; } - if (!(profile_item = _device_item_get_profile(device_item, device_profile))) { - pa_log_warn("cannot get profile item for %s", device_profile); + if (!(args = build_params_to_load_device(device_string, device_params, device_class))) { + pa_log_error("Get proper module name to load failed"); return NULL; } - - if (!(source = pa_hashmap_get(profile_item->capture_devices, role))) { - pa_log_warn("cannot get source for %s", role); + if (!(module = pa_module_load(c, module_name, args))) { + pa_log_error("Load module with name '%s' argu '%s' failed", module_name, args); return NULL; } - source = pa_namereg_set_default_source(dm->core, source); - return source; -} - -static dm_device_profile* handle_not_predefined_device_profile(void *pulse_device, pa_device_type_t pdt, const char *device_profile) { - dm_device_profile *profile_item = NULL; - dm_device_direction_t direc; - pa_log_info("Create device profile item %s", device_profile); - if (pdt == PA_DEVICE_TYPE_SINK) - direc = DM_DEVICE_DIRECTION_OUT; - else - direc = DM_DEVICE_DIRECTION_IN; - - if (!(profile_item = create_device_profile(device_profile, direc, NULL, NULL))) { - pa_log_error("create_device_profile failed"); - goto failed; - } - if (pdt == PA_DEVICE_TYPE_SINK) { - if (!(_device_profile_add_sink(profile_item, DEVICE_ROLE_NORMAL, pulse_device))) { - pa_log_error("failed to add sink"); - goto failed; + if (is_sink) { + PA_IDXSET_FOREACH(sink, c->sinks, device_idx) { + if (sink->module == module) { + return sink; + } } } else { - if (!(_device_profile_add_source(profile_item, DEVICE_ROLE_NORMAL, pulse_device))) { - pa_log_error("failed to add source"); - goto failed; - } - } - - return profile_item; -failed: - if (profile_item) - pa_xfree(profile_item); - return NULL; -} - - -static dm_device* handle_not_predefined_device(pa_device_manager *dm, void *pulse_device, pa_device_type_t pdt, dm_device_class_t device_class) { - dm_device_profile *profile_item = NULL; - const char *device_type, *device_profile, *device_name; - dm_device *device_item = NULL; - pa_source *sibling_source, *source; - pa_sink *sibling_sink, *sink; - - pa_assert(dm); - pa_assert(pulse_device); - - pa_log_info("handle_not_predefined_device"); - - if (pdt == PA_DEVICE_TYPE_SINK) - ((pa_sink*)pulse_device)->use_internal_codec = false; - else - ((pa_source*)pulse_device)->use_internal_codec = false; - - if (pulse_device_get_device_type(pulse_device, pdt, device_class, &device_type, &device_profile, &device_name) < 0) { - pa_log_warn("Cannot get device type of this device"); - return NULL; - } - - /* - Find opposite direction sink/sources on same device. - If Found, add sink or source to same device_item. - */ - if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) { - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; - if ((sibling_source = pulse_device_get_opposite_sibling_device(sink, PA_DEVICE_TYPE_SINK))) { - if (sibling_source->device_item) { - device_item = (dm_device *) sibling_source->device_item; - profile_item = _device_item_get_profile(device_item, NULL); - if (!(_device_profile_add_sink(profile_item, DEVICE_ROLE_NORMAL, sink))) { - pa_log_error("failed to add sink beside sibling source"); - goto failed; - } - _device_profile_update_direction(profile_item); - notify_device_info_changed(device_item, DM_DEVICE_CHANGED_INFO_IO_DIRECTION, dm); - goto end; - } - } - } else { - source = (pa_source*) pulse_device; - if ((sibling_sink = pulse_device_get_opposite_sibling_device(source, PA_DEVICE_TYPE_SOURCE))) { - if (sibling_sink->device_item) { - device_item = (dm_device *) sibling_sink->device_item; - profile_item = _device_item_get_profile(device_item, NULL); - if (!(_device_profile_add_source(profile_item, DEVICE_ROLE_NORMAL, source))) { - pa_log_error("failed to add source beside sibling sink"); - goto failed; - } - _device_profile_update_direction(profile_item); - notify_device_info_changed(device_item, DM_DEVICE_CHANGED_INFO_IO_DIRECTION, dm); - goto end; - } + PA_IDXSET_FOREACH(source, c->sources, device_idx) { + if (source->module == module) { + return source; } } } - if (!(profile_item = handle_not_predefined_device_profile(pulse_device, pdt, device_profile))) { - pa_log_error("failed to handle unknown device profile"); - goto failed; - } - _device_profile_update_direction(profile_item); - - if (device_class == DM_DEVICE_CLASS_BT) { - if ((device_item = _device_manager_get_device(dm->device_list, DEVICE_TYPE_BT))) { - pa_log_debug("found bt device"); - _device_item_add_profile(device_item, profile_item, NULL, dm); - goto end; - } - } - - if (!(device_item = create_device_item(device_type, device_name, profile_item, dm))) { - pa_log_error("failed to create device item for not predefined device"); - goto failed; - } - -end: - - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; - sink->device_item = device_item; - } else { - source = (pa_source *) pulse_device; - source->device_item = device_item; - } - - return device_item; - -failed: - pa_log_error("Failed to handle external device"); - if (profile_item) - pa_xfree(profile_item); - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; - sink->device_item = device_item; - } else { - source = (pa_source *) pulse_device; - source->device_item = device_item; - } - - return NULL; } -static bool pulse_device_loaded_with_param(pa_core *core, pa_device_type_t pdt, const char *device_string, const char *params) { - pa_sink *sink; - pa_source *source; +static pa_sink* _core_get_sink(pa_core *core, const char *device_string, const char *params) { uint32_t device_idx; + pa_sink *sink; pa_assert(core); pa_assert(device_string); - if (pdt == PA_DEVICE_TYPE_SINK) { - PA_IDXSET_FOREACH(sink, core->sinks, device_idx) { - if (pulse_device_class_is_monitor(sink->proplist)) - continue; - if (pa_streq(device_string, pulse_device_get_device_string(sink, pdt))) { - if (!compare_device_params_with_module_args(sink, pdt, params)) { - return true; - } - } - } - } else { - PA_IDXSET_FOREACH(source, core->sources, device_idx) { - if (pulse_device_class_is_monitor(source->proplist)) - continue; - if (pa_streq(device_string, pulse_device_get_device_string(source, pdt))) { - if (!compare_device_params_with_module_args(source, pdt, params)) { - return true; - } - } + PA_IDXSET_FOREACH(sink, core->sinks, device_idx) { + if (pulse_device_is_monitor(PA_OBJECT(sink))) + continue; + if (pulse_device_same_device_string(PA_OBJECT(sink), device_string)) { + if (params == NULL) + return sink; + else if (pulse_device_params_is_equal(PA_OBJECT(sink), params)) + return sink; } } - return false; + + return NULL; } -static int device_type_get_pulse_devices(struct device_type_info *type_info, pa_hashmap **playback, pa_hashmap **capture, pa_device_manager *dm) { - struct device_file_info *file_info; - const char *device_string, *params, *role; +static pa_source* _core_get_source(pa_core *core, const char *device_string, const char *params) { uint32_t device_idx; - pa_sink *sink; pa_source *source; - void *state; - - pa_assert(type_info); - pa_assert(playback); - pa_assert(capture); - pa_assert(dm); - - if (pa_streq(type_info->type, DEVICE_TYPE_FORWARDING)) { - dm_device *device_item; - dm_device_profile *device_profile; - pa_sink *spk_sink; - - /* Let sink of forwading device same as speaker, - * source of forwarding device will be monitor of that sink */ - if (!(device_item = _device_manager_get_device(dm->device_list, DEVICE_TYPE_SPEAKER))) { - pa_log_error("get speaker item failed"); - goto failed; - } else if (!(device_profile = _device_item_get_profile(device_item, NULL))) { - pa_log_error("get speaker profile failed"); - goto failed; - } else if (!(spk_sink = _device_profile_get_sink(device_profile, DEVICE_ROLE_NORMAL)) || !(spk_sink->monitor_source)) { - pa_log_error("get speaker sink and monitor source failed"); - goto failed; - } else { - *playback = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - *capture = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - pa_hashmap_put(*playback, (void *)DEVICE_ROLE_NORMAL, spk_sink); - pa_hashmap_put(*capture, (void *)DEVICE_ROLE_NORMAL, spk_sink->monitor_source); - ((pa_source*)(spk_sink->monitor_source))->use_internal_codec = true; - } - } else { - if (type_info->playback_devices) { - *playback = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - PA_HASHMAP_FOREACH_KEY(device_string, type_info->playback_devices, state, role) { - if (!(file_info = _device_manager_get_file_info(dm->file_map->playback, device_string))) { - pa_log_error("No playback file map for '%s'", device_string); - goto failed; - } - if (!(params = pa_hashmap_get(file_info->roles, role))) { - pa_log_error("No params for '%s:%s'", device_string, role); - goto failed; - } + pa_assert(core); + pa_assert(device_string); - PA_IDXSET_FOREACH(sink, dm->core->sinks, device_idx) { - if (pulse_device_class_is_monitor(sink->proplist)) - continue; - if (pulse_device_same_device_string(sink, PA_DEVICE_TYPE_SINK, device_string)) { - if (!compare_device_params_with_module_args(sink, PA_DEVICE_TYPE_SINK, params)) { - pa_hashmap_put(*playback, (void *)role, sink); - pa_log_debug("role:%s <- sink:%s", role, sink->name); - break; - } - } - } - } - } - if (type_info->capture_devices) { - *capture = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - PA_HASHMAP_FOREACH_KEY(device_string, type_info->capture_devices, state, role) { - if (!(file_info = _device_manager_get_file_info(dm->file_map->capture, device_string))) { - pa_log_error("No capture file map for '%s'", device_string); - goto failed; - } - if (!(params = pa_hashmap_get(file_info->roles, role))) { - pa_log_error("No params for '%s:%s'", device_string, role); - goto failed; - } - PA_IDXSET_FOREACH(source, dm->core->sources, device_idx) { - if (pulse_device_class_is_monitor(source->proplist)) - continue; - if (pulse_device_same_device_string(source, PA_DEVICE_TYPE_SOURCE, device_string)) { - if (!compare_device_params_with_module_args(source, PA_DEVICE_TYPE_SOURCE, params)) { - pa_hashmap_put(*capture, (void *)role, source); - pa_log_debug("role:%s <- source:%s", role, source->name); - break; - } - } - } - } + PA_IDXSET_FOREACH(source, core->sources, device_idx) { + if (pulse_device_is_monitor(PA_OBJECT(source))) + continue; + if (pulse_device_same_device_string(PA_OBJECT(source), device_string)) { + if (params == NULL) + return source; + else if (pulse_device_params_is_equal(PA_OBJECT(source), params)) + return source; } } - return 0; - -failed: - if (!(*playback)) - pa_hashmap_free(*playback); - if (!(*capture)) - pa_hashmap_free(*capture); - *playback = NULL; - *capture = NULL; - - return -1; -} - -static const char* device_type_info_get_device_string(struct device_type_info *type_info, const char *role, pa_device_type_t pdt) { - pa_assert(type_info); - pa_assert(role); - - if (pdt == PA_DEVICE_TYPE_SINK) { - if (type_info->playback_devices) - return pa_hashmap_get(type_info->playback_devices, role); - else - return NULL; - } else { - if (type_info->capture_devices) - return pa_hashmap_get(type_info->capture_devices, role); - else - return NULL; - } - -} - -static const char* device_file_info_get_role_with_params(struct device_file_info *file_info, const char *params) { - char *params_tmp, *role; - void *state; - - PA_HASHMAP_FOREACH_KEY(params_tmp, file_info->roles, state, role) { - if (!compare_device_params(params_tmp, params)) { - return role; - } - } return NULL; } -static dm_device* handle_device_type_available(struct device_type_info *type_info, const char *name, pa_device_manager *dm) { - dm_device_profile *profile_item = NULL; - dm_device *device_item = NULL; - dm_device_direction_t direction; - pa_hashmap *playback = NULL, *capture = NULL; - - pa_assert(dm); - pa_assert(dm->type_infos); - - pa_log_debug("handle_device_type_available, type:%s, profile:%s, name:%s", type_info->type, type_info->profile, name); - - /* Directions of some types are not statically defined, ex) earjack */ - if ((direction = device_type_get_direction(dm, type_info->type, type_info->profile, NULL)) < 0) { - pa_log_error("Failed to get direction of %s.%s", type_info->type, type_info->profile); - return NULL; - } - pa_log_debug("Direction of %s.%s is %s", type_info->type, type_info->profile, device_direction_to_string(direction)); - - /* Get Sink/Sources for device_type, profile */ - if (device_type_get_pulse_devices(type_info, &playback, &capture, dm) < 0) { - pa_log_error("Failed to get sink/sources related to %s.%s", type_info->type, type_info->profile); - return NULL; - } - - /* Check whether Sink/Sources for direction of type are loaded */ - if ((((direction & DM_DEVICE_DIRECTION_IN) && !capture) || ((direction & DM_DEVICE_DIRECTION_OUT) && !playback))) { - pa_log_debug("Sink/Sources for %s.%s are not fully loaded yet", type_info->type, type_info->profile); - goto failed; - } - profile_item = create_device_profile(type_info->profile, direction, playback, capture); +static void _fill_new_data_basic(pa_tz_device_new_data *data, const char *type, + dm_device_direction_t direction, bool use_internal_codec, pa_device_manager *dm) { + pa_assert(data); - if (!(device_item = _device_manager_get_device(dm->device_list, type_info->type))) { - pa_log_debug("No device item for %s, Create", type_info->type); - device_item = create_device_item(type_info->type, name, profile_item, dm); - } else { - _device_item_add_profile(device_item, profile_item, NULL, dm); - } - - return device_item; - -failed: - if (playback) - pa_hashmap_free(playback); - if (capture) - pa_hashmap_free(capture); - return NULL; + pa_tz_device_new_data_set_type(data, type); + pa_tz_device_new_data_set_direction(data, direction); + pa_tz_device_new_data_set_use_internal_codec(data, use_internal_codec); } -/* FIXME to get identifier of physical device */ -static const char* pulse_device_get_identifier(void *pulse_device, pa_device_type_t pdt, dm_device_class_t device_class) { -/* - const char *sysfs_path; +static void _fill_profile_new_data_basic(pa_tz_profile_new_data *profile_data, + const char *profile, dm_device_direction_t direction, bool use_internal_codec, pa_device_manager *dm) { + pa_assert(profile_data); - if (device_class == TIZEN_AUDIO_DEVICE_CLASS_ALSA) { - if (!(sysfs_path = pa_proplist_gets(sink->proplist, "sysfs.path"))) { - pa_log_warn("No sysfs.path for sink '%s'", sink->name); - return NULL; - } else { - return sysfs_path; - } - } else if (device_class == TIZEN_AUDIO_DEVICE_CLASS_BT) { - } - */ - return NULL; + pa_tz_profile_new_data_set_profile(profile_data, profile); + pa_tz_profile_new_data_set_direction(profile_data, direction); + pa_tz_profile_new_data_set_use_internal_codec(profile_data, use_internal_codec); } -static void handle_predefined_device_loaded(void *pulse_device, pa_device_type_t pdt, dm_device_class_t device_class, const char *device_string, const char *role, pa_device_manager *dm) { - const char *identifier, *device_string_tmp; - struct device_type_info *type_info; - struct device_status_info *status_info; - uint32_t type_idx; - dm_device *device_item; - dm_device_profile *profile_item; - - pa_assert(pulse_device); - pa_assert(dm); - pa_assert(dm->file_map); - pa_assert(device_string); - pa_assert(role); - - pa_log_info("Predefined device loaded, Type:%s, Class:%d, device_string:%s, role:%s", - pdt == PA_DEVICE_TYPE_SINK ? "sink" : "source", device_class, device_string, role); - - if (pdt == PA_DEVICE_TYPE_SINK) - ((pa_sink*)pulse_device)->use_internal_codec = true; - else - ((pa_source*)pulse_device)->use_internal_codec = true; - - identifier = pulse_device_get_identifier(pulse_device, pdt, device_class); - PA_IDXSET_FOREACH(type_info, dm->type_infos, type_idx) { - /* foreach matching types (which has device_string-role) */ - if ((device_string_tmp = device_type_info_get_device_string(type_info, role, pdt)) && pa_streq(device_string_tmp, device_string)) { - /* - Check device_item is already exists. - If already exists, add loaded sink or source to that. - */ - if ((device_item = _device_manager_get_device(dm->device_list, type_info->type))) { - if ((profile_item = _device_item_get_profile(device_item, type_info->profile))) { - pa_log_debug("device_item for %s.%s already exists", type_info->type, type_info->profile); - if (!_device_profile_add_pulse_device(profile_item, role, pulse_device, pdt)) - pa_log_error("add pulse device to profile_item failed"); - continue; - } - } +static int _fill_new_data_sinks(pa_tz_device_new_data *data, struct device_type_info *type_info, pa_device_manager *dm) { + pa_sink *sink; + char *device_string, *role; + void *state; - /* Get status_info for device_type, profile*/ - if (!(status_info = _device_manager_get_status_info(dm->device_status, type_info->type, type_info->profile, identifier))) { - pa_log_error("%s.%s.%s doesn't have status_info", type_info->type, type_info->profile, identifier); - continue; - } - /* Only if device_type is on detected state*/ - if (status_info->detected == DEVICE_DETECTED) { - pa_log_debug("%s.%s type is detected status", type_info->type, type_info->profile); + pa_assert(data); + pa_assert(type_info); - handle_device_type_available(type_info, NULL, dm); - } else { - pa_log_debug(" This type is not detected status"); - } - } + if (type_info->playback_devices == NULL) { + pa_log_error("No playback devices for %s %s", type_info->type, pa_strempty(type_info->profile)); + return -1; } -} -static void handle_sink_unloaded(pa_sink *sink, pa_device_manager *dm) { - dm_device_profile *profile_item = NULL; - dm_device *device_item; - uint32_t device_idx = 0, profile_idx; - pa_sink *sink_iter = NULL; - void *state = NULL; - const char *role; - - if (!sink || !dm) { - pa_log_error("Invalid Paramter"); - return; + PA_HASHMAP_FOREACH_KEY(device_string, type_info->playback_devices, state, role) { + sink = _core_get_sink(dm->core, device_string, NULL); + if (sink) + pa_tz_device_new_data_add_sink(data, role, sink); + else + pa_log_error("Failed to get matching sink for %s %s", role, device_string); } - pa_assert(sink); - pa_assert(dm); - pa_assert(dm->device_list); - pa_log_debug("Sink unloaded, Let's remove associated device_profiles with this sink"); - - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - PA_IDXSET_FOREACH(profile_item, device_item->profiles, profile_idx) { - if (profile_item->playback_devices) { - PA_HASHMAP_FOREACH_KEY(sink_iter, profile_item->playback_devices, state, role) { - if (sink_iter == sink) { - unsigned int profile_playback_size = 0, profile_capture_size = 0, item_size = 0; - pa_log_info("device '%s' have this sink", device_item->name); - _device_profile_get_size(profile_item, &profile_playback_size, &profile_capture_size); - item_size = _device_item_get_size(device_item); - pa_log_debug("profile playback size : %u, capture size : %u, item size : %u", profile_playback_size, profile_capture_size, item_size); - if (profile_playback_size == 1 && profile_capture_size == 0) { - if (item_size == 1) { - pa_log_debug("notify device disconnected"); - _device_list_remove_device(dm->device_list, device_item, dm); - notify_device_connection_changed(device_item, false, dm); - } - } - _device_profile_remove_sink(profile_item, role); - } - } - if (!pa_hashmap_size(profile_item->playback_devices)) { - pa_hashmap_free(profile_item->playback_devices); - profile_item->playback_devices = NULL; - - if (profile_item->direction == DM_DEVICE_DIRECTION_BOTH) { - if (device_type_is_valid_direction(profile_item->device_item->type, profile_item->profile, DM_DEVICE_DIRECTION_IN)) { - profile_item->direction = DM_DEVICE_DIRECTION_IN; - } else { - if (!destroy_device_profile(profile_item, dm)) - break; - } - } else { - if (!destroy_device_profile(profile_item, dm)) - break; - } - } else { - _device_profile_update_direction(profile_item); - } - } - } - } + return 0; } -static void handle_source_unloaded(pa_source *source, pa_device_manager *dm) { - dm_device_profile *profile_item = NULL; - dm_device *device_item; - uint32_t device_idx = 0, profile_idx; - pa_source *source_iter = NULL; - void *state = NULL; - const char *role; - - if (!source || !dm) { - pa_log_error("Invalid Paramter"); - return; - } - pa_assert(source); - pa_assert(dm); - pa_assert(dm->device_list); +static int _fill_new_data_sources(pa_tz_device_new_data *data, struct device_type_info *type_info, pa_device_manager *dm) { + pa_source *source; + char *device_string, *role; + void *state; - pa_log_debug("Source unloaded, Let's remove associated device_profiles with this source"); - - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - PA_IDXSET_FOREACH(profile_item, device_item->profiles, profile_idx) { - if (profile_item->capture_devices) { - PA_HASHMAP_FOREACH_KEY(source_iter, profile_item->capture_devices, state, role) { - if (source_iter == source) { - unsigned int profile_playback_size = 0, profile_capture_size = 0, item_size = 0; - pa_log_info("device '%s' have this source", device_item->name); - _device_profile_get_size(profile_item, &profile_playback_size, &profile_capture_size); - item_size = _device_item_get_size(device_item); - pa_log_debug("profile playback size : %u, capture size : %u, item size : %u", profile_playback_size, profile_capture_size, item_size); - if (profile_capture_size == 1 && profile_playback_size == 0) { - if (item_size == 1) { - pa_log_debug("notify device disconnected"); - _device_list_remove_device(dm->device_list, device_item, dm); - notify_device_connection_changed(device_item, false, dm); - } - } - - _device_profile_remove_source(profile_item, role); - } - } + pa_assert(data); + pa_assert(type_info); - if (!pa_hashmap_size(profile_item->capture_devices)) { - pa_hashmap_free(profile_item->capture_devices); - profile_item->capture_devices = NULL; - - if (profile_item->direction == DM_DEVICE_DIRECTION_BOTH) { - if (device_type_is_valid_direction(profile_item->device_item->type, profile_item->profile, DM_DEVICE_DIRECTION_OUT)) { - profile_item->direction = DM_DEVICE_DIRECTION_OUT; - } else { - if (!destroy_device_profile(profile_item, dm)) - break; - } - } else { - if (!destroy_device_profile(profile_item, dm)) - break; - } - } else { - _device_profile_update_direction(profile_item); - } - } - } + if (type_info->capture_devices == NULL) { + pa_log_error("No capture devices for %s %s", type_info->type, pa_strempty(type_info->profile)); + return -1; } -} -static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, pa_device_manager *dm) { - const char *device_string = NULL, *role = NULL, *device_string_removed_params = NULL; - struct device_file_info *file_info = NULL; - dm_device_class_t device_class; - - pa_assert(c); - pa_assert(sink); - pa_assert(sink->proplist); - pa_assert(dm); - - if (pulse_device_class_is_monitor(sink->proplist)) { - pa_log_debug("This device's class is monitor. Skip this"); - return PA_HOOK_OK; + PA_HASHMAP_FOREACH_KEY(device_string, type_info->capture_devices, state, role) { + source = _core_get_source(dm->core, device_string, NULL); + if (source) + pa_tz_device_new_data_add_source(data, role, source); + else + pa_log_error("Failed to get matching source for %s %s", role, device_string); } - pa_log_info("========== Sink Put Hook Callback '%s'(%d) ==========", sink->name, sink->index); + return 0; +} - device_class = pulse_device_get_class(sink, PA_DEVICE_TYPE_SINK); - pa_log_info("Device Class '%s'", device_class_to_string(device_class)); +static int _fill_profile_new_data_sinks(pa_tz_profile_new_data *data, struct device_type_info *type_info, pa_device_manager *dm) { + pa_sink *sink; + char *device_string, *role; + void *state; - if (!(device_string = pulse_device_get_device_string(sink, PA_DEVICE_TYPE_SINK))) { - return PA_HOOK_OK; - } else { - pa_log_info("Device String '%s'", device_string); - } + pa_assert(data); + pa_assert(type_info); - if (device_class == DM_DEVICE_CLASS_BT) { - handle_not_predefined_device(dm, sink, PA_DEVICE_TYPE_SINK, device_class); - } else if ((file_info = _device_manager_get_file_info(dm->file_map->playback, device_string))) { - /* module's argument includes device-string(ex. device=hw:0,0 ), - but key params for device_types hashmap is not. */ - if (!(device_string_removed_params = pulse_device_get_device_string_removed_argument(sink, PA_DEVICE_TYPE_SINK))) { - pa_log_debug("argument null"); - return PA_HOOK_OK; - } - if (!(role = device_file_info_get_role_with_params(file_info, device_string_removed_params))) { - pa_log_error("No role for %s", file_info->device_string); - return PA_HOOK_OK; - } + if (type_info->playback_devices == NULL) { + pa_log_error("No playback devices for %s %s", type_info->type, pa_strempty(type_info->profile)); + return -1; + } - handle_predefined_device_loaded(sink, PA_DEVICE_TYPE_SINK, device_class, device_string, role, dm); - } else { - pa_log_debug("Not-predefined device"); - handle_not_predefined_device(dm, sink, PA_DEVICE_TYPE_SINK, device_class); + PA_HASHMAP_FOREACH_KEY(device_string, type_info->playback_devices, state, role) { + sink = _core_get_sink(dm->core, device_string, NULL); + if (sink) + pa_tz_profile_new_data_add_sink(data, role, sink); + else + pa_log_error("Failed to get matching sink for %s %s", role, device_string); } - dump_device_list_info(dm, PA_LOG_INFO); - return PA_HOOK_OK; + return 0; } -static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, pa_device_manager *dm) { - pa_assert(c); - pa_assert(sink); - pa_assert(sink->proplist); - pa_assert(dm); +static int _fill_profile_new_data_sources(pa_tz_profile_new_data *data, struct device_type_info *type_info, pa_device_manager *dm) { + pa_source *source; + char *device_string, *role; + void *state; - if (pulse_device_class_is_monitor(sink->proplist)) { - pa_log_debug("This device's class is monitor. Skip this"); - return PA_HOOK_OK; + pa_assert(data); + pa_assert(type_info); + + if (type_info->capture_devices == NULL) { + pa_log_error("No capture devices for %s %s", type_info->type, pa_strempty(type_info->profile)); + return -1; } - pa_log_info("=========== Sink unlink Hook Callback '%s'(%d) ==========", sink->name, sink->index); - handle_sink_unloaded(sink, dm); - dump_device_list_info(dm, PA_LOG_INFO); - return PA_HOOK_OK; + PA_HASHMAP_FOREACH_KEY(device_string, type_info->capture_devices, state, role) { + source = _core_get_source(dm->core, device_string, NULL); + if (source) + pa_tz_profile_new_data_add_source(data, role, source); + else + pa_log_error("Failed to get matching source for %s %s", role, device_string); + } + + return 0; } -static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, pa_device_manager *dm) { - dm_device *device_item; - dm_device *_device_item; - bool use_internal_codec = false; - uint32_t idx = 0; +static int _load_type_devices(struct device_type_info *type_info, bool is_playback, pa_device_manager *dm) { + pa_hashmap *pcm_devices; + pa_idxset *file_infos; + void *state = NULL; + char *role; + const char *device_string, *params; - pa_assert(c); - pa_object_assert_ref(o); pa_assert(dm); + pa_assert(type_info); - if (pa_sink_isinstance(o)) { - pa_sink *s = PA_SINK(o); - pa_sink_state_t state = pa_sink_get_state(s); - pa_log_debug("=========== Sink(%p,%s) state has been changed to [%d](0:RUNNING, 1:IDLE, 2:SUSPEND) ==========", s, s->name, state); - if (s->use_internal_codec) { - if (state == PA_SINK_SUSPENDED) { - PA_IDXSET_FOREACH(_device_item, dm->device_list, idx) { - use_internal_codec = pa_device_manager_is_device_use_internal_codec(_device_item, DM_DEVICE_DIRECTION_OUT, DEVICE_ROLE_NORMAL); - if (use_internal_codec) - pa_device_manager_set_device_state(_device_item, DM_DEVICE_DIRECTION_OUT, DM_DEVICE_STATE_DEACTIVATED); - } - } - } else { - if ((device_item = pa_device_manager_get_device_with_sink(s))) { - if (state == PA_SINK_RUNNING) - pa_device_manager_set_device_state(device_item, DM_DEVICE_DIRECTION_OUT, DM_DEVICE_STATE_ACTIVATED); - else if (state == PA_SINK_SUSPENDED) - pa_device_manager_set_device_state(device_item, DM_DEVICE_DIRECTION_OUT, DM_DEVICE_STATE_DEACTIVATED); - } + pa_log_info("Load type devices : %s %s %s", type_info->type, pa_strempty(type_info->profile), + is_playback ? "playback" : "capture"); + + if (is_playback) { + pcm_devices = type_info->playback_devices; + file_infos = dm->file_map->playback; + } else { + pcm_devices = type_info->capture_devices; + file_infos = dm->file_map->capture; + } + + if (!pcm_devices || !file_infos) { + pa_log_error("No information to load"); + return -1; + } + + PA_HASHMAP_FOREACH_KEY(device_string, pcm_devices, state, role) { + params = _file_infos_get_param(file_infos, device_string, role); + /* Check duplicate load */ + if (is_playback && _core_get_sink(dm->core, device_string, params)) { + pa_log_debug("Already loaded %s %s", device_string, params); + continue; } - } else if (pa_source_isinstance(o)) { - pa_source *s = PA_SOURCE(o); - pa_source_state_t state = pa_source_get_state(s); - pa_log_debug("=========== Source(%p,%s) state has been changed to [%d](0:RUNNING, 1:IDLE, 2:SUSPEND) ==========", s, s->name, state); - if (s->use_internal_codec) { - if (state == PA_SOURCE_SUSPENDED) { - PA_IDXSET_FOREACH(_device_item, dm->device_list, idx) { - use_internal_codec = pa_device_manager_is_device_use_internal_codec(_device_item, DM_DEVICE_DIRECTION_IN, DEVICE_ROLE_NORMAL); - if (use_internal_codec) - pa_device_manager_set_device_state(_device_item, DM_DEVICE_DIRECTION_IN, DM_DEVICE_STATE_DEACTIVATED); - } - } - } else { - if ((device_item = pa_device_manager_get_device_with_source(s))) { - if (state == PA_SOURCE_RUNNING) - pa_device_manager_set_device_state(device_item, DM_DEVICE_DIRECTION_IN, DM_DEVICE_STATE_ACTIVATED); - else if (state == PA_SOURCE_SUSPENDED) - pa_device_manager_set_device_state(device_item, DM_DEVICE_DIRECTION_IN, DM_DEVICE_STATE_DEACTIVATED); - } + if (!is_playback && _core_get_source(dm->core, device_string, params)) { + pa_log_debug("Already loaded %s %s", device_string, params); + continue; + } + if (!(load_device(dm->core, is_playback, device_string, params))) { + pa_log_warn("load device failed %s %s", device_string, params); } } - return PA_HOOK_OK; + return 0; } -static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, pa_device_manager *dm) { - const char *device_string = NULL, *role = NULL, *device_string_removed_params = NULL; - struct device_file_info *file_info = NULL; - dm_device_class_t device_class; +/* + Handle device connection detected through dbus. + First, update device-status hashmap. + And if correnspondent sink/sources for device_type exist, should make device and notify it. + Use [device_type->roles] mappings in sink/source for find proper sink/source. +*/ +static void handle_device_connected(pa_device_manager *dm, const char *type, const char *device_profile, + const char *name, const char *system_id, device_detected_type_t detected_type) { + struct device_type_info *type_info; + pa_tz_device *device; + pa_tz_device_new_data data; - pa_assert(c); - pa_assert(source); - pa_assert(source->proplist); pa_assert(dm); + pa_assert(dm->device_status); + pa_assert(dm->device_list); - if (pulse_device_class_is_monitor(source->proplist)) { - pa_log_debug("This device's class is monitor. Skip this"); - return PA_HOOK_OK; - } + pa_log_info("Device connected, type(%s) profile(%s) name(%s) system_id(%s) detected_type(%d)", + type, pa_strempty(device_profile), pa_strempty(name), pa_strempty(system_id), detected_type); - pa_log_info("========== Source Put Hook Callback '%s'(%d) ==========", source->name, source->index); + type_info = _device_manager_get_type_info(dm->type_infos, type, device_profile); + if (device_type_is_equal(type, device_profile, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO)) { + pa_tz_profile_new_data profile_data; - device_class = pulse_device_get_class(source, PA_DEVICE_TYPE_SOURCE); - pa_log_info("Device Class '%s'", device_class_to_string(device_class)); + /* Use profile_new_data, because BT is multi profile type */ + pa_tz_profile_new_data_init(&profile_data); + _fill_profile_new_data_basic(&profile_data, DEVICE_PROFILE_BT_SCO, + DM_DEVICE_DIRECTION_BOTH, true, dm); - if (!(device_string = pulse_device_get_device_string(source, PA_DEVICE_TYPE_SOURCE))) { - return PA_HOOK_OK; - } else { - pa_log_info("Device String '%s'", device_string); - } + _fill_profile_new_data_sinks(&profile_data, type_info, dm); + _fill_profile_new_data_sources(&profile_data, type_info, dm); - if (device_class == DM_DEVICE_CLASS_BT) { - handle_not_predefined_device(dm, source, PA_DEVICE_TYPE_SOURCE, device_class); - } else if ((file_info = _device_manager_get_file_info(dm->file_map->capture, device_string))) { - /* module's argument includes device-string(ex. device=hw:0,0 ), - but key params for device_types hashmap is not. */ - if (!(device_string_removed_params = pulse_device_get_device_string_removed_argument(source, PA_DEVICE_TYPE_SOURCE))) { - pa_log_debug("argument null"); - return PA_HOOK_OK; - } - if (!(role = device_file_info_get_role_with_params(file_info, device_string_removed_params))) { - pa_log_error("No role for %s", file_info->device_string); - return PA_HOOK_OK; + device = _device_list_get_device(dm, DEVICE_TYPE_BT, system_id); + if (device) { + /* Just add profile, if already exists */ + pa_tz_device_add_profile(device, &profile_data, false); + } else { + /* Create new device with profile */ + + pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, dm->dbus_conn); + pa_tz_device_new_data_set_type(&data, DEVICE_TYPE_BT); + pa_tz_device_new_data_set_name(&data, name); + pa_tz_device_new_data_set_system_id(&data, system_id); + pa_tz_device_new_data_add_profile(&data, &profile_data, true); + + pa_tz_device_new(&data); + pa_tz_device_new_data_done(&data); } + pa_tz_profile_new_data_done(&profile_data); + } else if (device_type_is_equal(type, device_profile, DEVICE_TYPE_AUDIO_JACK, NULL)) { + dm_device_direction_t direction; - handle_predefined_device_loaded(source, PA_DEVICE_TYPE_SOURCE, device_class, device_string, role, dm); - } else { - pa_log_debug("Not-predefined device"); - handle_not_predefined_device(dm, source, PA_DEVICE_TYPE_SOURCE, device_class); - } + if (detected_type == DEVICE_CONNECTED_AUDIO_JACK_4P) + direction = DM_DEVICE_DIRECTION_BOTH; + else + direction = DM_DEVICE_DIRECTION_OUT; + pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, NULL); + _fill_new_data_basic(&data, DEVICE_TYPE_AUDIO_JACK, direction, true, dm); + _fill_new_data_sinks(&data, type_info, dm); + _fill_new_data_sources(&data, type_info, dm); + + pa_tz_device_new(&data); + pa_tz_device_new_data_done(&data); + } else if (device_type_is_equal(type, device_profile, DEVICE_TYPE_HDMI, NULL)) { + pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, NULL); + _fill_new_data_basic(&data, DEVICE_TYPE_HDMI, DM_DEVICE_DIRECTION_OUT, true, dm); + _fill_new_data_sinks(&data, type_info, dm); + + pa_tz_device_new(&data); + pa_tz_device_new_data_done(&data); + } else if (device_type_is_equal(type, device_profile, DEVICE_TYPE_FORWARDING, NULL)) { + pa_tz_device *spk_device; + pa_sink *spk_sink; - dump_device_list_info(dm, PA_LOG_INFO); - return PA_HOOK_OK; -} + if (!(spk_device = _device_list_get_device(dm, DEVICE_TYPE_SPEAKER, NULL))) { + pa_log_error("Get speaker device failed"); + return; + } + if (!(spk_sink = pa_tz_device_get_sink(spk_device, DEVICE_ROLE_NORMAL))) { + pa_log_error("Get speaker sink failed"); + return; + } -static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, pa_device_manager *dm) { - pa_assert(c); - pa_assert(source); - pa_assert(source->proplist); - pa_assert(dm); + pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, NULL); + _fill_new_data_basic(&data, DEVICE_TYPE_FORWARDING, DM_DEVICE_DIRECTION_BOTH, true, dm); + pa_tz_device_new_data_add_sink(&data, DEVICE_ROLE_NORMAL, spk_sink); + pa_tz_device_new_data_add_source(&data, DEVICE_ROLE_NORMAL, spk_sink->monitor_source); - if (pulse_device_class_is_monitor(source->proplist)) { - pa_log_debug("This device's class is monitor. Skip this"); - return PA_HOOK_OK; + pa_tz_device_new(&data); + pa_tz_device_new_data_done(&data); + } else { + dm_device_direction_t direction; + + direction = device_type_get_static_direction(type, device_profile); + if (direction != DM_DEVICE_DIRECTION_NONE) { + pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, NULL); + _fill_new_data_basic(&data, type, direction, true, dm); + if (direction & DM_DEVICE_DIRECTION_OUT) + _fill_new_data_sinks(&data, type_info, dm); + if (direction & DM_DEVICE_DIRECTION_IN) + _fill_new_data_sources(&data, type_info, dm); + + pa_tz_device_new(&data); + pa_tz_device_new_data_done(&data); + } else { + pa_log_error("Invalid case : not static direction"); + return ; + } } - pa_log_info("========== Source unlink Hook Callback '%s'(%d) ==========", source->name, source->index); - handle_source_unloaded(source, dm); - dump_device_list_info(dm, PA_LOG_INFO); - - return PA_HOOK_OK; + return ; } /* - Build params for load sink or source, and load it. + Handle device disconnection detected through dbus. + First, update device-status hashmap. + And if there is device which has the device_type, remove it. */ +static int handle_device_disconnected(pa_device_manager *dm, const char *type, const char *device_profile, const char *system_id) { + pa_tz_device *device; + uint32_t n_profile; -static void* load_device(pa_core *c, pa_device_type_t pdt, const char *device_string, const char *device_params) { - const char *args = NULL; - const char *module_name; - pa_module *module; - pa_sink *sink; - pa_source *source; - uint32_t device_idx; - dm_device_class_t device_class; - - pa_assert(c); - pa_assert(device_string); - pa_assert(device_params); - - pa_log_info("Load %s Device : String'%s' Param'%s'", pdt == PA_DEVICE_TYPE_SINK ? "Playback" : "Capture", device_string, device_params); + pa_assert(dm); + pa_assert(dm->device_status); - device_class = device_string_get_class(device_string); - if (device_class <= DM_DEVICE_CLASS_NONE || device_class >= DM_DEVICE_CLASS_MAX) { - pa_log_warn("Invalid device_string '%s'", device_string); - return NULL; - } + pa_log_info("Device type(%s) profile(%s) system_id(%s) disconnected", + type, pa_strempty(device_profile), pa_strempty(system_id)); - if (!(module_name = device_class_get_module_name(device_class, pdt))) { - pa_log_error("Get proper module name to load failed"); - return NULL; - } - if (!(args = build_params_to_load_device(device_string, device_params, device_class))) { - pa_log_error("Get proper module name to load failed"); - return NULL; - } - if (!(module = pa_module_load(c, module_name, args))) { - pa_log_error("Load module with name '%s' argu '%s' failed", module_name, args); - return NULL; + device = _device_list_get_device(dm, type, system_id); + if (!device) { + pa_log_error("Disconnection detected but no device for that"); + return -1; } + if ((n_profile = pa_tz_device_get_profile_num(device)) > 1) + pa_tz_device_remove_profile(device, device_profile); + else + pa_tz_device_free(device); - if (pdt == PA_DEVICE_TYPE_SINK) { - PA_IDXSET_FOREACH(sink, c->sinks, device_idx) { - if (sink->module == module) { - return sink; - } - } - } else { - PA_IDXSET_FOREACH(source, c->sources, device_idx) { - if (source->module == module) { - return source; - } - } - } - - return NULL; + return 0; } -/* - Load sink/sources with information written in device-file map, - If there is several roles in same device-file, then first load with 'normal' params - and other roles with same params just reference it. if there is a role which is on same device - but have different params, then do not load it. (ex.uhqa) - This does not make device_item , just load sink or source. -*/ static int load_builtin_devices(pa_device_manager *dm) { - void *role_state = NULL; - struct device_file_info *file_info = NULL; - const char *params, *role; - uint32_t file_idx; + struct device_type_info *type_info; + uint32_t type_idx; + device_detected_type_t detected_type = DEVICE_CONNECTED; + const char *type, *profile; pa_assert(dm); pa_log_debug("\n==================== Load Builtin Devices ===================="); - if (dm->file_map->playback) { - PA_IDXSET_FOREACH(file_info, dm->file_map->playback, file_idx) { - pa_log_debug("---------------- load sink for '%s' ------------------", file_info->device_string); + PA_IDXSET_FOREACH(type_info, dm->type_infos, type_idx) { - /* if normal device exists , load first */ - if ((params = pa_hashmap_get(file_info->roles, DEVICE_ROLE_NORMAL))) { - if (!load_device(dm->core, PA_DEVICE_TYPE_SINK, file_info->device_string, params)) - pa_log_error("load normal playback device failed"); - } + type = type_info->type; + profile = type_info->profile; - PA_HASHMAP_FOREACH_KEY(params, file_info->roles, role_state, role) { - if (pa_streq(role, DEVICE_ROLE_NORMAL)) - continue; - pa_log_debug("load sink for role %s", role); - if (!pulse_device_loaded_with_param(dm->core, PA_DEVICE_TYPE_SINK, file_info->device_string, params)) { - if (!load_device(dm->core, PA_DEVICE_TYPE_SINK, file_info->device_string, params)) - pa_log_error("load playback device failed"); - } - } + pa_log_info("type_info : %s %s", type, pa_strempty(profile)); + detected_type = _device_get_detected(dm, type, profile, NULL); + if (detected_type == DEVICE_DISCONNECTED) { + pa_log_info("Not detected yet"); + continue; } - } - - if (dm->file_map->capture) { - PA_IDXSET_FOREACH(file_info, dm->file_map->capture, file_idx) { - pa_log_debug("---------------- load source for '%s' ------------------", file_info->device_string); - /* if normal device exists , load first */ - if ((params = pa_hashmap_get(file_info->roles, DEVICE_ROLE_NORMAL))) { - if (!load_device(dm->core, PA_DEVICE_TYPE_SOURCE, file_info->device_string, params)) pa_log_error("load normal capture device failed"); + if (device_type_is_equal(type, profile, DEVICE_TYPE_AUDIO_JACK, NULL)) { + if (detected_type == DEVICE_CONNECTED_AUDIO_JACK_4P) { + _load_type_devices(type_info, true, dm); + _load_type_devices(type_info, false, dm); + } else { + _load_type_devices(type_info, true, dm); } - - PA_HASHMAP_FOREACH_KEY(params, file_info->roles, role_state, role) { - if (pa_streq(role, DEVICE_ROLE_NORMAL)) - continue; - pa_log_debug("load source for role %s", role); - if (!pulse_device_loaded_with_param(dm->core, PA_DEVICE_TYPE_SOURCE, file_info->device_string, params)) { - if (!load_device(dm->core, PA_DEVICE_TYPE_SOURCE, file_info->device_string, params)) { - pa_log_error("load capture device failed"); - } - } + handle_device_connected(dm, type, profile, NULL, NULL, detected_type); + } else if (device_type_is_use_external_card(type, profile) == false) { + dm_device_direction_t direction; + direction = device_type_get_static_direction(type, profile); + if (direction == DM_DEVICE_DIRECTION_NONE) { + pa_log_warn("Wrong direction"); + continue; } + if (direction & DM_DEVICE_DIRECTION_OUT) + _load_type_devices(type_info, true, dm); + if (direction & DM_DEVICE_DIRECTION_IN) + _load_type_devices(type_info, false, dm); + handle_device_connected(dm, type, profile, NULL, NULL, detected_type); + } else { + pa_log_warn("Invalid case"); } } return 0; } - /***************** Parse json file *******************/ static pa_hashmap* parse_device_role_object(json_object *device_role_o) { pa_hashmap *roles = NULL; @@ -2836,7 +2063,7 @@ static pa_hashmap* parse_device_role_object(json_object *device_role_o) { roles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); if (!roles) { pa_log_debug("hashmap new failed"); - goto failed; + goto fail; } it = json_object_iter_begin(device_role_o); @@ -2853,7 +2080,7 @@ static pa_hashmap* parse_device_role_object(json_object *device_role_o) { if (device_role_is_valid(device_role)) { if (pa_hashmap_put(roles, (void *)device_role, (void *)params)) { pa_log_error("put new role to hashmap faild"); - goto failed; + goto fail; } } else { pa_log_error("Invalid device role '%s'", device_role); @@ -2870,7 +2097,7 @@ static pa_hashmap* parse_device_role_object(json_object *device_role_o) { return roles; -failed: +fail: if (roles) pa_hashmap_free(roles); @@ -2902,7 +2129,7 @@ static struct device_file_info* parse_device_file_object(json_object *device_fil if (json_object_object_get_ex(device_file_o, DEVICE_TYPE_PROP_ROLE, &device_file_prop_o)) { if (!(roles = parse_device_role_object(device_file_prop_o))) { pa_log_error("Parse device role for '%s' failed", device_string); - goto failed; + goto fail; } } else { pa_log_error("Get device role object failed"); @@ -2917,7 +2144,7 @@ static struct device_file_info* parse_device_file_object(json_object *device_fil return file_info; -failed: +fail: return NULL; } @@ -2941,11 +2168,11 @@ static pa_idxset* parse_device_file_array_object(json_object *device_file_array_ pa_idxset_put(device_files, file_info, NULL); } else { pa_log_error("parse device file object failed"); - goto failed; + goto fail; } } else { pa_log_error("Get device file object failed"); - goto failed; + goto fail; } } @@ -2953,8 +2180,10 @@ static pa_idxset* parse_device_file_array_object(json_object *device_file_array_ pa_idxset_free(device_files, NULL); device_files = NULL; } + return device_files; -failed: + +fail: if (device_files) pa_xfree(device_files); return NULL; @@ -3019,11 +2248,11 @@ static pa_hashmap* parse_device_role_map(json_object *device_role_map_o) { if (device_role_is_valid(device_role)) { if (pa_hashmap_put(roles, (void *)device_role, (void *)device_string)) { pa_log_error("put new role to hashmap faild"); - goto failed; + goto fail; } } else { pa_log_error("Invalid device role '%s'", device_role); - goto failed; + goto fail; } json_object_iter_next(&it); @@ -3031,7 +2260,7 @@ static pa_hashmap* parse_device_role_map(json_object *device_role_map_o) { return roles; -failed: +fail: if (roles) pa_xfree(roles); @@ -3044,7 +2273,6 @@ static pa_idxset* parse_device_type_infos() { json_object *o, *device_array_o = NULL; int device_type_num = 0; int device_type_idx = 0; - json_bool builtin; struct device_type_info *type_info = NULL; //pa_hashmap *type_infos = NULL; pa_idxset *type_infos = NULL; @@ -3065,16 +2293,16 @@ static pa_idxset* parse_device_type_infos() { if ((device_o = json_object_array_get_idx(device_array_o, device_type_idx)) && json_object_is_type(device_o, json_type_object)) { json_object *device_prop_o; - const char *device_type = NULL, *device_profile = NULL; + const char *type = NULL, *device_profile = NULL; type_info = pa_xmalloc0(sizeof(struct device_type_info)); if (json_object_object_get_ex(device_o, DEVICE_TYPE_PROP_DEVICE_TYPE, &device_prop_o) && json_object_is_type(device_prop_o, json_type_string)) { - device_type = json_object_get_string(device_prop_o); - pa_log_info("[ Device - %s ]", device_type); - type_info->type = device_type; + type = json_object_get_string(device_prop_o); + pa_log_info("[ Device - %s ]", type); + type_info->type = type; } else { pa_log_error("Get device type failed"); - goto failed; + goto fail; } if (json_object_object_get_ex(device_o, "profile", &device_prop_o) && json_object_is_type(device_prop_o, json_type_string)) { device_profile = json_object_get_string(device_prop_o); @@ -3104,7 +2332,7 @@ static pa_idxset* parse_device_type_infos() { } return type_infos; -failed: +fail: if (type_infos) pa_xfree(type_infos); @@ -3112,139 +2340,34 @@ failed: } /* - Handle device connection detected through dbus. - First, update device-status hashmap. - And if correnspondent sink/sources for device_type exist, should make device_item and notify it. - Use [device_type->roles] mappings in sink/source for find proper sink/source. -*/ -static int handle_device_connected(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *name, const char *identifier, int detected_type) { - struct device_status_info *status_info; - struct device_type_info *type_info; - dm_device *device_item; - dm_device_profile *profile_item; - - pa_assert(dm); - pa_assert(dm->device_status); - - pa_log_info("Device %s connected, detected_type : %d", device_type, detected_type); - if (!(status_info = _device_manager_get_status_info(dm->device_status, device_type, device_profile, identifier))) { - pa_log_error("No device_status_info for %s.%s", device_type, device_profile); - return -1; - } - status_info->detected = DEVICE_DETECTED; - status_info->detected_type = detected_type; - - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_type, device_profile))) { - pa_log_error("Failed to get type_info for %s.%s", device_type, device_profile); - return -1; - } - - if ((device_item = _device_manager_get_device(dm->device_list, type_info->type))) { - if ((profile_item = _device_item_get_profile(device_item, type_info->profile))) { - pa_log_debug("device_item for %s.%s already exists", type_info->type, type_info->profile); - return 0; - } - } - - handle_device_type_available(type_info, name, dm); - - return 0; -} - -/* - Handle device disconnection detected through dbus. - First, update device-status hashmap. - And if there is device_item which has the device_type, remove it. -*/ -static int handle_device_disconnected(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *identifier) { - dm_device_profile *profile_item; - dm_device *device_item; - struct device_status_info *status_info; - uint32_t device_idx = 0; - - pa_assert(dm); - pa_assert(dm->device_status); - - pa_log_info("Device %s disconnected", device_type); - if (!(status_info = _device_manager_get_status_info(dm->device_status, device_type, device_profile, identifier))) { - pa_log_error("No device_status_info for %s.%s", device_type, device_profile); - return -1; - } - status_info->detected = DEVICE_NOT_DETECTED; - - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - if (pa_streq(device_item->type, device_type)) { - if ((profile_item = _device_item_get_profile(device_item, device_profile))) { - if (_device_item_get_size(device_item) == 1) { - _device_list_remove_device(dm->device_list, device_item, dm); - notify_device_connection_changed(device_item, false, dm); - } - destroy_device_profile(profile_item, dm); - } else { - pa_log_debug("no matching profile"); - } - } - } - - return 0; -} - - -/* look detected status which is external value, make conversion to internal consistent value, and handle it device_type, device_profile : which type of device is detected - identifier : identifier among same device types for support multi-device + system_id : system_id among same device types for support multi-device */ -static int handle_device_status_changed(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *name, const char *identifier, int detected_status) { +static int handle_device_status_changed(pa_device_manager *dm, const char *type, + const char *profile, const char *name, const char *system_id, device_detected_type_t detected) { pa_assert(dm); - pa_assert(device_type_is_valid(device_type)); - - pa_log_info("Device Status Changed, type : '%s', profile : '%s', identifier : '%s', detected_status : %d", - device_type, device_profile, identifier, detected_status); - if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) { - if (detected_status == EARJACK_DISCONNECTED) { - handle_device_disconnected(dm, device_type, device_profile, identifier); - } else if (detected_status == EARJACK_TYPE_SPK_ONLY) { - handle_device_connected(dm, device_type, device_profile, name, identifier, DEVICE_DETECTED_AUDIO_JACK_OUT_DIREC); - } else if (detected_status == EARJACK_TYPE_SPK_WITH_MIC) { - handle_device_connected(dm, device_type, device_profile, name, identifier, DEVICE_DETECTED_AUDIO_JACK_BOTH_DIREC); - } else { - pa_log_warn("Got invalid audio-jack detected value"); - return -1; - } - } else if (pa_streq(device_type, DEVICE_TYPE_BT) && device_profile && pa_streq(device_profile, DEVICE_PROFILE_BT_SCO)) { - if (detected_status == BT_SCO_DISCONNECTED) { - dm->bt_sco_status = DM_DEVICE_BT_SCO_STATUS_DISCONNECTED; - } else if (detected_status == BT_SCO_CONNECTED) { - dm->bt_sco_status = DM_DEVICE_BT_SCO_STATUS_CONNECTED; - } else { - pa_log_warn("Got invalid bt-sco detected value"); - return -1; - } - } else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) { - if (detected_status == HDMI_AUDIO_DISCONNECTED) { - handle_device_disconnected(dm, device_type, device_profile, identifier); - } else if (detected_status >= HDMI_AUDIO_AVAILABLE) { - handle_device_connected(dm, device_type, device_profile, name, identifier, DEVICE_DETECTED_HDMI); - } else if (detected_status == HDMI_AUDIO_NOT_AVAILABLE) { - pa_log_debug("HDMI audio not available"); - return -1; - } else { - pa_log_warn("Got invalid hdmi detected value"); - return -1; - } - } else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) { - if (detected_status == FORWARDING_DISCONNECTED) { - handle_device_disconnected(dm, device_type, device_profile, identifier); - } else if (detected_status == FORWARDING_CONNECTED) { - handle_device_connected(dm, device_type, device_profile, name, identifier, DEVICE_DETECTED_FORWARDING); - } else { - pa_log_warn("Got invalid mirroring detected value"); - return -1; - } + pa_assert(device_type_is_valid(type)); + + pa_log_info("Device Status Changed, type(%s) profile(%s) system_id(%s), detected_type(%d)", + type, pa_strempty(profile), pa_strempty(system_id), detected); + + if (device_type_is_equal(type, profile, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO)) { + _device_set_detected(dm, type, profile, name, system_id, detected); + if (detected == DEVICE_DISCONNECTED) + handle_device_disconnected(dm, type, profile, system_id); + else + handle_device_connected(dm, type, profile, name, system_id, detected); + } else if (device_type_is_need_detect(type, profile)) { + _device_set_detected(dm, type, profile, name, system_id, detected); + if (detected == DEVICE_DISCONNECTED) + handle_device_disconnected(dm, type, profile, system_id); + else + handle_device_connected(dm, type, profile, name, system_id, detected); } else { - pa_log_debug("unknown device type"); + pa_log_debug("No need to detect type %s %s", type, pa_strempty(profile)); } + return 0; } @@ -3254,82 +2377,101 @@ static int handle_device_status_changed(pa_device_manager *dm, const char *devic So, if device_type is not detected through dbus, let's initialize them to detected. (ex. spk, rcv,...) If not, initialize to not detected. */ -static pa_idxset* device_type_status_init(pa_idxset *type_infos) { - int avail_cond_idx = 0, avail_cond_num = 0, correct_avail_cond = 0; +static void device_type_status_init(pa_device_manager *manager) { struct device_type_info *type_info; - struct device_status_info *status_info; - pa_idxset *device_status; uint32_t type_idx; + const char *type, *profile; - pa_assert(type_infos); + pa_assert(manager); + pa_assert(manager->type_infos); pa_log_debug("\n==================== Init Device Status ===================="); - device_status = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - - PA_IDXSET_FOREACH(type_info, type_infos, type_idx) { - status_info = (struct device_status_info *) pa_xmalloc0(sizeof(struct device_status_info)); - status_info->type = type_info->type; - status_info->profile = type_info->profile; - if (!compare_device_type(status_info->type, status_info->profile, DEVICE_TYPE_AUDIO_JACK, NULL)) { + PA_IDXSET_FOREACH(type_info, manager->type_infos, type_idx) { + type = type_info->type; + profile = type_info->profile; + if (device_type_is_equal(type, profile, DEVICE_TYPE_AUDIO_JACK, NULL)) { int earjack_status = 0; if (vconf_get_int(VCONFKEY_SYSMAN_EARJACK, &earjack_status) < 0) { - status_info->detected = DEVICE_NOT_DETECTED; pa_log_error("Get earjack status failed"); - } else if (earjack_status == EARJACK_DISCONNECTED) { - status_info->detected = DEVICE_NOT_DETECTED; - } else if (earjack_status == EARJACK_TYPE_SPK_ONLY) { - status_info->detected = DEVICE_DETECTED; - status_info->detected_type = DEVICE_DETECTED_AUDIO_JACK_OUT_DIREC; - } else if (earjack_status == EARJACK_TYPE_SPK_WITH_MIC) { - status_info->detected = DEVICE_DETECTED; - status_info->detected_type = DEVICE_DETECTED_AUDIO_JACK_BOTH_DIREC; - } else { - status_info->detected = DEVICE_NOT_DETECTED; - pa_log_warn("Unknown earjack status : %d", earjack_status); + continue; } - } else if (!compare_device_type(status_info->type, status_info->profile, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO)) { - status_info->detected = DEVICE_NOT_DETECTED; - } else if (!compare_device_type(status_info->type, status_info->profile, DEVICE_TYPE_HDMI, NULL)) { - status_info->detected = DEVICE_NOT_DETECTED; - } else if (!compare_device_type(status_info->type, status_info->profile, DEVICE_TYPE_FORWARDING, NULL)) { + if (earjack_status == EARJACK_TYPE_SPK_ONLY) + _device_set_detected(manager, type, profile, NULL, NULL, DEVICE_CONNECTED_AUDIO_JACK_3P); + else if (earjack_status == EARJACK_TYPE_SPK_WITH_MIC) + _device_set_detected(manager, type, profile, NULL, NULL, DEVICE_CONNECTED_AUDIO_JACK_4P); + else if (earjack_status == EARJACK_DISCONNECTED) + _device_set_detected(manager, type, profile, NULL, NULL, DEVICE_DISCONNECTED); + else + pa_log_warn("Unknown earjack status : %d", earjack_status); + } else if (device_type_is_equal(type, profile, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO)) { + _device_set_detected(manager, type, profile, NULL, NULL, DEVICE_DISCONNECTED); + } else if (device_type_is_equal(type, profile, DEVICE_TYPE_HDMI, NULL)) { + _device_set_detected(manager, type, profile, NULL, NULL, DEVICE_DISCONNECTED); + } else if (device_type_is_equal(type, profile, DEVICE_TYPE_FORWARDING, NULL)) { int miracast_wfd_status = 0; if (vconf_get_bool(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, &miracast_wfd_status) < 0) { - status_info->detected = DEVICE_NOT_DETECTED; pa_log_error("Get mirroring status failed"); - } else if (miracast_wfd_status == FORWARDING_DISCONNECTED) { - status_info->detected = DEVICE_NOT_DETECTED; - } else if (miracast_wfd_status == FORWARDING_CONNECTED) { - status_info->detected = DEVICE_DETECTED; - status_info->detected_type = DEVICE_DETECTED_FORWARDING; - } else { - status_info->detected = DEVICE_NOT_DETECTED; - pa_log_warn("Unknown mirroring status : %d", miracast_wfd_status); + continue; } + if (miracast_wfd_status == FORWARDING_CONNECTED) + _device_set_detected(manager, type, profile, NULL, NULL, DEVICE_CONNECTED); } else { - status_info->detected = DEVICE_DETECTED; + _device_set_detected(manager, type, profile, NULL, NULL, DEVICE_CONNECTED); } - - pa_log_debug("Set %-17s %s detected", type_info->type, (status_info->detected == DEVICE_DETECTED) ? "" : "not"); - pa_idxset_put(device_status, status_info, NULL); } - return device_status; + return ; } -static int device_list_init(pa_device_manager *dm) { - pa_assert(dm); +#ifdef HAVE_DBUS - dm->device_list = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); +static int _translate_external_value(const char *type, const char *profile, int value, device_detected_type_t *detected) { + + if (!type || !detected) { + pa_log_error("Invalid Parameter for translate"); + return -1; + } + + if (device_type_is_equal(DEVICE_TYPE_AUDIO_JACK, NULL, type, profile)) { + if (value == EARJACK_DISCONNECTED) + *detected = DEVICE_DISCONNECTED; + else if (value == EARJACK_TYPE_SPK_ONLY) + *detected = DEVICE_CONNECTED_AUDIO_JACK_3P; + else if (value == EARJACK_TYPE_SPK_WITH_MIC) + *detected = DEVICE_CONNECTED_AUDIO_JACK_4P; + else + return -1; + } else if (device_type_is_equal(DEVICE_TYPE_HDMI, NULL, type, profile)) { + if (value == HDMI_AUDIO_DISCONNECTED) + *detected = DEVICE_DISCONNECTED; + else if (value == HDMI_AUDIO_AVAILABLE) + *detected = DEVICE_CONNECTED; + else + return -1; + } else if (device_type_is_equal(DEVICE_TYPE_FORWARDING, NULL, type, profile)) { + if (value == FORWARDING_DISCONNECTED) + *detected = DEVICE_DISCONNECTED; + else if (value == FORWARDING_CONNECTED) + *detected = DEVICE_CONNECTED; + else + return -1; + } else if (device_type_is_equal(DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, type, profile)) { + if (value == BT_SCO_DISCONNECTED) + *detected = DEVICE_DISCONNECTED; + else if (value == BT_SCO_CONNECTED) + *detected = DEVICE_CONNECTED_SCO; + else + return -1; + } return 0; } -#ifdef HAVE_DBUS - static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DBusMessage *s, void *userdata) { DBusError error; int status = 0; pa_device_manager *dm = (pa_device_manager *) userdata; + device_detected_type_t detected; pa_assert(userdata); @@ -3345,19 +2487,31 @@ static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DB if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { goto fail; } else { - handle_device_status_changed(dm, DEVICE_TYPE_AUDIO_JACK, NULL, NULL, NULL, status); + if (_translate_external_value(DEVICE_TYPE_AUDIO_JACK, NULL, status, &detected) < 0) { + pa_log_warn("failed to translate audio-jack detected value"); + goto fail; + } + handle_device_status_changed(dm, DEVICE_TYPE_AUDIO_JACK, NULL, NULL, NULL, detected); } } else if (dbus_message_is_signal(s, DBUS_INTERFACE_DEVICED_SYSNOTI, "ChangedHDMIAudio")) { if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { goto fail; } else { - handle_device_status_changed(dm, DEVICE_TYPE_HDMI, NULL, NULL, NULL, status); + if (_translate_external_value(DEVICE_TYPE_HDMI, NULL, status, &detected) < 0) { + pa_log_warn("failed to translate HDMI detected value"); + goto fail; + } + handle_device_status_changed(dm, DEVICE_TYPE_HDMI, NULL, NULL, NULL, detected); } } else if (dbus_message_is_signal(s, DBUS_INTERFACE_MIRRORING_SERVER, "miracast_wfd_source_status_changed")) { if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { goto fail; } else { - handle_device_status_changed(dm, DEVICE_TYPE_FORWARDING, NULL, NULL, NULL, status); + if (_translate_external_value(DEVICE_TYPE_FORWARDING, NULL, status, &detected) < 0) { + pa_log_warn("failed to translate forwarding detected value"); + goto fail; + } + handle_device_status_changed(dm, DEVICE_TYPE_FORWARDING, NULL, NULL, NULL, detected); } } else if (dbus_message_is_signal(s, DBUS_INTERFACE_BLUEZ_HEADSET, "PropertyChanged")) { DBusMessageIter msg_iter, variant_iter; @@ -3396,7 +2550,12 @@ static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DB } else { status = BT_SCO_DISCONNECTED; } - handle_device_status_changed(dm, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, name, NULL, status); + if (_translate_external_value(DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, status, &detected) < 0) { + pa_log_warn("failed to translate bt-sco detected value"); + goto fail; + } + handle_device_status_changed(dm, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, + name, dbus_message_get_path(s), detected); } } } else { @@ -3453,129 +2612,99 @@ static void unwatch_signals(pa_device_manager *dm) { } -static void send_device_connected_signal(uint32_t event_id, dm_device *device_item, bool connected, pa_device_manager *dm) { +static void send_device_connected_signal(uint32_t event_id, pa_tz_device *device, bool connected, pa_device_manager *dm) { DBusMessage *signal_msg; DBusMessageIter msg_iter, device_iter; - dm_device_profile *profile_item; dbus_bool_t _connected = connected; dm_device_state_t compound_state; - dbus_int32_t device_id; - const char *device_info_str; + dbus_int32_t device_id, direction; + char *type, *name; - pa_assert(device_item); - pa_assert(device_item->profiles); + pa_assert(device); pa_assert(dm); pa_log_info("Send following device %s signal", connected ? "Connected" : "Disconnected"); - dump_device_info(device_item, PA_LOG_INFO); pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceConnected")); dbus_message_iter_init_append(signal_msg, &msg_iter); dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_UINT32, &event_id); pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); - if (!(profile_item = _device_item_get_active_profile(device_item))) { - pa_log_error("active profile null"); - goto finish; - } - device_id = (dbus_int32_t) device_item->id; - compound_state = COMPOUND_STATE(profile_item); + direction = (dbus_int32_t) pa_tz_device_get_direction(device); + type = pa_tz_device_get_type(device); + name = pa_tz_device_get_name(device); + + device_id = (dbus_int32_t) pa_tz_device_get_id(device); + compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH); dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &device_item->type); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &profile_item->direction); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction); dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &compound_state); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &device_item->name); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter)); dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_BOOLEAN, &_connected); pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); -finish: + dbus_message_unref(signal_msg); } -static void send_device_info_changed_signal(uint32_t event_id, dm_device *device_item, int changed_type, pa_device_manager *dm) { +static void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *device, int changed_type, pa_device_manager *dm) { DBusMessage *signal_msg; DBusMessageIter msg_iter, device_iter; - dm_device_profile *profile_item; dm_device_state_t compound_state; - dbus_int32_t device_id; - const char *device_info_str; + dbus_int32_t device_id, direction; + char *type, *name; - pa_assert(device_item); - pa_assert(device_item->profiles); + pa_assert(device); pa_assert(dm); pa_log_debug("Send following device info changed signal"); - dump_device_info(device_item, PA_LOG_DEBUG); pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceInfoChanged")); dbus_message_iter_init_append(signal_msg, &msg_iter); dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_UINT32, &event_id); pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); - if (!(profile_item = _device_item_get_active_profile(device_item))) { - pa_log_error("active profile null"); - goto finish; - } - device_id = (dbus_int32_t) device_item->id; - compound_state = COMPOUND_STATE(profile_item); + + direction = (dbus_int32_t) pa_tz_device_get_direction(device); + type = pa_tz_device_get_type(device); + name = pa_tz_device_get_name(device); + device_id = (dbus_int32_t) pa_tz_device_get_id(device); + compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &device_item->type); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &profile_item->direction); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction); dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &compound_state); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &device_item->name); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter)); dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &changed_type); pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); -finish: - dbus_message_unref(signal_msg); -} - -static void notify_device_connection_changed(dm_device *device_item, bool connected, pa_device_manager *dm) { - pa_device_manager_hook_data_for_conn_changed hook_data; - uint32_t event_id; - event_id = _new_event_id(); - - hook_data.event_id = event_id; - hook_data.is_connected = connected; - hook_data.device = device_item; - pa_log_info("notify_device_connection_changed"); - pa_hook_fire(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), &hook_data); - send_device_connected_signal(event_id, device_item, connected, dm); -} - -static void notify_device_info_changed(dm_device *device_item, dm_device_changed_info_t changed_type, pa_device_manager *dm) { - pa_device_manager_hook_data_for_info_changed hook_data; - uint32_t event_id; - - event_id = _new_event_id(); - - send_device_info_changed_signal(event_id, device_item, changed_type, dm); - - hook_data.event_id = event_id; - hook_data.changed_info = changed_type; - hook_data.device = device_item; - pa_hook_fire(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED), &hook_data); + dbus_message_unref(signal_msg); } -static bool device_item_match_for_mask(dm_device *device_item, int device_flags, pa_device_manager *dm) { - dm_device_profile *profile_item = NULL; +static bool device_item_match_for_mask(pa_tz_device *device, int device_flags, pa_device_manager *dm) { bool match = false; int need_to_check_for_io_direction = device_flags & DEVICE_IO_DIRECTION_FLAGS; int need_to_check_for_state = device_flags & DEVICE_STATE_FLAGS; int need_to_check_for_type = device_flags & DEVICE_TYPE_FLAGS; + dm_device_direction_t direction; + char *type; - pa_assert(device_item); + pa_assert(device); if (device_flags == DEVICE_ALL_FLAG) return true; - profile_item = _device_item_get_active_profile(device_item); + direction = pa_tz_device_get_direction(device); + type = pa_tz_device_get_type(device); + if (need_to_check_for_io_direction) { - if ((profile_item->direction == DM_DEVICE_DIRECTION_IN) && (device_flags & DEVICE_IO_DIRECTION_IN_FLAG)) match = true; - else if ((profile_item->direction == DM_DEVICE_DIRECTION_OUT) && (device_flags & DEVICE_IO_DIRECTION_OUT_FLAG)) match = true; - else if ((profile_item->direction == DM_DEVICE_DIRECTION_BOTH) && (device_flags & DEVICE_IO_DIRECTION_BOTH_FLAG)) match = true; + if ((direction == DM_DEVICE_DIRECTION_IN) && (device_flags & DEVICE_IO_DIRECTION_IN_FLAG)) match = true; + else if ((direction == DM_DEVICE_DIRECTION_OUT) && (device_flags & DEVICE_IO_DIRECTION_OUT_FLAG)) match = true; + else if ((direction == DM_DEVICE_DIRECTION_BOTH) && (device_flags & DEVICE_IO_DIRECTION_BOTH_FLAG)) match = true; if (match) { if (!need_to_check_for_state && !need_to_check_for_type) return true; } else { @@ -3584,9 +2713,9 @@ static bool device_item_match_for_mask(dm_device *device_item, int device_flags, } if (need_to_check_for_state) { match = false; - if ((COMPOUND_STATE(profile_item) == DM_DEVICE_STATE_DEACTIVATED) && (device_flags & DEVICE_STATE_DEACTIVATED_FLAG)) + if ((pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH) == DM_DEVICE_STATE_DEACTIVATED) && (device_flags & DEVICE_STATE_DEACTIVATED_FLAG)) match = true; - else if ((COMPOUND_STATE(profile_item) == DM_DEVICE_STATE_ACTIVATED) && (device_flags & DEVICE_STATE_ACTIVATED_FLAG)) + else if ((pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH) == DM_DEVICE_STATE_ACTIVATED) && (device_flags & DEVICE_STATE_ACTIVATED_FLAG)) match = true; if (match) { if (!need_to_check_for_type) @@ -3596,104 +2725,15 @@ static bool device_item_match_for_mask(dm_device *device_item, int device_flags, } } if (need_to_check_for_type) { - if (device_type_is_builtin(device_item->type) && (device_flags & DEVICE_TYPE_INTERNAL_FLAG)) + if (device_type_is_builtin(type) && (device_flags & DEVICE_TYPE_INTERNAL_FLAG)) return true; - else if (!device_type_is_builtin(device_item->type) && (device_flags & DEVICE_TYPE_EXTERNAL_FLAG)) + else if (!device_type_is_builtin(type) && (device_flags & DEVICE_TYPE_EXTERNAL_FLAG)) return true; } return false; } - -static int method_call_bt_sco(DBusConnection *conn, bool onoff) { - DBusMessage *msg, *reply; - DBusError err; - const char *method; - - method = onoff ? "Play" : "Stop"; - if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_HFP_AGENT, DBUS_OBJECT_HFP_AGENT, DBUS_INTERFACE_HFP_AGENT, method))) { - pa_log_error("dbus method call failed"); - return -1; - } - - dbus_error_init(&err); - if (!(reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err))) { - pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_HFP_AGENT, method, err.message); - dbus_error_free(&err); - return -1; - } - - dbus_message_unref(reply); - return 0; -} - -static int method_call_bt_sco_get_property(DBusConnection *conn, bool *is_wide_band, bool *nrec) { - DBusMessage *msg, *reply; - DBusMessageIter reply_iter, reply_iter_entry; - DBusError err; - unsigned int codec; - const char *property; - - pa_assert(conn); - - if (!is_wide_band && !nrec) { - return -1; - } - - if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_HFP_AGENT, DBUS_OBJECT_HFP_AGENT, DBUS_INTERFACE_HFP_AGENT, "GetProperties"))) { - pa_log_error("dbus method call failed"); - return -1; - } - - dbus_error_init(&err); - if (!(reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err))) { - pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_HFP_AGENT, "GetProperties", err.message); - dbus_error_free(&err); - return -1; - } - - dbus_message_iter_init(reply, &reply_iter); - - if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) { - pa_log_error("Cannot get reply argument"); - return -1; - } - - dbus_message_iter_recurse(&reply_iter, &reply_iter_entry); - - while (dbus_message_iter_get_arg_type(&reply_iter_entry) == DBUS_TYPE_DICT_ENTRY) { - DBusMessageIter dict_entry, dict_entry_val; - dbus_message_iter_recurse(&reply_iter_entry, &dict_entry); - dbus_message_iter_get_basic(&dict_entry, &property); - pa_log_debug("String received = %s", property); - if (property) { - if (pa_streq("codec", property) && is_wide_band) { - dbus_message_iter_next(&dict_entry); - dbus_message_iter_recurse(&dict_entry, &dict_entry_val); - if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_UINT32) - continue; - dbus_message_iter_get_basic(&dict_entry_val, &codec); - pa_log_debug("Codec = [%d]", codec); - *is_wide_band = (codec == BT_MSBC_CODEC_ID) ? true : false; - } else if (pa_streq("nrec", property) && nrec) { - dbus_message_iter_next(&dict_entry); - dbus_message_iter_recurse(&dict_entry, &dict_entry_val); - if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_BOOLEAN) - continue; - dbus_message_iter_get_basic(&dict_entry_val, nrec); - pa_log_debug("nrec= [%d]", *nrec); - } - } - dbus_message_iter_next(&reply_iter_entry); - } - - - dbus_message_unref(reply); - return 0; -} - - static int method_call_bt_get_name(DBusConnection *conn, const char *device_path, char **name) { const char *intf = DBUS_INTERFACE_BLUEZ_DEVICE, *prop = "Alias"; DBusMessage *msg, *reply; @@ -3743,12 +2783,12 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage * pa_device_manager *dm; DBusMessage *reply = NULL; DBusMessageIter msg_iter, array_iter, device_iter; - dm_device *device_item; - dm_device_profile *profile_item; + pa_tz_device *device; dm_device_state_t compound_state; uint32_t device_idx; - dbus_int32_t device_id; + dbus_int32_t device_id, direction; int mask_flags; + char *type, *name; pa_assert(conn); pa_assert(msg); @@ -3767,20 +2807,19 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage * dbus_message_iter_init_append(reply, &msg_iter); pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(isiis)", &array_iter)); - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - if (!(profile_item = pa_idxset_get_by_index(device_item->profiles, device_item->active_profile))) { - pa_log_error("no active profile"); - continue; - } - compound_state = COMPOUND_STATE(profile_item); - if (device_item_match_for_mask(device_item, mask_flags, dm)) { - device_id = (dbus_int32_t)device_item->id; + PA_IDXSET_FOREACH(device, dm->device_list, device_idx) { + compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH); + direction = pa_tz_device_get_direction(device); + type = pa_tz_device_get_type(device); + name = pa_tz_device_get_name(device); + if (device_item_match_for_mask(device, mask_flags, dm)) { + device_id = (dbus_int32_t)pa_tz_device_get_id(device); pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &profile_item->device_item->type); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &profile_item->direction); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction); dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &compound_state); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &device_item->name); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); pa_assert_se(dbus_message_iter_close_container(&array_iter, &device_iter)); } } @@ -3795,8 +2834,7 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage * static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_device_manager *dm; DBusMessage *reply = NULL; - dm_device *device_item; - dm_device_profile *profile_item; + pa_tz_device *device; dbus_bool_t is_bt_on = false; const char *bt_name = "none"; @@ -3810,10 +2848,11 @@ static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, vo pa_assert_se((reply = dbus_message_new_method_return(msg))); - if ((device_item = _device_manager_get_device(dm->device_list, DEVICE_TYPE_BT)) != NULL) { - if ((profile_item = _device_item_get_profile(device_item, DEVICE_PROFILE_BT_A2DP)) != NULL) { + /* FIXME : Give system_id for multi device */ + if ((device = _device_list_get_device(dm, DEVICE_TYPE_BT, NULL)) != NULL) { + if (pa_tz_device_have_profile(device, DEVICE_PROFILE_BT_A2DP)) { is_bt_on = true; - bt_name = device_item->name; + bt_name = pa_tz_device_get_name(device); } } @@ -3829,27 +2868,27 @@ static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, vo static void handle_load_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_device_manager *dm; - char *device_type, *device_profile, *role; + char *type, *device_profile, *role; DBusMessage *reply = NULL; pa_assert_se((reply = dbus_message_new_method_return(msg))); dm = (pa_device_manager *) userdata; pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &device_type, + DBUS_TYPE_STRING, &type, DBUS_TYPE_STRING, &device_profile, DBUS_TYPE_STRING, &role, DBUS_TYPE_INVALID)); if (pa_streq(device_profile, "none")) device_profile = NULL; - pa_device_manager_load_sink(dm, device_type, device_profile, role); + pa_device_manager_load_sink(dm, type, device_profile, role); pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); } static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_device_manager *dm = (pa_device_manager *)userdata; - char *device_type, *device_profile; + char *type, *device_profile; dbus_int32_t status; DBusMessage *reply = NULL; DBusError error; @@ -3858,7 +2897,7 @@ static void handle_test_device_status_change(DBusConnection *conn, DBusMessage * dbus_error_init(&error); if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &device_type, + DBUS_TYPE_STRING, &type, DBUS_TYPE_STRING, &device_profile, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { @@ -3867,11 +2906,11 @@ static void handle_test_device_status_change(DBusConnection *conn, DBusMessage * dbus_error_free(&error); } - pa_log_debug("handle_test_device_status_change, type:%s, profile:%s, status:%d", device_type, device_profile, status); + pa_log_debug("handle_test_device_status_change, type:%s, profile:%s, status:%d", type, device_profile, status); if (pa_streq(device_profile, "none")) device_profile = NULL; - handle_device_status_changed(dm, device_type, device_profile, NULL, NULL, status); + handle_device_status_changed(dm, type, device_profile, NULL, NULL, status); pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); } @@ -4024,361 +3063,158 @@ pa_idxset* pa_device_manager_get_device_list(pa_device_manager *dm) { return dm->device_list; } -dm_device* pa_device_manager_get_device(pa_device_manager *dm, const char *device_type) { +pa_tz_device* pa_device_manager_get_device(pa_device_manager *dm, const char *type) { pa_assert(dm); - return _device_manager_get_device(dm->device_list, device_type); + return _device_list_get_device(dm, type, NULL); } -dm_device* pa_device_manager_get_device_by_id(pa_device_manager *dm, uint32_t id) { +pa_tz_device* pa_device_manager_get_device_by_id(pa_device_manager *dm, uint32_t id) { pa_assert(dm); - return _device_manager_get_device_with_id(dm->device_list, id); -} - -pa_sink* pa_device_manager_get_sink(dm_device *device_item, const char *role) { - dm_device_profile *profile_item; - pa_sink *sink; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - if (!profile_item->playback_devices) { - pa_log_debug("No playback device in %s", device_item->name); - return NULL; - } - if ((sink = pa_hashmap_get(profile_item->playback_devices, role))) - pa_log_debug("Got sink[%s] for [%s] role", sink->name, role); - else { - sink = pa_hashmap_get(profile_item->playback_devices, DEVICE_ROLE_NORMAL); - pa_log_debug("Could not get sink for [%s] role. so get sink[%s] for normal role", role, sink->name); - } - - return sink; -} - -pa_source* pa_device_manager_get_source(dm_device *device_item, const char *role) { - dm_device_profile *profile_item; - pa_source *source; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - if (!profile_item->capture_devices) { - pa_log_debug("No capture device in %s", device_item->name); - return NULL; - } - - if ((source = pa_hashmap_get(profile_item->capture_devices, role))) - pa_log_debug("Got source[%s] for [%s] role", source->name, role); - else - pa_log_warn("Could not get source for [%s] role", role); - - return source; + return _device_list_get_device_with_id(dm, id); } -dm_device* pa_device_manager_get_device_with_sink(pa_sink *sink) { +pa_tz_device* pa_device_manager_get_device_with_sink(pa_sink *sink) { pa_assert(sink); return sink->device_item; } -dm_device* pa_device_manager_get_device_with_source(pa_source *source) { +pa_tz_device* pa_device_manager_get_device_with_source(pa_source *source) { pa_assert(source); return source->device_item; } -void pa_device_manager_set_device_state(dm_device *device_item, dm_device_direction_t direction, dm_device_state_t state) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - pa_log_info("pa_device_manager_set_device_state : %s.%s direction %s -> %d", device_item->type, profile_item->profile, device_direction_to_string(direction), state); - _device_profile_set_state(profile_item, direction, state); -} - -dm_device_state_t pa_device_manager_get_device_state(dm_device *device_item, dm_device_direction_t direction) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - if (direction == DM_DEVICE_DIRECTION_BOTH) - return COMPOUND_STATE(profile_item); - else if (direction == DM_DEVICE_DIRECTION_OUT) - return profile_item->playback_state; - else if (direction == DM_DEVICE_DIRECTION_IN) - return profile_item->capture_state; - else - return DM_DEVICE_STATE_DEACTIVATED; -} - -uint32_t pa_device_manager_get_device_id(dm_device *device_item) { - pa_assert(device_item); - - return device_item->id; -} - -const char* pa_device_manager_get_device_type(dm_device *device_item) { - pa_assert(device_item); - - return device_item->type; -} - -const char* pa_device_manager_get_device_subtype(dm_device *device_item) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - return profile_item->profile; -} - -dm_device_direction_t pa_device_manager_get_device_direction(dm_device *device_item) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - return profile_item->direction; -} - -pa_usec_t pa_device_manager_get_device_creation_time(dm_device *device_item) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - return profile_item->creation_time; -} - -bool pa_device_manager_is_device_use_internal_codec(dm_device *device_item, dm_device_direction_t direction, const char *role) { - pa_sink *sink; - pa_source *source; - bool use_internal_codec = false; - - pa_assert(device_item); - pa_assert(role); - - if (direction == DM_DEVICE_DIRECTION_IN) { - if ((source = pa_device_manager_get_source(device_item, role))) - use_internal_codec = source->use_internal_codec; - } else if (direction == DM_DEVICE_DIRECTION_OUT) { - if ((sink = pa_device_manager_get_sink(device_item, role))) - use_internal_codec = sink->use_internal_codec; - } else if (direction == DM_DEVICE_DIRECTION_BOTH) { - if ((sink = pa_device_manager_get_sink(device_item, role)) && (source = pa_device_manager_get_source(device_item, role))) - use_internal_codec = sink->use_internal_codec & source->use_internal_codec; - } else { - pa_log_warn("invalid direction"); - } - - return use_internal_codec; -} - -int pa_device_manager_bt_sco_open(pa_device_manager *dm) { - dm_device *bt_device; - - pa_assert(dm); - pa_assert(dm->dbus_conn); - - if (dm->bt_sco_status != DM_DEVICE_BT_SCO_STATUS_CONNECTED) { - pa_log_error("BT SCO Not Connected"); - return -1; - } - - if ((bt_device = _device_manager_get_device(dm->device_list, DEVICE_TYPE_BT)) == NULL) { - pa_log_error("No BT Device"); - return -1; - } - - pa_log_info("BT SCO Open - Request to BT FW"); - if (method_call_bt_sco(pa_dbus_connection_get(dm->dbus_conn), true) < 0) { - pa_log_error("Failed to bt sco on"); - return -1; - } - pa_log_info("BT SCO Open - SUCCESS"); - - dm->bt_sco_status = DM_DEVICE_BT_SCO_STATUS_OPENED; - handle_device_connected(dm, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, NULL, NULL, DEVICE_DETECTED_BT_SCO); - - return 0; -} - -void pa_device_manager_bt_sco_get_status(pa_device_manager *dm, dm_device_bt_sco_status_t *status) { - pa_assert(dm); - pa_assert(status); - - pa_log_info("BT SCO get status %d", dm->bt_sco_status); - *status = dm->bt_sco_status; - - return; -} - -int pa_device_manager_bt_sco_close(pa_device_manager *dm) { - dm_device *bt_device; - - pa_assert(dm); - pa_assert(dm->dbus_conn); - - - if (dm->bt_sco_status != DM_DEVICE_BT_SCO_STATUS_OPENED) { - pa_log_error("BT SCO Not Opened"); - return -1; - } - - if ((bt_device = _device_manager_get_device(dm->device_list, DEVICE_TYPE_BT)) == NULL) { - pa_log_error("No BT Device"); - return -1; - } - - pa_log_info("BT SCO Close - Request to BT FW"); - if (method_call_bt_sco(pa_dbus_connection_get(dm->dbus_conn), false) < 0) { - pa_log_error("Failed to BT SCO Close"); - return -1; - } - pa_log_info("BT SCO Close - Success"); - - dm->bt_sco_status = DM_DEVICE_BT_SCO_STATUS_CONNECTED; - handle_device_disconnected(dm, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, NULL); - - - return 0; -} - -int pa_device_manager_bt_sco_get_property(pa_device_manager *dm, bool *is_wide_band, bool *nrec) { - pa_assert(dm); - pa_assert(dm->dbus_conn); - - pa_log_info("BT SCO Get Property - Request to BT FW"); - - if (method_call_bt_sco_get_property(pa_dbus_connection_get(dm->dbus_conn), is_wide_band, nrec) < 0) { - pa_log_error("Failed to get BT SCO Property"); - return -1; - } - - pa_log_info("BT SCO Get Property - Success, is wide band : %s, nrec : %s", pa_yes_no(is_wide_band), pa_yes_no(nrec)); - - return 0; -} - -int pa_device_manager_load_sink(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *role) { +int pa_device_manager_load_sink(pa_device_manager *dm, const char *type, const char *device_profile, const char *role) { const char *device_string, *params; struct device_type_info *type_info; struct device_file_info *file_info; - dm_device_profile *profile_item; - dm_device *device_item; + pa_tz_device *device; pa_sink *sink; uint32_t device_idx; pa_assert(dm); pa_assert(dm->device_list); - pa_log_info("Load Sink for '%s.%s.%s'", device_type, device_profile, role); - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - if (pa_streq(device_type, device_item->type)) { - if ((profile_item = _device_item_get_profile(device_item, device_profile))) { - if (pa_hashmap_get(profile_item->playback_devices, role)) { - pa_log_warn("Proper sink for '%s.%s.%s' already loaded", device_type, device_profile, role); - return -1; - } + pa_log_info("Load Sink for '%s.%s.%s'", type, device_profile, role); + PA_IDXSET_FOREACH(device, dm->device_list, device_idx) { + if (pa_streq(type, pa_tz_device_get_type(device))) { + if (pa_tz_device_profile_get_sink(device, device_profile, role) == NULL) { + pa_log_warn("Proper sink for '%s.%s.%s' already loaded", type, device_profile, role); + return -1; } } } - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_type, device_profile))) { - pa_log_error("No type map for %s", device_type); + if (!(type_info = _device_manager_get_type_info(dm->type_infos, type, device_profile))) { + pa_log_error("No type map for %s", type); return -1; } + if (type_info->playback_devices == NULL) { + pa_log_error("No playback devices for %s %s", type_info->type, pa_strempty(type_info->profile)); + goto fail; + } + if (!(device_string = pa_hashmap_get(type_info->playback_devices, role))) { - pa_log_error("No device-string for '%s.%s.%s'", device_type, device_profile, role); - goto failed; + pa_log_error("No device-string for '%s.%s.%s'", type, device_profile, role); + goto fail; } if (!(file_info = _device_manager_get_file_info(dm->file_map->playback, device_string))) { pa_log_error("No playback file-map for '%s'", device_string); - goto failed; + goto fail; } if (!(params = pa_hashmap_get(file_info->roles, role))) { pa_log_error("No params for '%s,%s'", device_string, role); - goto failed; + goto fail; } if ((sink = load_device(dm->core, PA_DEVICE_TYPE_SINK, device_string, params))) { - pa_log_debug("loaded sink '%s' for '%s,%s' success", sink->name, device_type, role); + pa_log_debug("loaded sink '%s' for '%s,%s' success", sink->name, type, role); } else { pa_log_warn("Cannot load playback device with '%s,%s'", device_string, params); - goto failed; + goto fail; } return 0; -failed: +fail: return -1; } -int pa_device_manager_load_source(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *role) { +int pa_device_manager_load_source(pa_device_manager *dm, const char *type, const char *device_profile, const char *role) { const char *device_string, *params; struct device_type_info *type_info; struct device_file_info *file_info; - dm_device_profile *profile_item; - dm_device *device_item; + pa_tz_device *device; pa_source *source; uint32_t device_idx; pa_assert(dm); - pa_log_info("Load Source for '%s.%s.%s'", device_type, device_profile, role); + pa_log_info("Load Source for '%s.%s.%s'", type, device_profile, role); - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - if (pa_streq(device_type, device_item->type)) { - if ((profile_item = _device_item_get_profile(device_item, device_profile))) { - if (pa_hashmap_get(profile_item->capture_devices, role)) { - pa_log_warn("Proper source for '%s.%s.%s' already loaded", device_type, device_profile, role); - return -1; - } + PA_IDXSET_FOREACH(device, dm->device_list, device_idx) { + if (pa_streq(type, pa_tz_device_get_type(device))) { + if (pa_tz_device_profile_get_source(device, device_profile, role) == NULL) { + pa_log_warn("Proper source for '%s.%s.%s' already loaded", type, device_profile, role); + return -1; } } } - - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_type, device_profile))) { - pa_log_error("No type map for %s", device_type); + if (!(type_info = _device_manager_get_type_info(dm->type_infos, type, device_profile))) { + pa_log_error("No type map for %s", type); return -1; } + if (type_info->capture_devices == NULL) { + pa_log_error("No capture devices for %s %s", type_info->type, pa_strempty(type_info->profile)); + goto fail; + } + if (!(device_string = pa_hashmap_get(type_info->capture_devices, role))) { - pa_log_error("No device-string for '%s.%s.%s'", device_type, device_profile, role); - goto failed; + pa_log_error("No device-string for '%s.%s.%s'", type, device_profile, role); + goto fail; } if (!(file_info = _device_manager_get_file_info(dm->file_map->capture, device_string))) { pa_log_error("No capture file-map for '%s'", device_string); - goto failed; + goto fail; } if (!(params = pa_hashmap_get(file_info->roles, role))) { pa_log_error("No params for '%s,%s'", device_string, role); - goto failed; + goto fail; } if ((source = load_device(dm->core, PA_DEVICE_TYPE_SOURCE, device_string, params))) { - pa_log_debug("loaded source '%s' for '%s,%s' success", source->name, device_type, role); + pa_log_debug("loaded source '%s' for '%s,%s' success", source->name, type, role); } else { pa_log_warn("Cannot load capture device with '%s,%s'", device_string, params); - goto failed; + goto fail; } return 0; -failed: +fail: return -1; } +static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_conn_changed *data, pa_device_manager *dm) { + send_device_connected_signal(data->event_id, data->device, data->is_connected, dm); + return PA_HOOK_OK; +} + +static pa_hook_result_t device_info_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_info_changed *data, pa_device_manager *dm) { + send_device_info_changed_signal(data->event_id, data->device, data->changed_info, dm); + return PA_HOOK_OK; +} + pa_device_manager* pa_device_manager_get(pa_core *c) { pa_device_manager *dm; @@ -4392,7 +3228,8 @@ pa_device_manager* pa_device_manager_get(pa_core *c) { dm = pa_xnew0(pa_device_manager, 1); PA_REFCNT_INIT(dm); dm->core = c; - dm->bt_sco_status = DM_DEVICE_BT_SCO_STATUS_DISCONNECTED; + dm->device_list = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + dm->device_status = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); dbus_init(dm); @@ -4402,8 +3239,11 @@ pa_device_manager* pa_device_manager_get(pa_core *c) { dm->source_put_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) source_put_hook_callback, dm); dm->source_state_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) device_state_changed_hook_cb, dm); dm->source_unlink_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) source_unlink_hook_callback, dm); - dm->comm = pa_communicator_get(dm->core); + dm->comm_hook_device_connection_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), + PA_HOOK_EARLY, (pa_hook_cb_t)device_connection_changed_hook_cb, dm); + dm->comm_hook_device_info_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED), + PA_HOOK_EARLY, (pa_hook_cb_t)device_info_changed_hook_cb, dm); if (!(dm->type_infos = parse_device_type_infos())) { pa_log_error("Parse device-type-map failed"); return NULL; @@ -4414,15 +3254,7 @@ pa_device_manager* pa_device_manager_get(pa_core *c) { return NULL; } - if (device_list_init(dm) < 0) { - pa_log_error("Init device list failed"); - return NULL; - } - - if (!(dm->device_status = device_type_status_init(dm->type_infos))) { - pa_log_error("Init device status failed"); - return NULL; - } + device_type_status_init(dm); if (load_builtin_devices(dm) != 0) { pa_log_error("Load Builtin Devices faled"); @@ -4460,6 +3292,10 @@ void pa_device_manager_unref(pa_device_manager *dm) { if (PA_REFCNT_DEC(dm) > 0) return; + if (dm->comm_hook_device_connection_changed_slot) + pa_hook_slot_free(dm->comm_hook_device_connection_changed_slot); + if (dm->comm_hook_device_info_changed_slot) + pa_hook_slot_free(dm->comm_hook_device_info_changed_slot); if (dm->sink_put_hook_slot) pa_hook_slot_free(dm->sink_put_hook_slot); if (dm->sink_state_changed_slot) @@ -4486,7 +3322,7 @@ void pa_device_manager_unref(pa_device_manager *dm) { pa_xfree(dm->file_map); } if (dm->device_list) - pa_idxset_free(dm->device_list, (pa_free_cb_t)device_item_free_func); + pa_idxset_free(dm->device_list, (pa_free_cb_t)pa_tz_device_free); if (dm->device_status) pa_idxset_free(dm->device_status, NULL); diff --git a/src/device-manager.h b/src/device-manager.h index fbf9a9e..8e2c04d 100644 --- a/src/device-manager.h +++ b/src/device-manager.h @@ -19,100 +19,33 @@ USA. ***/ -#include - -#define DEVICE_TYPE_SPEAKER "builtin-speaker" -#define DEVICE_TYPE_RECEIVER "builtin-receiver" -#define DEVICE_TYPE_MIC "builtin-mic" -#define DEVICE_TYPE_AUDIO_JACK "audio-jack" -#define DEVICE_TYPE_BT "bt" -#define DEVICE_TYPE_HDMI "hdmi" -#define DEVICE_TYPE_FORWARDING "forwarding" -#define DEVICE_TYPE_USB_AUDIO "usb-audio" -#define DEVICE_TYPE_NONE "none" - -#define DEVICE_PROFILE_BT_SCO "sco" -#define DEVICE_PROFILE_BT_A2DP "a2dp" - -#define DEVICE_ROLE_NORMAL "normal" -#define DEVICE_ROLE_CALL_VOICE "call-voice" -#define DEVICE_ROLE_CALL_VIDEO "call-video" -#define DEVICE_ROLE_VOIP "voip" -#define DEVICE_ROLE_LOW_LATENCY "low-latency" -#define DEVICE_ROLE_HIGH_LATENCY "high-latency" -#define DEVICE_ROLE_UHQA "uhqa" - -typedef enum dm_device_direction_type { - DM_DEVICE_DIRECTION_NONE, - DM_DEVICE_DIRECTION_IN = 0x1, - DM_DEVICE_DIRECTION_OUT = 0x2, - DM_DEVICE_DIRECTION_BOTH = DM_DEVICE_DIRECTION_IN | DM_DEVICE_DIRECTION_OUT -} dm_device_direction_t; - -typedef enum dm_device_changed_into_type { - DM_DEVICE_CHANGED_INFO_STATE, - DM_DEVICE_CHANGED_INFO_IO_DIRECTION -} dm_device_changed_info_t; +#ifndef footizendevicemanagerfoo +#define footizendevicemanagerfoo -typedef enum dm_device_state_type { - DM_DEVICE_STATE_DEACTIVATED = 0, - DM_DEVICE_STATE_ACTIVATED -} dm_device_state_t; - -typedef enum dm_device_bt_sco_status_type { - DM_DEVICE_BT_SCO_STATUS_DISCONNECTED = 0, - DM_DEVICE_BT_SCO_STATUS_CONNECTED, - DM_DEVICE_BT_SCO_STATUS_OPENED -} dm_device_bt_sco_status_t; +#include +#include +#include "tizen-device-def.h" +#include "tizen-device.h" typedef struct pa_device_manager pa_device_manager; -typedef struct dm_device dm_device; - -typedef struct _hook_call_data_for_conn_changed { - uint32_t event_id; - bool is_connected; - dm_device *device; -} pa_device_manager_hook_data_for_conn_changed; - -typedef struct _hook_call_data_for_info_changed { - uint32_t event_id; - dm_device_changed_info_t changed_info; - dm_device *device; -} pa_device_manager_hook_data_for_info_changed; pa_device_manager* pa_device_manager_get(pa_core* c); pa_device_manager* pa_device_manager_ref(pa_device_manager *dm); void pa_device_manager_unref(pa_device_manager *dm); -/* get device or list */ +/* Get device list, returned pa_idxset contains 'pa_tz_device' */ pa_idxset* pa_device_manager_get_device_list(pa_device_manager *dm); -dm_device* pa_device_manager_get_device(pa_device_manager *dm, const char *device_type); -dm_device* pa_device_manager_get_device_by_id(pa_device_manager *dm, uint32_t id); - -/* query device */ -pa_sink* pa_device_manager_get_sink(dm_device *device_item, const char *role); -pa_source* pa_device_manager_get_source(dm_device *device_item, const char *role); -uint32_t pa_device_manager_get_device_id(dm_device *device_item); -const char* pa_device_manager_get_device_type(dm_device *device_item); -const char* pa_device_manager_get_device_subtype(dm_device *device_item); -dm_device_direction_t pa_device_manager_get_device_direction(dm_device *device_item); -pa_usec_t pa_device_manager_get_device_creation_time(dm_device *device_item); -bool pa_device_manager_is_device_use_internal_codec(dm_device *device_item, dm_device_direction_t direction, const char *role); - -/* set/get device state */ -void pa_device_manager_set_device_state(dm_device *device_item, dm_device_direction_t direction, dm_device_state_t state); -dm_device_state_t pa_device_manager_get_device_state(dm_device *device_item, dm_device_direction_t direction); +/* Get device which of type is 'device_type' + * When there is multi-device for that 'device_type', return first one */ +pa_tz_device* pa_device_manager_get_device(pa_device_manager *dm, const char *device_type); +pa_tz_device* pa_device_manager_get_device_by_id(pa_device_manager *dm, uint32_t id); /* get device with sink or source */ -dm_device* pa_device_manager_get_device_with_sink(pa_sink *sink); -dm_device* pa_device_manager_get_device_with_source(pa_source *source); +pa_tz_device* pa_device_manager_get_device_with_sink(pa_sink *sink); +pa_tz_device* pa_device_manager_get_device_with_source(pa_source *source); /* load pulse device */ int pa_device_manager_load_sink(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *role); int pa_device_manager_load_source(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *role); -/* bt sco control/query */ -int pa_device_manager_bt_sco_open(pa_device_manager *dm); -void pa_device_manager_bt_sco_get_status(pa_device_manager *dm, dm_device_bt_sco_status_t *status); -int pa_device_manager_bt_sco_close(pa_device_manager *dm); -int pa_device_manager_bt_sco_get_property(pa_device_manager *dm, bool *is_wide_band, bool *nrec); +#endif diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index 9caedc7..fe46d7a 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -227,8 +227,8 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre const char *dm_device_type = NULL; const char *dm_device_subtype = NULL; dm_device_direction_t dm_device_direction = DM_DEVICE_DIRECTION_NONE; - dm_device *device = NULL; - dm_device *latest_device = NULL; + pa_tz_device *device = NULL; + pa_tz_device *latest_device = NULL; pa_idxset *conn_devices = NULL; pa_sink *sink = NULL; pa_sink *null_sink = NULL; @@ -276,10 +276,10 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre if (cached_connected_devices[convert_device_type_str(device_type)][CONVERT_TO_DEVICE_DIRECTION(data->stream_type)-1] == 0) continue; PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); - dm_device_direction = pa_device_manager_get_device_direction(device); - dm_device_id = pa_device_manager_get_device_id(device); + dm_device_type = pa_tz_device_get_type(device); + dm_device_subtype = pa_tz_device_get_profile(device); + dm_device_direction = pa_tz_device_get_direction(device); + dm_device_id = pa_tz_device_get_id(device); pa_log_debug(" -- type[%-16s], subtype[%-5s], direction[0x%x], id[%u]", dm_device_type, dm_device_subtype, dm_device_direction, dm_device_id); if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { @@ -290,9 +290,9 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre *(data->proper_sink) = (pa_sink*)pa_namereg_get(u->core, SINK_NAME_COMBINED, PA_NAMEREG_SINK); pa_log_debug(" -- found the combine-sink, set it to the sink"); } else - *(data->proper_sink) = pa_device_manager_get_sink(device, data->device_role); + *(data->proper_sink) = pa_tz_device_get_sink(device, data->device_role); } else - *(data->proper_source) = pa_device_manager_get_source(device, data->device_role); + *(data->proper_source) = pa_tz_device_get_source(device, data->device_role); break; } } @@ -305,11 +305,11 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre if (cached_connected_devices[convert_device_type_str(device_type)][CONVERT_TO_DEVICE_DIRECTION(data->stream_type)-1] == 0) continue; PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); - dm_device_direction = pa_device_manager_get_device_direction(device); - dm_device_id = pa_device_manager_get_device_id(device); - creation_time = pa_device_manager_get_device_creation_time(device); + dm_device_type = pa_tz_device_get_type(device); + dm_device_subtype = pa_tz_device_get_profile(device); + dm_device_direction = pa_tz_device_get_direction(device); + dm_device_id = pa_tz_device_get_id(device); + creation_time = pa_tz_device_get_creation_time(device); pa_log_debug(" -- type[%-16s], subtype[%-5s], direction[0x%x], id[%u], creation_time[%llu]", dm_device_type, dm_device_subtype, dm_device_direction, dm_device_id, creation_time); if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { @@ -324,9 +324,9 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre /* update active device info. */ if (latest_device) { if (data->stream_type == STREAM_SINK_INPUT) - *(data->proper_sink) = pa_device_manager_get_sink(latest_device, data->device_role); + *(data->proper_sink) = pa_tz_device_get_sink(latest_device, data->device_role); else - *(data->proper_source) = pa_device_manager_get_source(latest_device, data->device_role); + *(data->proper_source) = pa_tz_device_get_source(latest_device, data->device_role); pa_proplist_sets(GET_STREAM_NEW_PROPLIST(data->stream, data->stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, dm_device_type); } @@ -339,23 +339,23 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre continue; PA_IDXSET_FOREACH(device_id, data->idx_manual_devices, m_idx) { if ((device = pa_device_manager_get_device_by_id(u->device_manager, *device_id))) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); - dm_device_direction = pa_device_manager_get_device_direction(device); + dm_device_type = pa_tz_device_get_type(device); + dm_device_subtype = pa_tz_device_get_profile(device); + dm_device_direction = pa_tz_device_get_direction(device); pa_log_debug(" -- type[%-16s], subtype[%-5s], direction[0x%x], device id[%u]", dm_device_type, dm_device_subtype, dm_device_direction, *device_id); if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { pa_log_info(" ** found a matched device: type[%-16s], direction[0x%x]", device_type, dm_device_direction); if (data->stream_type == STREAM_SINK_INPUT) { if ((*(data->proper_sink)) == null_sink) - pa_sink_input_move_to((pa_sink_input*)(data->stream), pa_device_manager_get_sink(device, data->device_role), false); + pa_sink_input_move_to((pa_sink_input*)(data->stream), pa_tz_device_get_sink(device, data->device_role), false); else - *(data->proper_sink) = pa_device_manager_get_sink(device, data->device_role); + *(data->proper_sink) = pa_tz_device_get_sink(device, data->device_role); } else { if ((*(data->proper_source)) == null_source) - pa_source_output_move_to((pa_source_output*)(data->stream), pa_device_manager_get_source(device, data->device_role), false); + pa_source_output_move_to((pa_source_output*)(data->stream), pa_tz_device_get_source(device, data->device_role), false); else - *(data->proper_source) = pa_device_manager_get_source(device, data->device_role); + *(data->proper_source) = pa_tz_device_get_source(device, data->device_role); } } } @@ -369,9 +369,9 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre continue; PA_IDXSET_FOREACH(device_id, data->idx_manual_devices, m_idx) { if ((device = pa_device_manager_get_device_by_id(u->device_manager, *device_id))) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); - dm_device_direction = pa_device_manager_get_device_direction(device); + dm_device_type = pa_tz_device_get_type(device); + dm_device_subtype = pa_tz_device_get_profile(device); + dm_device_direction = pa_tz_device_get_direction(device); pa_log_debug(" -- type[%-16s], subtype[%-5s], direction[0x%x], device id[%u]", dm_device_type, dm_device_subtype, dm_device_direction, *device_id); if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { @@ -379,12 +379,12 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre /* currently, we support two sinks for combining */ if (data->stream_type == STREAM_SINK_INPUT) { if (!combine_sink_arg1) { - if ((sink = combine_sink_arg1 = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL))) + if ((sink = combine_sink_arg1 = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) pa_log_debug(" -- combine_sink_arg1[%s], combine_sink_arg2[%p]", sink->name, combine_sink_arg2); else pa_log_warn(" -- could not get combine_sink_arg1"); } else if (!combine_sink_arg2) { - sink = combine_sink_arg2 = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); + sink = combine_sink_arg2 = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL); if (sink && !pa_streq(sink->name, combine_sink_arg1->name)) { pa_log_debug(" -- combine_sink_arg2[%s]", sink->name); /* load combine sink */ @@ -414,7 +414,7 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre } } else if (data->stream_type == STREAM_SOURCE_OUTPUT) { - if ((source = pa_device_manager_get_source(device, DEVICE_ROLE_NORMAL))) { + if ((source = pa_tz_device_get_source(device, DEVICE_ROLE_NORMAL))) { if (data->origins_from_new_data) *(data->proper_source) = source; else { @@ -443,48 +443,82 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre /* The state of a device using internal audio codec is handled here. * Regarding the state of an external device, those is handled in device-manager.c */ -static void set_device_state_if_using_internal_codec(dm_device *device, stream_type_t stream_type, dm_device_state_t device_state) { +static void set_device_state_if_using_internal_codec(pa_tz_device *device, stream_type_t stream_type, dm_device_state_t device_state) { bool use_internal_codec = false; dm_device_direction_t direction; pa_assert(device); - direction = pa_device_manager_get_device_direction(device); + direction = pa_tz_device_get_direction(device); if (IS_AVAILABLE_DIRECTION(stream_type, direction)) - if ((use_internal_codec = pa_device_manager_is_device_use_internal_codec(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), DEVICE_ROLE_NORMAL))) - pa_device_manager_set_device_state(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), device_state); + if ((use_internal_codec = pa_tz_device_is_use_internal_codec(device))) + pa_tz_device_set_state(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), device_state); return; } +/* threre is only one sco connected device */ +static pa_tz_device* _get_sco_connected_device(pa_device_manager *dm) { + pa_idxset *device_list; + pa_tz_device *device; + uint32_t device_idx; + + pa_assert(dm); + + device_list = pa_device_manager_get_device_list(dm); + + PA_IDXSET_FOREACH(device, device_list, device_idx) { + if (pa_streq(device->type, DEVICE_TYPE_BT)) { + /* FIXME : not works */ + if (pa_tz_device_have_profile(device, DEVICE_PROFILE_BT_SCO)) { + return device; + } + } + } + return NULL; +} + /* Open/Close BT SCO if it is possible */ static int update_bt_sco_state(pa_device_manager *dm, bool open) { dm_device_bt_sco_status_t sco_status; + pa_tz_device *bt_device; pa_assert(dm); - pa_device_manager_bt_sco_get_status(dm, &sco_status); + bt_device = _get_sco_connected_device(dm); + if (bt_device == NULL) { + pa_log_debug("No SCO connected bt device"); + return 0; + } else + pa_log_info("Got BT SCO connected device(%u)", bt_device->id); - if (!open && (sco_status == DM_DEVICE_BT_SCO_STATUS_OPENED)) { - /* close BT SCO */ - if (pa_device_manager_bt_sco_close(dm)) { - pa_log_error("BT SCO was opened, but failed to close SCO"); - return -1; - } else - pa_log_debug("BT SCO is now closed"); - - } else if (open) { - if (sco_status == DM_DEVICE_BT_SCO_STATUS_DISCONNECTED) { - pa_log_error("BT SCO is not available for this BT device"); - return -1; - } else if (sco_status == DM_DEVICE_BT_SCO_STATUS_CONNECTED) { - /* open BT SCO */ - if (pa_device_manager_bt_sco_open(dm)) { + if (pa_tz_device_sco_get_status(bt_device, &sco_status) < 0) { + pa_log_error("get BT SCO status failed"); + return -1; + } + + if (sco_status == DM_DEVICE_BT_SCO_STATUS_DISCONNECTED) { + pa_log_info("BT SCO is not available for this BT device"); + return 0; + } + if (open) { + if (sco_status == DM_DEVICE_BT_SCO_STATUS_CONNECTED) { + if (pa_tz_device_sco_open(bt_device) < 0) { pa_log_error("failed to open BT SCO"); return -1; } else pa_log_debug("BT SCO is now opened"); - } + } else + pa_log_error("BT SCO is already opened for this BT device"); + } else { + if (sco_status == DM_DEVICE_BT_SCO_STATUS_OPENED) { + if (pa_tz_device_sco_close(bt_device) < 0) { + pa_log_error("BT SCO was opened, but failed to close SCO"); + return -1; + } else + pa_log_debug("BT SCO is now closed"); + } else + pa_log_error("BT SCO is already closed for this BT device"); } return 0; @@ -560,9 +594,9 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ uint32_t dm_device_id = 0; stream_route_type_t route_type; const char *device_type = NULL; - dm_device *device = NULL; - dm_device *_device = NULL; - dm_device *latest_device = NULL; + pa_tz_device *device = NULL; + pa_tz_device *_device = NULL; + pa_tz_device *latest_device = NULL; const char *dm_device_type = NULL; const char *dm_device_subtype = NULL; dm_device_state_t dm_device_state = DM_DEVICE_STATE_DEACTIVATED; @@ -609,9 +643,9 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ conn_devices = pa_device_manager_get_device_list(u->device_manager); /* set device state to deactivate */ PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_state = pa_device_manager_get_device_state(device, CONVERT_TO_DEVICE_DIRECTION(data->stream_type)); - dm_device_direction = pa_device_manager_get_device_direction(device); + dm_device_type = pa_tz_device_get_type(device); + dm_device_state = pa_tz_device_get_state(device, CONVERT_TO_DEVICE_DIRECTION(data->stream_type)); + dm_device_direction = pa_tz_device_get_direction(device); if (dm_device_state == DM_DEVICE_STATE_ACTIVATED && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { pa_log_info("[ROUTE][RESET] found a matched device and set state to DE-ACTIVATED: type[%s], direction[0x%x]", dm_device_type, dm_device_direction); @@ -662,17 +696,15 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ if (cached_connected_devices[convert_device_type_str(device_type)][CONVERT_TO_DEVICE_DIRECTION(data->stream_type)-1] == 0) continue; PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); - dm_device_direction = pa_device_manager_get_device_direction(device); - dm_device_id = pa_device_manager_get_device_id(device); + dm_device_type = pa_tz_device_get_type(device); + dm_device_subtype = pa_tz_device_get_profile(device); + dm_device_direction = pa_tz_device_get_direction(device); + dm_device_id = pa_tz_device_get_id(device); pa_log_debug(" -- type[%-16s], subtype[%-5s], direction[0x%x], id[%u]", dm_device_type, dm_device_subtype, dm_device_direction, dm_device_id); if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { pa_log_debug(" ** found a matched device: type[%-16s], direction[0x%x]", dm_device_type, dm_device_direction); - use_internal_codec = pa_device_manager_is_device_use_internal_codec(device, - CONVERT_TO_DEVICE_DIRECTION(data->stream_type), - data->device_role); + use_internal_codec = pa_tz_device_is_use_internal_codec(device); if (use_internal_codec) { hal_direction = CONVERT_TO_HAL_DIRECTION(data->stream_type); route_info.num_of_devices++; @@ -694,9 +726,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ if (data->route_type == STREAM_ROUTE_TYPE_AUTO) { /* check if this device uses internal codec */ - use_internal_codec = pa_device_manager_is_device_use_internal_codec(device, - CONVERT_TO_DEVICE_DIRECTION(data->stream_type), - data->device_role); + use_internal_codec = pa_tz_device_is_use_internal_codec(device); if (use_internal_codec) { /* set other device's state to be deactivated */ PA_IDXSET_FOREACH(_device, conn_devices, conn_idx) { @@ -712,7 +742,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ /* move sink-inputs/source-outputs if needed */ if (data->stream_type == STREAM_SINK_INPUT) - sink = pa_device_manager_get_sink(device, data->device_role); + sink = pa_tz_device_get_sink(device, data->device_role); /* unload combine sink */ if (data->stream_type == STREAM_SINK_INPUT && u->module_combine_sink) { @@ -739,13 +769,13 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ sink = (pa_sink*)pa_namereg_get(u->core, SINK_NAME_COMBINED, PA_NAMEREG_SINK); pa_log_info("[ROUTE][AUTO_ALL] found the combine_sink already existed"); } else if (data->stream_type == STREAM_SINK_INPUT && !combine_sink_arg1) { - sink = combine_sink_arg1 = pa_device_manager_get_sink(device, data->device_role); + sink = combine_sink_arg1 = pa_tz_device_get_sink(device, data->device_role); if (sink) pa_log_debug("[ROUTE][AUTO_ALL] combine_sink_arg1[%s], combine_sink_arg2[%p]", sink->name, combine_sink_arg2); else pa_log_error("[ROUTE][AUTO_ALL] could not get sink from pa_device_manager_get_sink"); } else if (data->stream_type == STREAM_SINK_INPUT && !combine_sink_arg2) { - sink = combine_sink_arg2 = pa_device_manager_get_sink(device, data->device_role); + sink = combine_sink_arg2 = pa_tz_device_get_sink(device, data->device_role); if (sink && !pa_streq(sink->name, combine_sink_arg1->name)) { pa_log_debug("[ROUTE][AUTO_ALL] combine_sink_arg2[%s]", sink->name); /* load combine sink */ @@ -767,7 +797,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ pa_log_error("[ROUTE][AUTO_ALL] could not get combine_sink"); } } else if (data->stream_type == STREAM_SOURCE_OUTPUT) - source = pa_device_manager_get_source(device, data->device_role); + source = pa_tz_device_get_source(device, data->device_role); if (data->origins_from_new_data) { if (data->stream_type == STREAM_SINK_INPUT) @@ -801,11 +831,11 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ if (cached_connected_devices[convert_device_type_str(device_type)][CONVERT_TO_DEVICE_DIRECTION(data->stream_type)-1] == 0) continue; PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); - dm_device_direction = pa_device_manager_get_device_direction(device); - dm_device_id = pa_device_manager_get_device_id(device); - creation_time = pa_device_manager_get_device_creation_time(device); + dm_device_type = pa_tz_device_get_type(device); + dm_device_subtype = pa_tz_device_get_profile(device); + dm_device_direction = pa_tz_device_get_direction(device); + dm_device_id = pa_tz_device_get_id(device); + creation_time = pa_tz_device_get_creation_time(device); pa_log_debug(" -- type[%-16s], subtype[%-5s], direction[0x%x], id[%u], creation_time[%llu]", dm_device_type, dm_device_subtype, dm_device_direction, dm_device_id, creation_time); if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { @@ -819,11 +849,9 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ } /* update activated device if it is found */ if (latest_device) { - dm_device_type = pa_device_manager_get_device_type(latest_device); - dm_device_id = pa_device_manager_get_device_id(latest_device); - use_internal_codec = pa_device_manager_is_device_use_internal_codec(latest_device, - CONVERT_TO_DEVICE_DIRECTION(data->stream_type), - data->device_role); + dm_device_type = pa_tz_device_get_type(latest_device); + dm_device_id = pa_tz_device_get_id(latest_device); + use_internal_codec = pa_tz_device_is_use_internal_codec(latest_device); if (use_internal_codec) { hal_direction = CONVERT_TO_HAL_DIRECTION(data->stream_type); route_info.num_of_devices++; @@ -873,7 +901,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ /* set other device's state to be deactivated */ PA_IDXSET_FOREACH(_device, conn_devices, conn_idx) { bool need_to_deactive = true; - dm_device_id = pa_device_manager_get_device_id(_device); + dm_device_id = pa_tz_device_get_id(_device); for (i = 0; i < route_info.num_of_devices; i++) { if (dm_device_id == route_info.device_infos[i].id) { need_to_deactive = false; @@ -893,10 +921,23 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ PA_IDXSET_FOREACH(device_id, data->idx_manual_devices, d_idx) { pa_log_debug(" -- manual_device[%u] for this role[%-16s]: device_id(%u)", idx, data->stream_role, *device_id); if ((device = pa_device_manager_get_device_by_id(u->device_manager, *device_id))) { - dm_device_type = pa_device_manager_get_device_type(device); + /* FIXME : This is temparary code, until App could give + * proper BT-SCO device for call-voice */ + if (pa_streq(route_info.role, STREAM_ROLE_CALL_VOICE) && pa_streq(device->type, DEVICE_TYPE_BT)) { + pa_tz_device *sco_device; + if ((sco_device = _get_sco_connected_device(u->device_manager)) == NULL) { + pa_log_error(" ** could not find BT SCO"); + continue; + } + if (sco_device->id != *device_id) { + pa_log_info("Redirecting this manual routing for call-voice to SCO device(%u)", sco_device->id); + device = sco_device; + } + } + dm_device_type = pa_tz_device_get_type(device); if (pa_streq(device_type, dm_device_type)) { - dm_device_direction = pa_device_manager_get_device_direction(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); + dm_device_direction = pa_tz_device_get_direction(device); + dm_device_subtype = pa_tz_device_get_profile(device); pa_log_debug(" ** found a matched device: type[%-16s], subtype[%-5s], direction[0x%x]", dm_device_type, dm_device_subtype, dm_device_direction); /* Check for BT SCO in case of call routing */ @@ -913,15 +954,13 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ /* Check for in/out devices in case of loopback */ if (pa_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) { if ((data->stream_type == STREAM_SINK_INPUT) && (dm_device_direction & DM_DEVICE_DIRECTION_OUT)) - u->loopback_args.sink = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); + u->loopback_args.sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL); else if ((data->stream_type == STREAM_SOURCE_OUTPUT) && (dm_device_direction & DM_DEVICE_DIRECTION_IN)) - u->loopback_args.source = pa_device_manager_get_source(device, DEVICE_ROLE_NORMAL); + u->loopback_args.source = pa_tz_device_get_source(device, DEVICE_ROLE_NORMAL); } if (IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { - use_internal_codec = pa_device_manager_is_device_use_internal_codec(device, - CONVERT_TO_DEVICE_DIRECTION(data->stream_type), - DEVICE_ROLE_NORMAL); + use_internal_codec = pa_tz_device_is_use_internal_codec(device); if (use_internal_codec) { route_info.num_of_devices++; route_info.device_infos = pa_xrealloc(route_info.device_infos, sizeof(hal_device_info)*route_info.num_of_devices); @@ -951,15 +990,15 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ if (pa_streq(data->stream_role, STREAM_ROLE_CALL_VOICE)) { if (data->stream_type == STREAM_SINK_INPUT) { - if (!(sink = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL)) || - !(dst_sink = pa_device_manager_get_sink(device, DEVICE_ROLE_CALL_VOICE)) || + if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL)) || + !(dst_sink = pa_tz_device_get_sink(device, DEVICE_ROLE_CALL_VOICE)) || sink == dst_sink) pa_log_debug("[ROUTE][CALL-VOICE] no need to move streams, sink(%p), dst_sink(%p)", sink, dst_sink); else streams = sink->inputs; } else if (data->stream_type == STREAM_SOURCE_OUTPUT) { - if (!(source = pa_device_manager_get_source(device, DEVICE_ROLE_NORMAL)) || - !(dst_source = pa_device_manager_get_source(device, DEVICE_ROLE_CALL_VOICE)) || + if (!(source = pa_tz_device_get_source(device, DEVICE_ROLE_NORMAL)) || + !(dst_source = pa_tz_device_get_source(device, DEVICE_ROLE_CALL_VOICE)) || source == dst_source) pa_log_debug("[ROUTE][CALL-VOICE] no need to move streams, source(%p), dst_source(%p)", source, dst_source); else @@ -988,7 +1027,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ } else if (pa_streq(data->stream_role, STREAM_ROLE_RADIO)) { if (data->stream_type == STREAM_SINK_INPUT && pa_stream_manager_check_name_is_vstream(data->stream, STREAM_SINK_INPUT, true)) { - if ((sink = pa_device_manager_get_sink(device, data->device_role))) { + if ((sink = pa_tz_device_get_sink(device, data->device_role))) { *(data->proper_sink) = sink; pa_log_debug("[ROUTE][RADIO] *** now, sink-input(%p,%u) uses the sink(%p,%s)", data->stream, ((pa_sink_input*)data->stream)->index, sink, sink->name); @@ -1011,9 +1050,9 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ if (device && data->stream && !data->origins_from_new_data && data->route_type != STREAM_ROUTE_TYPE_MANUAL) { if (data->stream_type == STREAM_SINK_INPUT) - sink = pa_device_manager_get_sink(device, data->device_role); + sink = pa_tz_device_get_sink(device, data->device_role); else if (data->stream_type == STREAM_SOURCE_OUTPUT) - source = pa_device_manager_get_source(device, data->device_role); + source = pa_tz_device_get_source(device, data->device_role); if (data->idx_streams) { PA_IDXSET_FOREACH(s, data->idx_streams, idx) { if (sink && sink != ((pa_sink_input*)s)->sink) { @@ -1100,18 +1139,18 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_ pa_sink *combine_sink = NULL; bool use_internal_codec = false; pa_idxset* conn_devices = NULL; - dm_device* device = NULL; + pa_tz_device *device = NULL; pa_assert(c); pa_assert(conn); pa_assert(u); - device_direction = pa_device_manager_get_device_direction(conn->device); + device_direction = pa_tz_device_get_direction(conn->device); pa_log_info("[CONN] device_connection_changed_hook_cb is called. conn(%p), is_connected(%d), device(%p), direction(0x%x)", conn, conn->is_connected, conn->device, device_direction); - update_connected_devices(pa_device_manager_get_device_type(conn->device), device_direction, conn->is_connected); + update_connected_devices(pa_tz_device_get_type(conn->device), device_direction, conn->is_connected); dump_connected_devices(); null_sink = (pa_sink*)pa_namereg_get(u->core, SINK_NAME_NULL, PA_NAMEREG_SINK); @@ -1120,7 +1159,7 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_ return PA_HOOK_OK; } - use_internal_codec = pa_device_manager_is_device_use_internal_codec(conn->device, device_direction, DEVICE_ROLE_NORMAL); + use_internal_codec = pa_tz_device_is_use_internal_codec(conn->device); /* update for unloading modules when external device is disconnected */ if (!use_internal_codec && !conn->is_connected) { if (device_direction & DM_DEVICE_DIRECTION_OUT) { @@ -1129,10 +1168,10 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_ if ((combine_sink = (pa_sink*)pa_namereg_get(u->core, SINK_NAME_COMBINED, PA_NAMEREG_SINK))) { conn_devices = pa_device_manager_get_device_list(u->device_manager); PA_IDXSET_FOREACH(device, conn_devices, idx) { - device_direction = pa_device_manager_get_device_direction(device); + device_direction = pa_tz_device_get_direction(device); if (device_direction == DM_DEVICE_DIRECTION_OUT) { - if ((use_internal_codec = pa_device_manager_is_device_use_internal_codec(device, device_direction, DEVICE_ROLE_NORMAL))) { - sink = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); + if ((use_internal_codec = pa_tz_device_is_use_internal_codec(device))) { + sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL); break; } } @@ -1169,13 +1208,13 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_ } /* unload loopback module */ if (u->module_loopback) - if (u->loopback_args.sink == pa_device_manager_get_sink(conn->device, DEVICE_ROLE_NORMAL)) + if (u->loopback_args.sink == pa_tz_device_get_sink(conn->device, DEVICE_ROLE_NORMAL)) update_loopback_module(u, false); } if (device_direction & DM_DEVICE_DIRECTION_IN) { /* unload loopback module */ if (u->module_loopback) - if (u->loopback_args.source == pa_device_manager_get_source(conn->device, DEVICE_ROLE_NORMAL)) + if (u->loopback_args.source == pa_tz_device_get_source(conn->device, DEVICE_ROLE_NORMAL)) update_loopback_module(u, false); } } @@ -1193,13 +1232,13 @@ static pa_hook_result_t device_info_changed_hook_cb(pa_core *c, pa_device_manage pa_assert(conn); pa_assert(u); - device_direction = pa_device_manager_get_device_direction(conn->device); + device_direction = pa_tz_device_get_direction(conn->device); pa_log_info("[CONN] device_info_changed_hook_cb is called. conn(%p), changed_info(%d), device(%p), direction(0x%x)", conn, conn->changed_info, conn->device, device_direction); if (conn->changed_info == DM_DEVICE_CHANGED_INFO_IO_DIRECTION) - if (pa_streq(pa_device_manager_get_device_type(conn->device), DEVICE_TYPE_BT)) { + if (pa_streq(pa_tz_device_get_type(conn->device), DEVICE_TYPE_BT)) { /* In case of the bluetooth, we do not maintain a ref. count of the bluetooth devices. * Because bluetooth framework supports only one device simultaneously for audio profile. */ ptr_in = &cached_connected_devices[convert_device_type_str(DEVICE_TYPE_BT)][CACHED_DEVICE_DIRECTION_IN]; diff --git a/src/stream-manager.c b/src/stream-manager.c index e9f168b..a356637 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -2902,7 +2902,7 @@ static pa_hook_result_t source_output_move_finish_cb(pa_core *core, pa_source_ou return PA_HOOK_OK; } -static void find_next_device_for_auto_route(pa_stream_manager *m, stream_route_type_t route_type, const char *role, stream_type_t stream_type, const char *cur_device_type, dm_device **next_device) { +static void find_next_device_for_auto_route(pa_stream_manager *m, stream_route_type_t route_type, const char *role, stream_type_t stream_type, const char *cur_device_type, pa_tz_device **next_device) { stream_info *si = NULL; pa_idxset *devices = NULL; uint32_t idx = 0; @@ -2910,7 +2910,7 @@ static void find_next_device_for_auto_route(pa_stream_manager *m, stream_route_t bool ret_next = false; pa_usec_t creation_time = 0; pa_usec_t latest_creation_time = 0; - dm_device* latest_device = NULL; + pa_tz_device* latest_device = NULL; pa_assert(m); pa_assert(m->stream_infos); @@ -2952,7 +2952,7 @@ static void find_next_device_for_auto_route(pa_stream_manager *m, stream_route_t } else if (route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) { PA_IDXSET_FOREACH(device_type, devices, idx) { if ((*next_device = pa_device_manager_get_device(m->dm, device_type))) { - creation_time = pa_device_manager_get_device_creation_time(*next_device); + creation_time = pa_tz_device_get_creation_time(*next_device); if (!latest_device || (latest_creation_time <= creation_time)) { latest_device = *next_device; latest_creation_time = creation_time; @@ -3051,19 +3051,19 @@ static void process_stream_as_device_change_for_auto_route(pa_stream_manager *m, /* The state of a device using internal audio codec is handled here. * Regarding the state of an external device, those is handled in device-manager.c */ -static void set_device_state_if_using_internal_codec(dm_device *device, stream_type_t stream_type, dm_device_state_t device_state) { +static void set_device_state_if_using_internal_codec(pa_tz_device *device, stream_type_t stream_type, dm_device_state_t device_state) { bool use_internal_codec = false; pa_assert(device); - if ((use_internal_codec = pa_device_manager_is_device_use_internal_codec(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), DEVICE_ROLE_NORMAL))) - pa_device_manager_set_device_state(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), device_state); + if ((use_internal_codec = pa_tz_device_is_use_internal_codec(device))) + pa_tz_device_set_state(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), device_state); return; } static void update_sink_or_source_as_device_change(stream_route_type_t stream_route_type, pa_idxset *streams, - stream_type_t stream_type, dm_device *device, bool is_connected, pa_stream_manager *m) { + stream_type_t stream_type, pa_tz_device *device, bool is_connected, pa_stream_manager *m) { #define MAX_CACHED_LEN 128 typedef struct _cached_device_list { const char *device_type; @@ -3075,8 +3075,8 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro const char *device_type = NULL; const char *cur_device_type = NULL; const char *new_device_type = NULL; - dm_device *next_device = NULL; - dm_device *_device = NULL; + pa_tz_device *next_device = NULL; + pa_tz_device *_device = NULL; stream_route_type_t route_type; pa_sink *sink = NULL; pa_sink *next_sink = NULL; @@ -3100,15 +3100,15 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro pa_log_error("[SM][UPDATE_SINK_SOURCE] could not get null_sink(%p) or null_source(%p)", null_sink, null_source); return; } - device_type = pa_device_manager_get_device_type(device); + device_type = pa_tz_device_get_type(device); if (stream_route_type == STREAM_ROUTE_TYPE_AUTO || stream_route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) { pa_log_debug("[SM][UPDATE_SINK_SOURCE][AUTO] route_type(%d), deivce_type(%s), is_connected(%d))", stream_route_type, device_type, is_connected); if (stream_type == STREAM_SINK_INPUT) - sink = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); + sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL); else - source = pa_device_manager_get_source(device, DEVICE_ROLE_NORMAL); + source = pa_tz_device_get_source(device, DEVICE_ROLE_NORMAL); PA_IDXSET_FOREACH(s, streams, s_idx) { /* streams: core->source_outputs/core->sink_inputs */ if (!get_route_type(s, stream_type, false, &route_type) && (route_type == stream_route_type)) { @@ -3155,8 +3155,8 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro if (sink && (sink == ((pa_sink_input*)s)->sink)) { find_next_device_for_auto_route(m, route_type, role, stream_type, device_type, &next_device); if (next_device) { - if ((next_sink = pa_device_manager_get_sink(next_device, DEVICE_ROLE_NORMAL))) { - new_device_type = pa_device_manager_get_device_type(next_device); + if ((next_sink = pa_tz_device_get_sink(next_device, DEVICE_ROLE_NORMAL))) { + new_device_type = pa_tz_device_get_type(next_device); /* update activated device */ pa_proplist_sets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, new_device_type); set_device_state_if_using_internal_codec(next_device, stream_type, DM_DEVICE_STATE_ACTIVATED); @@ -3180,8 +3180,8 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro } else if (source && (source == ((pa_source_output*)s)->source)) { find_next_device_for_auto_route(m, route_type, role, stream_type, device_type, &next_device); if (next_device) { - if ((next_source = pa_device_manager_get_source(next_device, DEVICE_ROLE_NORMAL))) { - new_device_type = pa_device_manager_get_device_type(next_device); + if ((next_source = pa_tz_device_get_source(next_device, DEVICE_ROLE_NORMAL))) { + new_device_type = pa_tz_device_get_type(next_device); /* update activated device */ pa_proplist_sets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, new_device_type); set_device_state_if_using_internal_codec(next_device, stream_type, DM_DEVICE_STATE_ACTIVATED); @@ -3325,29 +3325,29 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_ pa_assert(data); pa_assert(m); - device_direction = pa_device_manager_get_device_direction(data->device); - device_type = pa_device_manager_get_device_type(data->device); - device_id = pa_device_manager_get_device_id(data->device); - use_internal_codec = pa_device_manager_is_device_use_internal_codec(data->device, device_direction, DEVICE_ROLE_NORMAL); + device_direction = pa_tz_device_get_direction(data->device); + device_type = pa_tz_device_get_type(data->device); + device_id = pa_tz_device_get_id(data->device); + use_internal_codec = pa_tz_device_is_use_internal_codec(data->device); pa_log_info("[SM][CONN] device_connection_changed_hook_cb is called. evend_id(%u), is_connected(%d), device(%p, %s, %u), direction(0x%x), use_internal_codec(%d)", data->event_id, data->is_connected, data->device, device_type, device_id, device_direction, use_internal_codec); /* mute all the streams belong to this device, those will be un-muted in event_fully_handled_hook_cb */ if (!data->is_connected && (device_direction & DM_DEVICE_DIRECTION_OUT)) - if ((sink = pa_device_manager_get_sink(data->device, DEVICE_ROLE_NORMAL))) + if ((sink = pa_tz_device_get_sink(data->device, DEVICE_ROLE_NORMAL))) mute_sink_inputs_as_device_disconnection(m, data->event_id, true, sink->inputs); /* Update streams belong to this external device that have MAUAL_EXT route type */ if (!use_internal_codec && (device_direction & DM_DEVICE_DIRECTION_IN)) { - if ((source = pa_device_manager_get_source(data->device, DEVICE_ROLE_NORMAL))) + if ((source = pa_tz_device_get_source(data->device, DEVICE_ROLE_NORMAL))) update_sink_or_source_as_device_change(STREAM_ROUTE_TYPE_MANUAL_EXT, source->outputs, STREAM_SOURCE_OUTPUT, data->device, data->is_connected, m); else pa_log_error("[SM][CONN] could not get source"); } if (!use_internal_codec && (device_direction & DM_DEVICE_DIRECTION_OUT)) { - if ((sink = pa_device_manager_get_sink(data->device, DEVICE_ROLE_NORMAL))) + if ((sink = pa_tz_device_get_sink(data->device, DEVICE_ROLE_NORMAL))) update_sink_or_source_as_device_change(STREAM_ROUTE_TYPE_MANUAL_EXT, sink->inputs, STREAM_SINK_INPUT, data->device, data->is_connected, m); else diff --git a/src/subscribe-observer.c b/src/subscribe-observer.c index 5db7fa9..9e6c8df 100644 --- a/src/subscribe-observer.c +++ b/src/subscribe-observer.c @@ -37,9 +37,10 @@ #include #endif +#include "subscribe-observer.h" #include "communicator.h" #include "device-manager.h" -#include "subscribe-observer.h" +#include "tizen-device.h" #define SHARED_SUBSCRIBE_OBSERVER "tizen-subscribe-observer" diff --git a/src/subscribe-observer.h b/src/subscribe-observer.h index 4102e3a..6210963 100644 --- a/src/subscribe-observer.h +++ b/src/subscribe-observer.h @@ -22,6 +22,8 @@ #ifndef foosubscribeobserverfoo #define foosubscribeobserverfoo +#include + typedef struct pa_subscribe_observer pa_subscribe_observer; pa_subscribe_observer* pa_subscribe_observer_get(pa_core *c); diff --git a/src/tizen-device-def.c b/src/tizen-device-def.c new file mode 100644 index 0000000..f0f5b82 --- /dev/null +++ b/src/tizen-device-def.c @@ -0,0 +1,262 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include "tizen-device-def.h" + +#define DEVICE_DIRECTION_STR_NONE "none" +#define DEVICE_DIRECTION_STR_OUT "out" +#define DEVICE_DIRECTION_STR_IN "in" +#define DEVICE_DIRECTION_STR_BOTH "both" + +static inline bool pa_safe_streq2(const char *a, const char *b) { + if (a == NULL || b == NULL) + return a == b; + else if (a == NULL || b != NULL) + return false; + else if (a != NULL || b == NULL) + return false; + return pa_streq(a, b); +} + +bool device_profile_is_equal(const char *device_profile1, const char *device_profile2) { + if (!device_profile1 && !device_profile2) + return true; + else if (!device_profile1 || !device_profile2) + return false; + else if (pa_streq(device_profile1, device_profile2)) + return true; + else + return false; +} + +bool device_type_is_equal(const char *device_type1, const char *device_profile1, const char *device_type2, const char *device_profile2) { + pa_assert(device_type1); + pa_assert(device_type2); + + if (pa_streq(device_type1, device_type2)) + return device_profile_is_equal(device_profile1, device_profile2); + else + return false; +} + +bool device_type_is_builtin(const char *device_type) { + if (!device_type) + return false; + else if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_MIC)) + return true; + else + return false; +} + +bool device_type_is_valid(const char *device_type) { + if (!device_type) + return false; + else if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_MIC)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_BT)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) + return true; + else + return false; +} + +bool device_type_is_use_external_card(const char *device_type, const char *profile) { + if (!device_type) + return false; + else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) + return true; + else if ((pa_streq(device_type, DEVICE_TYPE_BT)) && + profile && pa_streq(profile, DEVICE_PROFILE_BT_A2DP)) + return true; + else + return false; +} + +bool device_type_is_multi_profile(const char *device_type) { + if (!device_type) + return false; + else if (pa_streq(device_type, DEVICE_TYPE_BT)) + return true; + else + return false; +} + +bool device_type_is_avail_multi_device(const char *device_type) { + if (!device_type) + return false; + else if (pa_streq(device_type, DEVICE_TYPE_BT)) + return true; + else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) + return true; + else + return false; +} + +bool device_type_is_need_detect(const char *type, const char *profile) { + if (!type) + return false; + else if (pa_streq(type, DEVICE_TYPE_AUDIO_JACK)) + return true; + else if (pa_streq(type, DEVICE_TYPE_HDMI)) + return true; + else if (pa_streq(type, DEVICE_TYPE_FORWARDING)) + return true; + else if (device_type_is_equal(type, profile, DEVICE_TYPE_BT ,DEVICE_PROFILE_BT_SCO)) + return true; + else + return false; +} + +/* Some type have static(fixed) direction, + * and other type(ex.audio-jack)'s direction varies with detected type, + * and the other types(ex. bt-a2dp, usb-audio)'s direction is decided with + * sink/source */ +dm_device_direction_t device_type_get_static_direction(const char *type, const char *profile) { + if (!type) + return DM_DEVICE_DIRECTION_NONE; + else if (pa_streq(type, DEVICE_TYPE_SPEAKER)) + return DM_DEVICE_DIRECTION_OUT; + else if (pa_streq(type, DEVICE_TYPE_RECEIVER)) + return DM_DEVICE_DIRECTION_OUT; + else if (pa_streq(type, DEVICE_TYPE_MIC)) + return DM_DEVICE_DIRECTION_IN; + else if (device_type_is_equal(type, profile, DEVICE_TYPE_BT ,DEVICE_PROFILE_BT_SCO)) + return DM_DEVICE_DIRECTION_BOTH; + else if (pa_streq(type, DEVICE_TYPE_HDMI)) + return DM_DEVICE_DIRECTION_OUT; + else if (pa_streq(type, DEVICE_TYPE_FORWARDING)) + return DM_DEVICE_DIRECTION_BOTH; + else + return DM_DEVICE_DIRECTION_NONE; +} + +/* Check whether 'direction' is valid for 'device_type' + * This is static device-type availability, not for runtime checking */ +bool device_type_is_valid_direction(const char *device_type, const char *device_profile, dm_device_direction_t direction) { + if (!device_type || direction == DM_DEVICE_DIRECTION_NONE) + return false; + + if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) + return direction == DM_DEVICE_DIRECTION_OUT; + else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) + return direction == DM_DEVICE_DIRECTION_OUT; + else if (pa_streq(device_type, DEVICE_TYPE_MIC)) + return direction == DM_DEVICE_DIRECTION_IN; + else if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) + return direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_BOTH; + else if (pa_streq(device_type, DEVICE_TYPE_BT) && pa_safe_streq2(device_profile, DEVICE_PROFILE_BT_SCO)) + return direction == DM_DEVICE_DIRECTION_BOTH; + else if (pa_streq(device_type, DEVICE_TYPE_BT) && pa_safe_streq2(device_profile, DEVICE_PROFILE_BT_A2DP)) + return direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_IN; + else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) + return direction == DM_DEVICE_DIRECTION_OUT; + else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) + return direction == DM_DEVICE_DIRECTION_BOTH; + else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) + return direction == DM_DEVICE_DIRECTION_BOTH || direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_IN; + else + return false; +} + +const char* device_direction_to_string(dm_device_direction_t direction) { + if (direction <= DM_DEVICE_DIRECTION_NONE || direction > DM_DEVICE_DIRECTION_BOTH) { + return NULL; + } + + if (direction == DM_DEVICE_DIRECTION_NONE) + return DEVICE_DIRECTION_STR_NONE; + else if (direction == DM_DEVICE_DIRECTION_OUT) + return DEVICE_DIRECTION_STR_OUT; + else if (direction == DM_DEVICE_DIRECTION_IN) + return DEVICE_DIRECTION_STR_IN; + else if (direction == DM_DEVICE_DIRECTION_BOTH) + return DEVICE_DIRECTION_STR_BOTH; + else + return NULL; +} + +bool device_role_is_valid(const char *device_role) { + if (!device_role) + return false; + else if (pa_streq(device_role, DEVICE_ROLE_NORMAL)) + return true; + else if (pa_streq(device_role, DEVICE_ROLE_CALL_VOICE)) + return true; + else if (pa_streq(device_role, DEVICE_ROLE_CALL_VIDEO)) + return true; + else if (pa_streq(device_role, DEVICE_ROLE_VOIP)) + return true; + else if (pa_streq(device_role, DEVICE_ROLE_LOW_LATENCY)) + return true; + else if (pa_streq(device_role, DEVICE_ROLE_HIGH_LATENCY)) + return true; + else if (pa_streq(device_role, DEVICE_ROLE_UHQA)) + return true; + else + return false; +} + +dm_device_direction_t device_direction_to_int(const char *device_direction) { + if (!device_direction) { + return -1; + } + + if (pa_streq(device_direction, DEVICE_DIRECTION_STR_NONE)) { + return DM_DEVICE_DIRECTION_NONE; + } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_OUT)) { + return DM_DEVICE_DIRECTION_OUT; + } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_IN)) { + return DM_DEVICE_DIRECTION_IN; + } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_BOTH)) { + return DM_DEVICE_DIRECTION_BOTH; + } else { + return -1; + } +} + +int get_profile_priority(const char *device_profile) { + if (!device_profile) { + return 0; + } else if (pa_streq(device_profile, DEVICE_PROFILE_BT_A2DP)) { + return 1; + } else if (pa_streq(device_profile, DEVICE_PROFILE_BT_SCO)) { + return 2; + } else { + return -1; + } +} + +int compare_profile_priority(const char *device_profile1, const char *device_profile2) { + int priority1, priority2; + + priority1 = get_profile_priority(device_profile1); + priority2 = get_profile_priority(device_profile2); + + if (priority1 > priority2) { + return 1; + } else if (priority1 == priority2) { + return 0; + } else { + return -1; + } +} + diff --git a/src/tizen-device-def.h b/src/tizen-device-def.h new file mode 100644 index 0000000..e4efdd7 --- /dev/null +++ b/src/tizen-device-def.h @@ -0,0 +1,70 @@ +#ifndef footizendevicedeffoo +#define footizendevicedeffoo + +#include +#include + +#define DEVICE_TYPE_SPEAKER "builtin-speaker" +#define DEVICE_TYPE_RECEIVER "builtin-receiver" +#define DEVICE_TYPE_MIC "builtin-mic" +#define DEVICE_TYPE_AUDIO_JACK "audio-jack" +#define DEVICE_TYPE_BT "bt" +#define DEVICE_TYPE_HDMI "hdmi" +#define DEVICE_TYPE_FORWARDING "forwarding" +#define DEVICE_TYPE_USB_AUDIO "usb-audio" +#define DEVICE_TYPE_NONE "none" + +#define PROFILE_NUM_MAX 2 +#define DEVICE_PROFILE_BT_SCO "sco" +#define DEVICE_PROFILE_BT_A2DP "a2dp" + +#define DEVICE_ROLE_NORMAL "normal" +#define DEVICE_ROLE_CALL_VOICE "call-voice" +#define DEVICE_ROLE_CALL_VIDEO "call-video" +#define DEVICE_ROLE_VOIP "voip" +#define DEVICE_ROLE_LOW_LATENCY "low-latency" +#define DEVICE_ROLE_HIGH_LATENCY "high-latency" +#define DEVICE_ROLE_UHQA "uhqa" + +typedef enum dm_device_direction_type { + DM_DEVICE_DIRECTION_NONE, + DM_DEVICE_DIRECTION_IN = 0x1, + DM_DEVICE_DIRECTION_OUT = 0x2, + DM_DEVICE_DIRECTION_BOTH = DM_DEVICE_DIRECTION_IN | DM_DEVICE_DIRECTION_OUT +} dm_device_direction_t; + +typedef enum dm_device_changed_into_type { + DM_DEVICE_CHANGED_INFO_STATE, + DM_DEVICE_CHANGED_INFO_IO_DIRECTION +} dm_device_changed_info_t; + +typedef enum dm_device_state_type { + DM_DEVICE_STATE_DEACTIVATED = 0, + DM_DEVICE_STATE_ACTIVATED +} dm_device_state_t; + +typedef enum dm_device_bt_sco_status_type { + DM_DEVICE_BT_SCO_STATUS_DISCONNECTED = 0, + DM_DEVICE_BT_SCO_STATUS_CONNECTED, + DM_DEVICE_BT_SCO_STATUS_OPENED +} dm_device_bt_sco_status_t; + +/* A macro to ease iteration through all entries */ +#define PA_HASHMAP_FOREACH_KEY(e, h, state, key) \ + for ((state) = NULL, (e) = pa_hashmap_iterate((h), &(state), (const void**)&(key)); (e); (e) = pa_hashmap_iterate((h), &(state), (const void**)&(key))) + +bool device_type_is_builtin(const char *device_type); +bool device_type_is_use_external_card(const char *device_type, const char *device_profile); +bool device_type_is_valid(const char *device_type); +bool device_type_is_valid_direction(const char *device_type, const char *device_profile, dm_device_direction_t direction); +bool device_type_is_multi_profile(const char *device_type); +bool device_type_is_avail_multi_device(const char *device_type); +bool device_type_is_need_detect(const char *type, const char *profile); +dm_device_direction_t device_type_get_static_direction(const char *type, const char *profile); +const char* device_direction_to_string(dm_device_direction_t direction); +bool device_role_is_valid(const char *device_role); +dm_device_direction_t device_direction_to_int(const char *device_direction); +bool device_profile_is_equal(const char *device_profile1, const char *device_profile2); +bool device_type_is_equal(const char *device_type1, const char *device_profile1, const char *device_type2, const char *device_profile2); + +#endif diff --git a/src/tizen-device.c b/src/tizen-device.c new file mode 100644 index 0000000..9f73f79 --- /dev/null +++ b/src/tizen-device.c @@ -0,0 +1,1365 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "tizen-device.h" + +#define DBUS_SERVICE_HFP_AGENT "org.bluez.ag_agent" +#define DBUS_OBJECT_HFP_AGENT "/org/bluez/hfp_agent" +#define DBUS_INTERFACE_HFP_AGENT "Org.Hfp.App.Interface" + +#define BT_CVSD_CODEC_ID 1 // narrow-band +#define BT_MSBC_CODEC_ID 2 // wide-band + +#define COMPOUND_STATE(d) (((pa_tz_profile*)d)->playback_state | ((pa_tz_profile*)d)->capture_state) + +int device_id_max_g = 1; +uint32_t event_id_max_g = 1; + +static uint32_t _new_event_id() { + return event_id_max_g++; +} + +static char* get_playback_list_str(pa_hashmap *playback_devices) { + pa_sink *sink = NULL; + void *state = NULL; + const char *role; + pa_strbuf *buf; + + if (!playback_devices || !pa_hashmap_size(playback_devices)) + return NULL; + + buf = pa_strbuf_new(); + pa_strbuf_printf(buf, " Playback device list\n"); + PA_HASHMAP_FOREACH_KEY(sink, playback_devices, state, role) + pa_strbuf_printf(buf, " %-13s -> %s\n", role, sink->name); + + return pa_strbuf_tostring_free(buf); +} + +static char* get_capture_list_str(pa_hashmap *capture_devices) { + pa_source *source = NULL; + void *state = NULL; + const char *role; + pa_strbuf *buf; + + if (!capture_devices || !pa_hashmap_size(capture_devices)) + return NULL; + + buf = pa_strbuf_new(); + pa_strbuf_printf(buf, " Capture device list\n"); + PA_HASHMAP_FOREACH_KEY(source, capture_devices, state, role) + pa_strbuf_printf(buf, " %-13s -> %s\n", role, source->name); + + return pa_strbuf_tostring_free(buf); +} + +/* Returned string must be freed */ +static char* get_device_profile_info_str(pa_tz_profile *profile) { + pa_strbuf *buf; + char *playback_str, *capture_str; + if (!profile) + return NULL; + + buf = pa_strbuf_new(); + pa_strbuf_printf(buf, " Profile : %s\n", pa_strna(profile->profile)); + pa_strbuf_printf(buf, " Direction : %s\n", device_direction_to_string(profile->direction)); + pa_strbuf_printf(buf, " Is activated : %s\n", pa_yes_no(COMPOUND_STATE(profile) == DM_DEVICE_STATE_ACTIVATED)); + pa_strbuf_printf(buf, " Internal : %s\n", pa_yes_no(profile->use_internal_codec)); + if (profile->profile && pa_streq(profile->profile, DEVICE_PROFILE_BT_SCO)) + pa_strbuf_printf(buf, " SCO opened : %s\n", pa_yes_no(profile->sco_opened)); + playback_str = get_playback_list_str(profile->playback_devices); + capture_str = get_capture_list_str(profile->capture_devices); + + if (playback_str) + pa_strbuf_puts(buf, playback_str); + if (capture_str) + pa_strbuf_puts(buf, capture_str); + + pa_xfree(playback_str); + pa_xfree(capture_str); + + return pa_strbuf_tostring_free(buf); +} + +static char* _device_get_info_str(pa_tz_device *device) { + pa_strbuf *buf; + char *profile_info; + pa_tz_profile *profile; + uint32_t profile_idx; + + if (!device) + return NULL; + + buf = pa_strbuf_new(); + pa_strbuf_printf(buf, "[Device #%u]\n", device->id); + pa_strbuf_printf(buf, " ID : %u\n", device->id); + pa_strbuf_printf(buf, " Type : %s\n", device->type); + pa_strbuf_printf(buf, " Name : %s\n", device->name); + if (device_type_is_multi_profile(device->type)) + pa_strbuf_printf(buf, " System ID : %s\n", device->system_id); + pa_strbuf_printf(buf, " Active Profile : %u\n", device->active_profile); + + PA_IDXSET_FOREACH(profile, device->profiles, profile_idx) { + pa_strbuf_printf(buf, " (Profile #%d)\n", profile_idx); + profile_info = get_device_profile_info_str(profile); + if (profile_info) + pa_strbuf_puts(buf, profile_info); + pa_xfree(profile_info); + } + + return pa_strbuf_tostring_free(buf); +} + + +void pa_tz_device_dump_info(pa_tz_device *device, pa_log_level_t log_level) { + char *info; + + if (!device) + return; + + if ((info = _device_get_info_str(device))) { + pa_logl(log_level, "%s", info); + pa_xfree(info); + } +} + +static void notify_device_connection_changed(pa_tz_device *device, bool connected) { + pa_device_manager_hook_data_for_conn_changed hook_data; + uint32_t event_id; + + event_id = _new_event_id(); + + hook_data.event_id = event_id; + hook_data.is_connected = connected; + hook_data.device = device; + + pa_log_info("Fire hook for device connection changed, device(%u) %s", + device->id, connected ? "connected" : "disconnected"); + pa_hook_fire(pa_communicator_hook(device->comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), &hook_data); +} + +static void notify_device_info_changed(pa_tz_device *device, dm_device_changed_info_t changed_type) { + pa_device_manager_hook_data_for_info_changed hook_data; + uint32_t event_id; + + event_id = _new_event_id(); + + hook_data.event_id = event_id; + hook_data.changed_info = changed_type; + hook_data.device = device; + + pa_log_info("Fire hook for device info changed, device(%u) %s changed", + device->id, changed_type == DM_DEVICE_CHANGED_INFO_STATE ? "state" : "direction"); + pa_hook_fire(pa_communicator_hook(device->comm, PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED), &hook_data); +} + +/* pa_tz_device_new_data */ +void pa_tz_device_new_data_init(pa_tz_device_new_data *data, pa_idxset *list, + pa_communicator *comm, pa_dbus_connection *conn) { + pa_assert(data); + pa_assert(list); + pa_assert(comm); + + data->list = list; + data->comm = comm; + data->dbus_conn = conn; + + data->type = NULL; + data->name = NULL; + data->system_id = NULL; + data->direction = DM_DEVICE_DIRECTION_NONE; + + data->playback_pcms= pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + data->capture_pcms = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + + data->n_profile = 0; +} + +void pa_tz_device_new_data_set_type(pa_tz_device_new_data *data, const char *type) { + pa_assert(data); + + data->type = pa_xstrdup(type); +} + +void pa_tz_device_new_data_set_name(pa_tz_device_new_data *data, const char *name) { + pa_assert(data); + + data->name = pa_xstrdup(name); +} + +void pa_tz_device_new_data_set_direction(pa_tz_device_new_data *data, dm_device_direction_t direction) { + pa_assert(data); + + data->direction = direction; +} +/* only for external? */ +void pa_tz_device_new_data_set_system_id(pa_tz_device_new_data *data, const char *system_id) { + pa_assert(data); + + data->system_id = pa_xstrdup(system_id); +} + +void pa_tz_device_new_data_set_use_internal_codec(pa_tz_device_new_data *data, bool use_internal_codec) { + pa_assert(data); + + data->use_internal_codec = use_internal_codec; +} + +void pa_tz_device_new_data_add_sink(pa_tz_device_new_data *data, const char *role, pa_sink *sink) { + pa_assert(data); + + pa_hashmap_put(data->playback_pcms, (void*)role, sink); +} + +void pa_tz_device_new_data_add_source(pa_tz_device_new_data *data, const char *role, pa_source *source) { + pa_assert(data); + + pa_hashmap_put(data->playback_pcms, (void*)role, source); +} +/* after set_type, only for multi profile type, and check direction, profile */ +void pa_tz_device_new_data_add_profile(pa_tz_device_new_data *data, pa_tz_profile_new_data *profile_data, bool as_active) { + uint32_t profile_idx; + pa_assert(data); + + profile_idx = data->n_profile; + data->profile_data[profile_idx] = profile_data; + if (as_active) + data->active_profile = profile_idx; + + data->n_profile++; +} + +void pa_tz_device_new_data_done(pa_tz_device_new_data *data) { + pa_assert(data); + + pa_xfree(data->type); + pa_xfree(data->name); +} + +static int _check_valid_device_new_data(pa_tz_device_new_data *data) { + bool is_multi_profile; + pa_assert(data); + + if (data->type == NULL) { + pa_log_error("new data type is null"); + return -1; + } + + is_multi_profile = device_type_is_multi_profile(data->type); + + if (is_multi_profile == false && data->direction == DM_DEVICE_DIRECTION_NONE) { + pa_log_error("new data direction is none"); + return -1; + } + + if (is_multi_profile == true && data->n_profile == 0) { + pa_log_error("multi profile type, but there is no profile"); + return -1; + } + if (is_multi_profile == false && data->n_profile > 0) { + pa_log_error("not multi profile type, but there are profile"); + return -1; + } + + return 0; +} + +static pa_tz_profile* profile_new(char *profile_str, dm_device_direction_t direction, + pa_hashmap *playbacks, pa_hashmap *captures, bool use_internal_codec, pa_tz_device *device) { + pa_tz_profile *profile; + + pa_log_info("New profile(%s) direction(%s), for device(%u)", + pa_strempty(profile_str), device_direction_to_string(direction), device->id); + + profile = pa_xmalloc(sizeof(pa_tz_profile)); + + profile->profile = pa_xstrdup(profile_str); + profile->playback_devices = playbacks; + profile->capture_devices = captures; + profile->direction = direction; + profile->playback_state = DM_DEVICE_STATE_DEACTIVATED; + profile->capture_state = DM_DEVICE_STATE_DEACTIVATED; + profile->device = device; + profile->creation_time = pa_rtclock_now(); + profile->use_internal_codec = use_internal_codec; + profile->sco_opened = false; + + return profile; +} + +static void profile_free(pa_tz_profile *profile) { + if (!profile) + return; + + pa_log_info("Free profile(%s) for device(%u)", + pa_strempty(profile->profile), profile->device->id); + + pa_xfree(profile->profile); + + if (profile->playback_devices) + pa_hashmap_free(profile->playback_devices); + if (profile->capture_devices) + pa_hashmap_free(profile->capture_devices); + + pa_xfree(profile); +} + +static int profile_add_sink(pa_tz_profile *profile, const char *role, pa_sink *sink) { + pa_assert(profile); + + if (pa_hashmap_put(profile->playback_devices, (void*)role, sink) < 0) { + pa_log_error("Failed to add sink : put sink failed"); + return -1; + } + return 0; +} + +static int profile_add_source(pa_tz_profile *profile, const char *role, pa_source *source) { + pa_assert(profile); + + if (pa_hashmap_put(profile->playback_devices, (void*)role, source) < 0) { + pa_log_error("Failed to add source : put source failed"); + return -1; + } + return 0; +} + +static pa_sink* profile_get_sink(pa_tz_profile *profile, const char *role) { + pa_sink *sink; + pa_assert(profile); + + if ((sink = pa_hashmap_get(profile->playback_devices, role)) == NULL) { + pa_log_warn("Failed to get sink for %s", role); + return NULL; + } + + return sink; +} + +static pa_source* profile_get_source(pa_tz_profile *profile, const char *role) { + pa_source *source; + pa_assert(profile); + + if ((source = pa_hashmap_get(profile->playback_devices, role)) == NULL) { + pa_log_warn("Failed to get source for %s", role); + return NULL; + } + + return source; +} + +static void profile_set_state(pa_tz_profile *profile, dm_device_direction_t direction, dm_device_state_t state) { + dm_device_state_t prev_state, new_state; + pa_assert(profile); + + prev_state = COMPOUND_STATE(profile); + pa_log_debug("previous playback_state : %d, capture_state : %d => state %d", profile->playback_state, profile->capture_state, prev_state); + if (direction & DM_DEVICE_DIRECTION_IN) + profile->capture_state = state; + if (direction & DM_DEVICE_DIRECTION_OUT) + profile->playback_state = state; + new_state = COMPOUND_STATE(profile); + pa_log_debug("new playback_state : %d, capture_state : %d => state %d", profile->playback_state, profile->capture_state, new_state); + + if (prev_state != new_state) { + notify_device_info_changed(profile->device, DM_DEVICE_CHANGED_INFO_STATE); + pa_tz_device_dump_info(profile->device, PA_LOG_DEBUG); + } +} + +static dm_device_state_t profile_get_state(pa_tz_profile *profile, dm_device_direction_t direction) { + pa_assert(profile); + + if (direction == DM_DEVICE_DIRECTION_BOTH) + return COMPOUND_STATE(profile); + else if (direction == DM_DEVICE_DIRECTION_OUT) + return profile->playback_state; + else if (direction == DM_DEVICE_DIRECTION_IN) + return profile->capture_state; + else + return DM_DEVICE_STATE_DEACTIVATED; +} + +static int profile_remove_sink_with_role(pa_tz_profile *profile, const char *role) { + pa_sink *sink; + pa_assert(profile); + + sink = pa_hashmap_remove(profile->playback_devices, role); + return sink ? 0 : -1; +} + +static int profile_remove_source_with_role(pa_tz_profile *profile, const char *role) { + pa_source *source; + pa_assert(profile); + + source = pa_hashmap_remove(profile->capture_devices, role); + return source ? 0 : -1; +} + +static int profile_remove_sink(pa_tz_profile *profile, pa_sink *sink) { + pa_sink *_sink; + void *state; + char *role; + + pa_assert(profile); + + PA_HASHMAP_FOREACH_KEY(_sink, profile->playback_devices, state, role) { + if (sink == _sink) + return profile_remove_sink_with_role(profile, role); + } + + return -1; +} + +static int profile_remove_source(pa_tz_profile *profile, pa_source *source) { + pa_source *_source; + void *state; + char *role; + + pa_assert(profile); + + PA_HASHMAP_FOREACH_KEY(_source, profile->capture_devices, state, role) { + if (source == _source) + return profile_remove_source_with_role(profile, role); + } + + return -1; +} + +/* pa_tz_device */ +pa_tz_device* pa_tz_device_new(pa_tz_device_new_data *data) { + pa_tz_device *device; + pa_sink *sink; + pa_source *source; + pa_tz_profile *profile; + uint32_t profile_idx; + + pa_assert(data); + + if (_check_valid_device_new_data(data) < 0) { + pa_log_error("Invalid device_new_data"); + return NULL; + } + + device = pa_xmalloc(sizeof(pa_tz_device)); + device->list = data->list; + device->comm = data->comm; + device->dbus_conn = data->dbus_conn; + + device->id = device_id_max_g++; + device->type = pa_xstrdup(data->type); + if (data->name) + device->name = pa_xstrdup(data->name); + else + device->name = pa_xstrdup(data->type); + device->system_id = pa_xstrdup(data->system_id); + device->active_profile = 0; + + pa_log_info("New device type(%s) id(%u) name(%s) system_id(%s)", + device->type, device->id, device->name, pa_strempty(device->system_id)); + + device->profiles = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + + /* If multi profile type, get from data->profile_data */ + if (device_type_is_multi_profile(data->type)) { + pa_tz_profile_new_data *pdata; + for (int i = 0; i < data->n_profile; i++) { + pdata = data->profile_data[i]; + profile = profile_new(pdata->profile, pdata->direction, + pdata->playback_pcms, pdata->capture_pcms, pdata->use_internal_codec, device); + pa_idxset_put(device->profiles, profile, NULL); + } + device->active_profile = data->active_profile; + } else { + profile = profile_new(NULL, data->direction, + data->playback_pcms, data->capture_pcms, data->use_internal_codec, device); + pa_idxset_put(device->profiles, profile, NULL); + } + + PA_IDXSET_FOREACH(profile, device->profiles, profile_idx) { + if (device_type_is_use_external_card(device->type, profile->profile)) { + if ((sink = profile_get_sink(profile, DEVICE_ROLE_NORMAL))) + sink->device_item = device; + if ((source = profile_get_source(profile, DEVICE_ROLE_NORMAL))) + source->device_item = device; + } + } + + pa_idxset_put(device->list, device, NULL); + notify_device_connection_changed(device, true); + + pa_tz_device_dump_info(device, PA_LOG_INFO); + + return device; +} + +static uint32_t _get_profile_idx(pa_tz_device *device, const char *profile_str) { + pa_tz_profile *profile; + uint32_t profile_idx; + + pa_assert(device); + pa_assert(device->profiles); + + if (profile_str == NULL || pa_streq(profile_str, "")) { + pa_idxset_first(device->profiles, &profile_idx); + return profile_idx; + } + + PA_IDXSET_FOREACH(profile, device->profiles, profile_idx) { + if (device_profile_is_equal(profile->profile, profile_str)) + return profile_idx; + } + + return PA_INVALID_INDEX; +} + +static pa_tz_profile* _get_profile(pa_tz_device *device, const char *profile_str) { + pa_tz_profile *profile; + uint32_t profile_idx; + + pa_assert(device); + pa_assert(device->profiles); + + PA_IDXSET_FOREACH(profile, device->profiles, profile_idx) { + if (device_profile_is_equal(profile->profile, profile_str)) + return profile; + } + + return NULL; +} + +static pa_tz_profile* _get_profile_by_idx(pa_tz_device *device, uint32_t profile_idx) { + pa_tz_profile *profile; + + pa_assert(device); + + profile = pa_idxset_get_by_index(device->profiles, profile_idx); + if (profile == NULL) + pa_log_error("No profile(%u) in device(%u)", profile_idx, device->id); + + return profile; +} + + +static pa_tz_profile* _get_active_profile(pa_tz_device *device) { + pa_tz_profile *profile; + + pa_assert(device); + + profile = _get_profile_by_idx(device, device->active_profile); + if (profile == NULL) + pa_log_error("Failed to find active profile(%u)", device->active_profile); + + return profile; +} + +/* if noti_always is true, always noti this change without checking index + * if profile is null, set first profile as active */ +int _set_active_profile(pa_tz_device *device, const char *profile, bool noti_always) { + uint32_t profile_idx, prev_active_idx; + + pa_assert(device); + + pa_log_info("Set active profile, device(%u) profile(%s)", + device->id, pa_strempty(profile)); + + prev_active_idx = device->active_profile; + profile_idx = _get_profile_idx(device, profile); + if (profile_idx == PA_INVALID_INDEX) { + pa_log_error("index for profile(%s) is invalid", pa_strempty(profile)); + return -1; + } + device->active_profile = profile_idx; + pa_log_info("new active profile index %u", profile_idx); + + /* Compare index only when check_idx is true */ + if (noti_always || prev_active_idx != device->active_profile) + notify_device_info_changed(device, DM_DEVICE_CHANGED_INFO_IO_DIRECTION); + + return 0; +} + +/* only for multi profile type */ +int pa_tz_device_add_profile(pa_tz_device *device, pa_tz_profile_new_data *pdata, bool as_active) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(device->profiles); + + pa_log_info("device add profile, device(%u) profile(%s) as_active(%s)", + device->id, pa_strempty(pdata->profile), pa_yes_no(as_active)); + + if (device_type_is_multi_profile(device->type) == false) { + pa_log_error("Failed to add profile : not multi profile type"); + return -1; + } + if (pa_idxset_size(device->profiles) >= PROFILE_NUM_MAX) { + pa_log_error("Failed to add profile : Too many profiles"); + return -1; + } + + profile = profile_new(pdata->profile, pdata->direction, + pdata->playback_pcms, pdata->capture_pcms, pdata->use_internal_codec, device); + pa_idxset_put(device->profiles, profile, NULL); + + if (as_active) + _set_active_profile(device, pdata->profile, true); + pa_tz_device_dump_info(device, PA_LOG_INFO); + + return 0; +} + +int pa_tz_device_remove_profile(pa_tz_device *device, const char *profile_str) { + pa_tz_profile *profile; + uint32_t profile_idx, remove_idx; + bool found = false; + unsigned profile_num; + + pa_assert(device); + pa_assert(device->profiles); + + pa_log_info("device remove profile, device(%u) profile(%s)", + device->id, pa_strempty(profile_str)); + + if (device_type_is_multi_profile(device->type) == false) { + pa_log_error("Failed to add profile : not multi profile type"); + return -1; + } + + if ((profile_num = pa_tz_device_get_profile_num(device)) <= 1) { + pa_log_error("This device have too small profiles %u, Should be freed", profile_num); + return -1; + } + + PA_IDXSET_FOREACH(profile, device->profiles, profile_idx) { + if (pa_safe_streq(profile->profile, profile_str)) { + pa_log_info("found matching profile to remove"); + found = true; + remove_idx = profile_idx; + } + } + + if (found) { + pa_idxset_remove_by_index(device->profiles, remove_idx); + /* change active profile if removed one was active */ + if (device->active_profile == remove_idx) + _set_active_profile(device, NULL, true); + pa_tz_device_dump_info(device, PA_LOG_INFO); + return 0; + } else { + pa_log_warn("no matching profile to remove"); + return -1; + } +} + +/* only for single profile type */ +int pa_tz_device_add_sink(pa_tz_device *device, const char *role, pa_sink *sink) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(device_role_is_valid(role)); + pa_assert(sink); + + pa_log_info("device add sink, device(%u) role(%s) sink(%s)", + device->id, role, sink->name); + + if (pa_tz_device_get_profile_num(device) > 1) { + pa_log_error("Failed to add sink : Too many profiles"); + return -1; + } + + profile = pa_idxset_first(device->profiles, NULL); + + if (profile_add_sink(profile, role, sink) < 0) { + pa_log_error("Failed to add sink : Can't add to profile"); + return -1; + } + + return 0; +} + +int pa_tz_device_add_source(pa_tz_device *device, const char *role, pa_source *source) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(device_role_is_valid(role)); + pa_assert(source); + + pa_log_info("device add source, device(%u) role(%s) source(%s)", + device->id, role, source->name); + + if (pa_tz_device_get_profile_num(device) > 1) { + pa_log_warn("Failed to add source : Too many profiles"); + return -1; + } + + profile = pa_idxset_first(device->profiles, NULL); + + if (profile_add_source(profile, role, source) < 0) { + pa_log_error("Failed to add source : Can't add to profile"); + return -1; + } + + return 0; +} + +int pa_tz_device_remove_sink(pa_tz_device *device, pa_sink *sink) { + pa_tz_profile *profile; + int removed = 0; + uint32_t profile_idx; + + pa_assert(device); + pa_assert(sink); + + pa_log_info("device remove sink, device(%u) sink(%s)", + device->id, sink->name); + + PA_IDXSET_FOREACH(profile, device->profiles, profile_idx) + removed &= profile_remove_sink(profile, sink); + + return removed; +} + +int pa_tz_device_remove_source(pa_tz_device *device, pa_source *source) { + pa_tz_profile *profile; + uint32_t profile_idx; + int removed = 0; + + pa_assert(device); + pa_assert(source); + + pa_log_info("device remove source, device(%u) source(%s)", + device->id, source->name); + + PA_IDXSET_FOREACH(profile, device->profiles, profile_idx) + removed &= profile_remove_source(profile, source); + + return removed; +} + +int pa_tz_device_remove_sink_with_role(pa_tz_device *device, const char *role) { + pa_tz_profile *profile; + uint32_t profile_idx; + int removed = 0; + + pa_assert(device); + pa_assert(device_role_is_valid(role)); + + pa_log_info("device remove sink with role, device(%u) role(%s)", + device->id, role); + + PA_IDXSET_FOREACH(profile, device->profiles, profile_idx) + removed &= profile_remove_sink_with_role(profile, role); + + return removed; +} + +int pa_tz_device_remove_source_with_role(pa_tz_device *device, const char *role) { + pa_tz_profile *profile; + uint32_t profile_idx; + int removed = 0; + + pa_assert(device); + pa_assert(device_role_is_valid(role)); + + pa_log_info("device remove source with role, device(%u) role(%s)", + device->id, role); + + PA_IDXSET_FOREACH(profile, device->profiles, profile_idx) + removed &= profile_remove_source_with_role(profile, role); + + return removed; +} + +/* only for multi profile */ +int pa_tz_device_profile_add_sink(pa_tz_device *device, const char *profile_str, const char *role, pa_sink *sink) { + pa_tz_profile *profile; + + pa_assert(device); + + pa_log_info("device profile add sink, device(%u) profile(%s) role(%s) sink(%s)", + device->id, pa_strempty(profile_str), role, sink->name); + + if ((profile = _get_profile(device, profile_str)) == NULL) { + pa_log_error("Can't get profile %s", profile_str); + return -1; + } + + if (profile_add_sink(profile, role, sink) < 0) { + pa_log_error("Can't add to profile"); + return -1; + } + + return 0; +} + +int pa_tz_device_profile_add_source(pa_tz_device *device, const char *profile_str, const char *role, pa_source *source) { + pa_tz_profile *profile; + + pa_assert(device); + + pa_log_info("device profile add source, device(%u) profile(%s) role(%s) source(%s)", + device->id, pa_strempty(profile_str), role, source->name); + + if ((profile = _get_profile(device, profile_str)) == NULL) { + pa_log_error("Can't get profile %s", profile_str); + return -1; + } + + if (profile_add_source(profile, role, source) < 0) { + pa_log_error("Can't add to profile"); + return -1; + } + + return 0; +} + +int pa_tz_device_profile_remove_sink(pa_tz_device *device, const char *profile_str, pa_sink *sink) { + pa_tz_profile *profile; + + pa_assert(device); + + pa_log_info("device profile remove sink, device(%u) profile(%s) sink(%s)", + device->id, pa_strempty(profile_str), sink->name); + + if ((profile = _get_profile(device, profile_str)) == NULL) { + pa_log_error("Can't get profile %s", profile_str); + return -1; + } + + if (profile_remove_sink(profile, sink) < 0) { + pa_log_error("Can't remove from profile"); + return -1; + } + + return 0; +} + +int pa_tz_device_profile_remove_source(pa_tz_device *device, const char *profile_str, pa_source *source) { + pa_tz_profile *profile; + + pa_assert(device); + + pa_log_info("device profile remove source, device(%u) profile(%s) source(%s)", + device->id, pa_strempty(profile_str), source->name); + + if ((profile = _get_profile(device, profile_str)) == NULL) { + pa_log_error("Can't get profile %s", profile_str); + return -1; + } + + if (profile_remove_source(profile, source) < 0) { + pa_log_error("Can't remove from profile"); + return -1; + } + + return 0; +} + +int pa_tz_device_profile_remove_sink_with_role(pa_tz_device *device, const char *profile_str, const char *role) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(device_role_is_valid(role)); + + pa_log_info("device profile remove sink with role, device(%u) profile(%s) role(%s)", + device->id, pa_strempty(profile_str), role); + + if ((profile = _get_profile(device, profile_str)) == NULL) { + pa_log_error("Can't get profile %s", profile_str); + return -1; + } + + if (profile_remove_sink_with_role(profile, role) < 0) { + pa_log_error("Can't remove from profile"); + return -1; + } + + return 0; +} + +int pa_tz_device_profile_remove_source_with_role(pa_tz_device *device, const char *profile_str, const char *role) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(device_role_is_valid(role)); + + pa_log_info("device profile remove source with role, device(%u) profile(%s) role(%s)", + device->id, pa_strempty(profile_str), role); + + if ((profile = _get_profile(device, profile_str)) == NULL) { + pa_log_error("Can't get profile %s", profile_str); + return -1; + } + + if (profile_remove_source_with_role(profile, role) < 0) { + pa_log_error("Can't remove from profile"); + return -1; + } + + return 0; +} + +pa_sink* pa_tz_device_profile_get_sink(pa_tz_device *device, const char *profile_str, const char *role) { + pa_sink *sink; + pa_tz_profile *profile; + + pa_assert(device); + + pa_log_info("device profile get sink, device(%u) profile(%s) role(%s)", + device->id, pa_strempty(profile_str), role); + + if ((profile = _get_profile(device, profile_str)) == NULL) { + pa_log_error("Can't get profile %s", profile_str); + return NULL; + } + + if ((sink = profile_get_sink(profile, role)) == NULL) { + pa_log_error("Can't get sink from profile"); + return NULL; + } + + return sink; +} + +pa_source* pa_tz_device_profile_get_source(pa_tz_device *device, const char *profile_str, const char *role) { + pa_source *source; + pa_tz_profile *profile; + + pa_assert(device); + + pa_log_info("device profile get source, device(%u) profile(%s) role(%s)", + device->id, pa_strempty(profile_str), role); + + if ((profile = _get_profile(device, profile_str)) == NULL) { + pa_log_error("Can't get profile %s", profile_str); + return NULL; + } + + if ((source = profile_get_source(profile, role)) == NULL) { + pa_log_error("Can't get source from profile"); + return NULL; + } + + return source; +} + +void pa_tz_device_free(pa_tz_device *device) { + pa_assert(device); + + pa_log_info("Free device type(%s) id(%u) name(%s) system_id(%s)", + device->type, device->id, device->name, device->system_id); + + pa_tz_device_dump_info(device, PA_LOG_INFO); + + pa_idxset_remove_by_data(device->list, device, NULL); + notify_device_connection_changed(device, false); + + pa_xfree(device->type); + pa_xfree(device->name); + pa_xfree(device->system_id); + + pa_idxset_free(device->profiles, (pa_free_cb_t)profile_free); + + pa_xfree(device); +} + +/* pa_tz_profile_new_data */ +void pa_tz_profile_new_data_init(pa_tz_profile_new_data *profile_data) { + pa_assert(profile_data); + + profile_data->profile = NULL; + profile_data->direction = DM_DEVICE_DIRECTION_NONE; + + profile_data->playback_pcms= pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + profile_data->capture_pcms = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); +} + +void pa_tz_profile_new_data_set_direction(pa_tz_profile_new_data *profile_data, dm_device_direction_t direction) { + pa_assert(profile_data); + + profile_data->direction = direction; +} + +void pa_tz_profile_new_data_set_profile(pa_tz_profile_new_data *profile_data, const char *profile) { + pa_assert(profile_data); + + profile_data->profile = pa_xstrdup(profile); +} + +void pa_tz_profile_new_data_set_use_internal_codec(pa_tz_profile_new_data *profile_data, bool use_internal_codec) { + pa_assert(profile_data); + profile_data->use_internal_codec = use_internal_codec; +} + +void pa_tz_profile_new_data_add_sink(pa_tz_profile_new_data *profile_data, const char *role, pa_sink *sink) { + pa_assert(profile_data); + + pa_hashmap_put(profile_data->playback_pcms, (void*)role, sink); +} + +void pa_tz_profile_new_data_add_source(pa_tz_profile_new_data *profile_data, const char *role, pa_source *source) { + pa_assert(profile_data); + + pa_hashmap_put(profile_data->capture_pcms, (void*)role, source); +} + +void pa_tz_profile_new_data_done(pa_tz_profile_new_data *profile_data) { + pa_assert(profile_data); + + pa_xfree(profile_data->profile); +} + +/* exported api */ +pa_sink* pa_tz_device_get_sink(pa_tz_device *device, const char *role) { + pa_tz_profile *profile; + pa_sink *sink; + + pa_assert(device); + pa_assert(profile = _get_active_profile(device)); + + pa_log_info("device get sink, device(%u) role(%s), active-profile(%s)", + device->id, role, pa_strempty(profile->profile)); + + if ((sink = profile_get_sink(profile, role)) == NULL) { + pa_log_error("Failed to get sink from profile"); + return NULL; + } + + return sink; +} + +pa_source* pa_tz_device_get_source(pa_tz_device *device, const char *role) { + pa_tz_profile *profile; + pa_source *source; + + pa_assert(device); + pa_assert(profile = _get_active_profile(device)); + + pa_log_info("device get source, device(%u) role(%s), active-profile(%s)", + device->id, role, pa_strempty(profile->profile)); + + if ((source = profile_get_source(profile, role)) == NULL) { + pa_log_error("Failed to get source from profile"); + return NULL; + } + + return source; +} + +void pa_tz_device_set_state(pa_tz_device *device, dm_device_direction_t direction, dm_device_state_t state) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(profile = _get_active_profile(device)); + + pa_log_info("device set state, device(%u) type(%s) active-profile(%s) direction(%s) -> %d", + device->id, device->type, pa_strempty(profile->profile), device_direction_to_string(direction), state); + profile_set_state(profile, direction, state); +} + +dm_device_state_t pa_tz_device_get_state(pa_tz_device *device, dm_device_direction_t direction) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(profile = _get_active_profile(device)); + + return profile_get_state(profile, direction); +} + +uint32_t pa_tz_device_get_id(pa_tz_device *device) { + pa_assert(device); + + return device->id; +} + +char* pa_tz_device_get_type(pa_tz_device *device) { + pa_assert(device); + + return device->type; +} + +char* pa_tz_device_get_name(pa_tz_device *device) { + pa_assert(device); + + return device->name; +} + +char* pa_tz_device_get_system_id(pa_tz_device *device) { + pa_assert(device); + + return device->system_id; +} + +char* pa_tz_device_get_profile(pa_tz_device *device) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(profile = _get_active_profile(device)); + + return profile->profile; +} + +dm_device_direction_t pa_tz_device_get_direction(pa_tz_device *device) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(profile = _get_active_profile(device)); + + return profile->direction; +} + +pa_usec_t pa_tz_device_get_creation_time(pa_tz_device *device) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(profile = _get_active_profile(device)); + + return profile->creation_time; +} + +bool pa_tz_device_is_use_internal_codec(pa_tz_device *device) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(profile = _get_active_profile(device)); + + return profile->use_internal_codec; +} + +unsigned pa_tz_device_get_profile_num(pa_tz_device *device) { + pa_assert(device); + pa_assert(device->profiles); + + return pa_idxset_size(device->profiles); +} + +bool pa_tz_device_have_profile(pa_tz_device *device, const char *profile) { + pa_assert(device); + + if (_get_profile(device, profile) == NULL) + return false; + else + return true; +} + +static int method_call_bt_sco(pa_dbus_connection *conn, bool onoff) { + DBusMessage *msg, *reply; + DBusError err; + const char *method; + + pa_assert(conn); + + method = onoff ? "Play" : "Stop"; + if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_HFP_AGENT, DBUS_OBJECT_HFP_AGENT, DBUS_INTERFACE_HFP_AGENT, method))) { + pa_log_error("dbus method call failed"); + return -1; + } + + dbus_error_init(&err); + if (!(reply = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(conn), msg, -1, &err))) { + pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_HFP_AGENT, method, err.message); + dbus_error_free(&err); + return -1; + } + + dbus_message_unref(reply); + return 0; +} + +static int method_call_bt_sco_get_property(pa_dbus_connection *conn, bool *is_wide_band, bool *nrec) { + DBusMessage *msg, *reply; + DBusMessageIter reply_iter, reply_iter_entry; + DBusError err; + unsigned int codec; + const char *property; + + pa_assert(conn); + + if (!is_wide_band && !nrec) { + return -1; + } + + if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_HFP_AGENT, DBUS_OBJECT_HFP_AGENT, DBUS_INTERFACE_HFP_AGENT, "GetProperties"))) { + pa_log_error("dbus method call failed"); + return -1; + } + + dbus_error_init(&err); + if (!(reply = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(conn), msg, -1, &err))) { + pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_HFP_AGENT, "GetProperties", err.message); + dbus_error_free(&err); + return -1; + } + + dbus_message_iter_init(reply, &reply_iter); + + if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) { + pa_log_error("Cannot get reply argument"); + return -1; + } + + dbus_message_iter_recurse(&reply_iter, &reply_iter_entry); + + while (dbus_message_iter_get_arg_type(&reply_iter_entry) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter dict_entry, dict_entry_val; + dbus_message_iter_recurse(&reply_iter_entry, &dict_entry); + dbus_message_iter_get_basic(&dict_entry, &property); + pa_log_debug("String received = %s", property); + if (property) { + if (pa_streq("codec", property) && is_wide_band) { + dbus_message_iter_next(&dict_entry); + dbus_message_iter_recurse(&dict_entry, &dict_entry_val); + if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_UINT32) + continue; + dbus_message_iter_get_basic(&dict_entry_val, &codec); + pa_log_debug("Codec = [%d]", codec); + *is_wide_band = (codec == BT_MSBC_CODEC_ID) ? true : false; + } else if (pa_streq("nrec", property) && nrec) { + dbus_message_iter_next(&dict_entry); + dbus_message_iter_recurse(&dict_entry, &dict_entry_val); + if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_BOOLEAN) + continue; + dbus_message_iter_get_basic(&dict_entry_val, nrec); + pa_log_debug("nrec= [%d]", *nrec); + } + } + dbus_message_iter_next(&reply_iter_entry); + } + + + dbus_message_unref(reply); + return 0; +} + +/* only for bt device, which have sco profile */ +int pa_tz_device_sco_open(pa_tz_device *device) { + pa_tz_profile *profile; + + pa_assert(device); + pa_assert(device->dbus_conn); + + pa_log_info("BT SCO Open for device(%u)", device->id); + if (pa_streq(device->type, DEVICE_TYPE_BT) == false) { + pa_log_error("Not BT device"); + return -1; + } + if ((profile = _get_profile(device, DEVICE_PROFILE_BT_SCO)) == NULL) { + pa_log_error("No BT SCO profile"); + return -1; + } + + if (profile->sco_opened) { + pa_log_warn("SCO already opened"); + return -1; + } + + if (method_call_bt_sco(device->dbus_conn, true) < 0) { + pa_log_error("Failed to bt sco on"); + return -1; + } + + profile->sco_opened = true; + _set_active_profile(device, DEVICE_PROFILE_BT_SCO, false); + pa_tz_device_dump_info(profile->device, PA_LOG_DEBUG); + pa_log_info("BT SCO Open - SUCCESS"); + + return 0; +} + +/* only for bt device, which have sco profile */ +int pa_tz_device_sco_close(pa_tz_device *device) { + pa_tz_profile *profile; + pa_assert(device); + + pa_log_info("BT SCO Close for device(%u)", device->id); + + if (pa_streq(device->type, DEVICE_TYPE_BT) == false) { + pa_log_error("Not BT device"); + return -1; + } + if ((profile = _get_profile(device, DEVICE_PROFILE_BT_SCO)) == NULL) { + pa_log_error("No BT SCO profile"); + return -1; + } + + if (profile->sco_opened == false) { + pa_log_warn("SCO not opened"); + return -1; + } + + if (method_call_bt_sco(device->dbus_conn, false) < 0) { + pa_log_error("Failed to bt sco on"); + return -1; + } + + profile->sco_opened = false; + if (pa_tz_device_have_profile(device, DEVICE_PROFILE_BT_A2DP)) + _set_active_profile(device, DEVICE_PROFILE_BT_A2DP, false); + pa_tz_device_dump_info(profile->device, PA_LOG_DEBUG); + pa_log_info("BT SCO Close - Success"); + + return 0; +} + +/* only for bt device, which have sco profile */ +int pa_tz_device_sco_get_property(pa_tz_device *device, bool *is_wide_band, bool *nrec) { + pa_assert(device); + + pa_log_info("BT SCO get property for device(%u)", device->id); + if (pa_streq(device->type, DEVICE_TYPE_BT) == false) { + pa_log_error("Not BT device"); + return -1; + } + if ((_get_profile(device, DEVICE_PROFILE_BT_SCO)) == NULL) { + pa_log_error("No BT SCO profile"); + return -1; + } + + if (method_call_bt_sco_get_property(device->dbus_conn, is_wide_band, nrec) < 0) { + pa_log_error("Failed to get BT SCO Property"); + return -1; + } + + pa_log_info("BT SCO Get Property - Success, is wide band : %s, nrec : %s", pa_yes_no(is_wide_band), pa_yes_no(nrec)); + + return 0; +} + +/* only for bt device */ +int pa_tz_device_sco_get_status(pa_tz_device *device, dm_device_bt_sco_status_t *status) { + pa_tz_profile *profile; + pa_assert(device); + + pa_log_info("BT SCO get status for device(%u)", device->id); + if (pa_streq(device->type, DEVICE_TYPE_BT) == false) { + pa_log_error("Not BT device"); + return -1; + } + if (status == NULL) { + pa_log_error("invalid parameter"); + return -1; + } + + if ((profile = _get_profile(device, DEVICE_PROFILE_BT_SCO))) { + if (profile->sco_opened == false) + *status = DM_DEVICE_BT_SCO_STATUS_CONNECTED; + else + *status = DM_DEVICE_BT_SCO_STATUS_OPENED; + } else { + *status = DM_DEVICE_BT_SCO_STATUS_DISCONNECTED; + } + + pa_log_debug("BT SCO Get Status, %d", *status); + return 0; +} + diff --git a/src/tizen-device.h b/src/tizen-device.h new file mode 100644 index 0000000..9cd4f75 --- /dev/null +++ b/src/tizen-device.h @@ -0,0 +1,208 @@ +#ifndef footizendevicefoo +#define footizendevicefoo + +#include +#include "tizen-device-def.h" +#include "communicator.h" +#ifdef HAVE_DBUS +#include +#include +#endif + +typedef struct pa_tz_device pa_tz_device; +typedef struct pa_tz_profile pa_tz_profile; +typedef struct pa_tz_device_new_data pa_tz_device_new_data; +typedef struct pa_tz_profile_new_data pa_tz_profile_new_data; + +/* structures for represent device items which can be connected/disconnected */ +/* + Before beginning, There are two structure(pa_tz_device, pa_tz_profile) + for represent device by following reasons. + When bt-a2dp and bt-sco are on physically same device ,it is of course same device. + So those physically same device item are represended by pa_tz_device, + and each profile is represented by pa_tz_profile. +*/ + +/* + Structure to represent physicall device, + which can have multiple profiles (ex. bt-a2dp and sco). + If this is created or freed, device connected/disconnected + hook(for internal)/callback(for apps) will be called. +*/ +struct pa_tz_device { + char *type; + char *name; + /* Decimal ID which is unique in device list + * This will be exported up to sound_manager_get_device_id */ + uint32_t id; + /* String ID which will be used internally + * In multi-Device case(bt, usb), this will be used to classify + * each physicall device */ + char *system_id; + + /* Even though there are several profiles in device, + * only one profile can be activated. + * This indicate current activat profile */ + uint32_t active_profile; + /* Have only one item except bt device */ + /* pa_tz_profile* profiles[PROFILE_NUM_MAX]; */ + pa_idxset *profiles; + + /* Devices are contained in this list */ + pa_idxset *list; + + pa_communicator *comm; + pa_dbus_connection *dbus_conn; +}; + +struct pa_tz_device_new_data { + char *type; + char *name; + /* for multi-device type(bt, usb) */ + char *system_id; + + /* for solo profile type */ + dm_device_direction_t direction; + bool use_internal_codec; + pa_hashmap *playback_pcms; + pa_hashmap *capture_pcms; + + /* for multi profile type */ + pa_tz_profile_new_data* profile_data[PROFILE_NUM_MAX]; + uint32_t n_profile; + uint32_t active_profile; + + pa_idxset *list; + pa_communicator *comm; + pa_dbus_connection *dbus_conn; +}; + +struct pa_tz_profile_new_data { + char *profile; + dm_device_direction_t direction; + + pa_hashmap *playback_pcms; + pa_hashmap *capture_pcms; + + bool use_internal_codec; +}; + +/* + Structure to represent each device profile (subtype). + Even if both-way device(earjack, sco..) ,one device_profile. +*/ +struct pa_tz_profile { + /* This can be null except bt device */ + char *profile; + dm_device_direction_t direction; + + /* Set by stream-manager + * If this is changed, will be notifacted */ + dm_device_state_t playback_state; + dm_device_state_t capture_state; + + /* Can get proper sink/source in hashmaps with key(=device_role) */ + pa_hashmap *playback_devices; + pa_hashmap *capture_devices; + + /* device belongs to */ + pa_tz_device *device; + + /* creation time */ + pa_usec_t creation_time; + + /* Will be true, if this profile uses internal codec(card), + * false, if this profile uses external card(bt-a2dp, usb */ + bool use_internal_codec; + /* If this is sco profile, this can be used to */ + bool sco_opened; +}; + +typedef struct _hook_call_data_for_conn_changed { + uint32_t event_id; + bool is_connected; + pa_tz_device *device; +} pa_device_manager_hook_data_for_conn_changed; + +typedef struct _hook_call_data_for_info_changed { + uint32_t event_id; + dm_device_changed_info_t changed_info; + pa_tz_device *device; +} pa_device_manager_hook_data_for_info_changed; + +/*** For device manager ***/ +void pa_tz_device_dump_info(pa_tz_device *device, pa_log_level_t log_level); +void pa_tz_device_new_data_init(pa_tz_device_new_data *data, pa_idxset *list, pa_communicator *comm, pa_dbus_connection *conn); +void pa_tz_device_new_data_set_type(pa_tz_device_new_data *data, const char *type); +void pa_tz_device_new_data_set_name(pa_tz_device_new_data *data, const char *name); +void pa_tz_device_new_data_set_direction(pa_tz_device_new_data *data, dm_device_direction_t direction); +/* deivce which is multi-device type should have system_id */ +void pa_tz_device_new_data_set_system_id(pa_tz_device_new_data *data, const char *system_id); +void pa_tz_device_new_data_set_use_internal_codec(pa_tz_device_new_data *data, bool use_internal_codec); +void pa_tz_device_new_data_add_sink(pa_tz_device_new_data *data, const char *role, pa_sink *sink); +void pa_tz_device_new_data_add_source(pa_tz_device_new_data *data, const char *role, pa_source *source); +void pa_tz_device_new_data_done(pa_tz_device_new_data *data); +/* For multi profile device */ +void pa_tz_device_new_data_add_profile(pa_tz_device_new_data *data, pa_tz_profile_new_data *profile_data, bool as_active); + +/* Create tizen device instance, + * device connected hook will be fired */ +pa_tz_device* pa_tz_device_new(pa_tz_device_new_data *data); +/* Destroy tizen device instance, + * device disconnected hook will be fired */ +void pa_tz_device_free(pa_tz_device *device); +/* Can be used add/remove sink/source in runtime */ +int pa_tz_device_add_sink(pa_tz_device *device, const char *role, pa_sink *sink); +int pa_tz_device_add_source(pa_tz_device *device, const char *role, pa_source *source); +int pa_tz_device_remove_sink(pa_tz_device *device, pa_sink *sink); +int pa_tz_device_remove_source(pa_tz_device *device, pa_source *source); +int pa_tz_device_remove_sink_with_role(pa_tz_device *device, const char *role); +int pa_tz_device_remove_source_with_role(pa_tz_device *device, const char *role); + +/* For multi profile device */ +int pa_tz_device_add_profile(pa_tz_device *device, pa_tz_profile_new_data *pdata, bool as_active); +int pa_tz_device_remove_profile(pa_tz_device *device, const char *profile); +int pa_tz_device_profile_add_sink(pa_tz_device *device, const char *profile, const char *role, pa_sink *sink); +int pa_tz_device_profile_add_source(pa_tz_device *device, const char *profile, const char *role, pa_source *source); +int pa_tz_device_profile_remove_sink(pa_tz_device *device, const char *profile, pa_sink *sink); +int pa_tz_device_profile_remove_source(pa_tz_device *device, const char *profile, pa_source *source); +int pa_tz_device_profile_remove_sink_with_role(pa_tz_device *device, const char *profile, const char *role); +int pa_tz_device_profile_remove_source_with_role(pa_tz_device *device, const char *profile, const char *role); +pa_sink* pa_tz_device_profile_get_sink(pa_tz_device *device, const char *profile, const char *role); +pa_source* pa_tz_device_profile_get_source(pa_tz_device *device, const char *profile, const char *role); + +/* This APIs can be used with pa_tz_device_new_data_add_profile or + * pa_tz_device_add_profile */ +void pa_tz_profile_new_data_init(pa_tz_profile_new_data *profile_data); +void pa_tz_profile_new_data_set_direction(pa_tz_profile_new_data *profile_data, dm_device_direction_t direction); +void pa_tz_profile_new_data_set_profile(pa_tz_profile_new_data *profile_data, const char *profile); +void pa_tz_profile_new_data_set_use_internal_codec(pa_tz_profile_new_data *profile_data, bool use_internal_codec); +void pa_tz_profile_new_data_add_sink(pa_tz_profile_new_data *profile_data, const char *role, pa_sink *sink); +void pa_tz_profile_new_data_add_source(pa_tz_profile_new_data *profile_data, const char *role, pa_source *source); +void pa_tz_profile_new_data_done(pa_tz_profile_new_data *profile_data); + +/* Exported API for other modules */ +pa_sink* pa_tz_device_get_sink(pa_tz_device *device, const char *role); +pa_source* pa_tz_device_get_source(pa_tz_device *device, const char *role); +void pa_tz_device_set_state(pa_tz_device *device, dm_device_direction_t direction, dm_device_state_t state); +dm_device_state_t pa_tz_device_get_state(pa_tz_device *device, dm_device_direction_t direction); +uint32_t pa_tz_device_get_id(pa_tz_device *device); +char* pa_tz_device_get_type(pa_tz_device *device); +char* pa_tz_device_get_name(pa_tz_device *device); +char* pa_tz_device_get_system_id(pa_tz_device *device); +char* pa_tz_device_get_profile(pa_tz_device *device); +dm_device_direction_t pa_tz_device_get_direction(pa_tz_device *device); +pa_usec_t pa_tz_device_get_creation_time(pa_tz_device *device); +bool pa_tz_device_is_use_internal_codec(pa_tz_device *device); +unsigned pa_tz_device_get_profile_num(pa_tz_device *device); +bool pa_tz_device_have_profile(pa_tz_device *device, const char *profile); + +/* Only for BT device + * Check device type and check also sco profile + * with pa_tz_device_have_profile */ +int pa_tz_device_sco_open(pa_tz_device *device); +int pa_tz_device_sco_close(pa_tz_device *device); +int pa_tz_device_sco_get_property(pa_tz_device *device, bool *is_wide_band, bool *nrec); +int pa_tz_device_sco_get_status(pa_tz_device *device, dm_device_bt_sco_status_t *status); + +#endif -- 2.7.4 From 11806886e89301547dfb9380bace262d67c5d52d Mon Sep 17 00:00:00 2001 From: Mok Jeongho Date: Thu, 8 Sep 2016 15:55:49 +0900 Subject: [PATCH 16/16] Remove build warning [Version] 5.0.72 [Profile] Common [Issue Type] Build Warning Change-Id: I3d3f65f119c6324b12ab07b64d0f9198c7a9ec11 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager.c | 42 --------------------------------- 2 files changed, 1 insertion(+), 43 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 54d30b1..707ad1a 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.71 +Version: 5.0.72 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager.c b/src/device-manager.c index 4cd9abb..b563845 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -865,35 +865,6 @@ static void _device_set_detected(pa_device_manager *manager, const char *type, c } } -/* return system_id of sco connected/opened bt device */ -static int _device_get_detected_sco(pa_device_manager *manager, device_detected_type_t detected, - char **system_id, char **name) { - struct device_status_info *status_info; - uint32_t status_idx; - - pa_assert(manager); - pa_assert(manager->device_status); - - if (detected != DEVICE_CONNECTED_SCO && detected != DEVICE_OPENED_SCO) { - pa_log_warn("Invalid detected type for sco"); - return -1; - } - - PA_IDXSET_FOREACH(status_info, manager->device_status, status_idx) { - if (device_type_is_equal(status_info->type, status_info->profile, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO)) { - if (status_info->detected == detected) { - if (system_id) - *system_id = status_info->system_id; - if (name) - *name = status_info->name; - return 0; - } - } - } - - return -1; -} - static pa_tz_device* _device_list_get_device(pa_device_manager *manager, const char *type, const char *system_id) { pa_tz_device *device; uint32_t idx; @@ -941,19 +912,6 @@ static pa_tz_device* _device_list_get_device_with_id(pa_device_manager *manager, return NULL; } -static void dump_device_list_info(pa_device_manager *dm, pa_log_level_t log_level) { - pa_tz_device *device; - uint32_t device_idx; - - if (!dm || !dm->device_list) - return; - - pa_logl(log_level, "=========== Device List ================\n"); - PA_IDXSET_FOREACH(device, dm->device_list, device_idx) - pa_tz_device_dump_info(device, log_level); - pa_logl(log_level, "========================================\n"); -} - static const char* build_params_to_load_device(const char *device_string, const char *params, dm_device_class_t device_class) { pa_strbuf *args_buf; static char args[DEVICE_PARAM_STRING_MAX] = {0,}; -- 2.7.4