device-manager: Add API for unload sink/source with device_string 59/109759/5
authorJeongho Mok <jho.mok@samsung.com>
Tue, 10 Jan 2017 03:44:56 +0000 (12:44 +0900)
committerJeongho Mok <jho.mok@samsung.com>
Thu, 12 Jan 2017 09:03:59 +0000 (01:03 -0800)
[Version] 5.0.124
[Profile] Common
[Issue Type] Bug

Change-Id: I31d6779c88d21ffbe86b2ebb913feaecfee0175d

src/device-manager.c
src/device-manager.h

index cd80945..8d73a0c 100644 (file)
@@ -402,6 +402,8 @@ static void handle_is_stream_on_device(DBusConnection *conn, DBusMessage *msg, v
 static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_load_sink(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_unload_sink(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_unload_sink_with_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_dump_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata);
 
@@ -413,6 +415,8 @@ enum method_handler_index {
     METHOD_HANDLER_GET_BT_A2DP_STATUS,
     METHOD_HANDLER_LOAD_SINK,
     METHOD_HANDLER_UNLOAD_SINK,
+    METHOD_HANDLER_UNLOAD_SINK_WITH_DEVICE_STRING,
+    METHOD_HANDLER_GET_DEVICE_STRING,
     METHOD_HANDLER_DUMP_DEVICE_LIST,
     METHOD_HANDLER_STATUS_TEST,
     METHOD_HANDLER_MAX
@@ -434,6 +438,12 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
     [METHOD_HANDLER_UNLOAD_SINK] = {
         .method_name = "UnloadSink",
         .receive_cb = handle_unload_sink},
+    [METHOD_HANDLER_UNLOAD_SINK_WITH_DEVICE_STRING] = {
+        .method_name = "UnloadSinkWithDeviceString",
+        .receive_cb = handle_unload_sink_with_device_string},
+    [METHOD_HANDLER_GET_DEVICE_STRING] = {
+        .method_name = "GetDeviceString",
+        .receive_cb = handle_get_device_string},
     [METHOD_HANDLER_DUMP_DEVICE_LIST] = {
         .method_name = "DumpDeviceList",
         .receive_cb = handle_dump_device_list},
@@ -1073,44 +1083,20 @@ static bool pulse_device_same_device_string(pa_object *pdevice, const char *devi
     return pa_streq(_device_string, device_string);
 }
 
-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;
+static const char* device_type_info_get_device_string(struct device_type_info *type_info, bool is_playback, const char *role) {
+    const char *_role, *device_string;
     void *state;
-    const char *role, *_device_string;
-    dm_device_direction_t direction;
-
-    pa_assert(type_info);
-    pa_assert(device_string);
-
-    direction = device_type_get_static_direction(type_info->type);
-    if (direction == DM_DEVICE_DIRECTION_NONE) {
-        pa_log_debug("Not static direction");
-        return NULL;
-    }
-
-    if (is_playback) {
-        if (direction == DM_DEVICE_DIRECTION_IN) {
-            pa_log_debug("Invalid direction");
-            return NULL;
-        }
-        pcm_devices = type_info->playback_devices;
-    } else {
-        if (direction == DM_DEVICE_DIRECTION_OUT) {
-            pa_log_debug("Invalid direction");
-            return NULL;
-        }
-        pcm_devices = type_info->capture_devices;
-    }
+    pa_hashmap *pcm_devices;
 
-    if (!pcm_devices) {
-        pa_log_warn("No %s pcm devices for %s", is_playback ? "playback" : "capture", type_info->type);
+    pcm_devices = is_playback ? type_info->playback_devices : type_info->capture_devices;
+    if (pcm_devices == NULL) {
+        pa_log_error("No pcm device config for %s %s %s", is_playback ? "Playback" : "Capture", type_info->type, role);
         return NULL;
     }
 
-    PA_HASHMAP_FOREACH_KV(role, _device_string, pcm_devices, state) {
-        if (pa_streq(_device_string, device_string)) {
-            return role;
-        }
+    PA_HASHMAP_FOREACH_KV(_role, device_string, pcm_devices, state) {
+        if (pa_safe_streq(role, _role))
+            return device_string;
     }
 
     return NULL;
@@ -1681,25 +1667,31 @@ static void* load_device(pa_core *c, bool is_sink, const char *device_string, co
 }
 
 static void unload_device(pa_core *c, bool is_sink, const char *device_string) {
+    uint32_t device_idx;
+
     pa_assert(c);
     pa_assert(device_string);
 
     pa_log_info("Unload %s Device : String'%s'", is_sink ? "Playback" : "Capture", device_string);
 
     if (is_sink) {
-        pa_sink *sink = _core_get_sink(c, device_string, NULL);
-        if (sink == NULL) {
-            pa_log_warn("No matching sink");
-            return;
+        pa_sink *sink;
+
+        PA_IDXSET_FOREACH(sink, c->sinks, device_idx) {
+            if (pulse_device_is_monitor(PA_OBJECT(sink)))
+                continue;
+            if (pulse_device_same_device_string(PA_OBJECT(sink), device_string))
+                pa_module_unload(c, sink->module, true);
         }
-        pa_module_unload(c, sink->module, true);
     } else {
-        pa_source *source = _core_get_source(c, device_string, NULL);
-        if (source == NULL) {
-            pa_log_warn("No matching source");
-            return;
+        pa_source *source;
+
+        PA_IDXSET_FOREACH(source, c->sources, device_idx) {
+            if (pulse_device_is_monitor(PA_OBJECT(source)))
+                continue;
+            if (pulse_device_same_device_string(PA_OBJECT(source), device_string))
+                pa_module_unload(c, source->module, true);
         }
-        pa_module_unload(c, source->module, true);
     }
 }
 
@@ -2875,6 +2867,50 @@ static void handle_unload_sink(DBusConnection *conn, DBusMessage *msg, void *use
     dbus_message_unref(reply);
 }
 
+static void handle_unload_sink_with_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_device_manager *dm;
+    char *device_string;
+    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_string,
+                                       DBUS_TYPE_INVALID));
+
+    pa_device_manager_unload_sink_with_device_string(dm, device_string);
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+static void handle_get_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_device_manager *dm;
+    char *type, *role;
+    const char *device_string;
+    dbus_bool_t is_playback;
+    DBusMessage *reply;
+
+    dm = (pa_device_manager *) userdata;
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_BOOLEAN, &is_playback,
+                                       DBUS_TYPE_STRING, &type,
+                                       DBUS_TYPE_STRING, &role,
+                                       DBUS_TYPE_INVALID));
+
+    device_string = pa_device_manager_get_device_string(dm, is_playback, type, role);
+    if (device_string == NULL) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal");
+        return;
+    }
+
+    pa_log_info("device string : %s", device_string);
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+    pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &device_string,
+                                                 DBUS_TYPE_INVALID));
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
 static void handle_dump_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     pa_device_manager *dm;
     pa_tz_device *device;
@@ -3193,6 +3229,13 @@ void pa_device_manager_unload_sink(pa_device_manager *dm, const char *type, cons
     unload_device(dm->core, true, device_string);
 }
 
+void pa_device_manager_unload_sink_with_device_string(pa_device_manager *dm, const char *device_string) {
+    pa_assert(dm);
+    pa_assert(device_string);
+
+    unload_device(dm->core, true, device_string);
+}
+
 pa_source* pa_device_manager_load_source(pa_device_manager *dm, const char *type, const char *role) {
     const char *device_string, *params;
     struct device_type_info *type_info;
@@ -3284,6 +3327,29 @@ void pa_device_manager_unload_source(pa_device_manager *dm, const char *type, co
     unload_device(dm->core, false, device_string);
 }
 
+void pa_device_manager_unload_source_with_device_string(pa_device_manager *dm, const char *device_string) {
+    pa_assert(dm);
+    pa_assert(device_string);
+
+    unload_device(dm->core, false, device_string);
+}
+
+const char* pa_device_manager_get_device_string(pa_device_manager *dm, bool is_playback, const char *type, const char *role) {
+    struct device_type_info *type_info;
+
+    pa_assert(dm);
+    pa_assert(type);
+    pa_assert(role);
+
+    type_info = _device_manager_get_type_info(dm->type_infos, type);
+    if (type_info == NULL) {
+        pa_log_error("No type info for %s", type);
+        return NULL;
+    }
+
+    return device_type_info_get_device_string(type_info, is_playback, role);
+}
+
 static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_conn_changed *data, pa_device_manager *dm) {
     send_device_connection_changed_signal(data->event_id, data->device, data->is_connected, dm);
     return PA_HOOK_OK;
index 389a8f8..0632bf6 100644 (file)
@@ -53,5 +53,9 @@ pa_sink* pa_device_manager_load_sink(pa_device_manager *dm, const char *type, co
 pa_source* pa_device_manager_load_source(pa_device_manager *dm, const char *type, const char *role);
 void pa_device_manager_unload_sink(pa_device_manager *dm, const char *type, const char *role);
 void pa_device_manager_unload_source(pa_device_manager *dm, const char *type, const char *role);
+void pa_device_manager_unload_sink_with_device_string(pa_device_manager *dm, const char *device_string);
+void pa_device_manager_unload_source_with_device_string(pa_device_manager *dm, const char *device_string);
+
+const char* pa_device_manager_get_device_string(pa_device_manager *dm, bool is_playback, const char *type, const char *role);
 
 #endif