stream-manager: Add support for stream restriction 45/67645/6 accepted/tizen/common/20160504.125848 accepted/tizen/ivi/20160504.011132 accepted/tizen/mobile/20160504.011038 accepted/tizen/tv/20160504.011057 accepted/tizen/wearable/20160504.011113 submit/tizen/20160503.074218
authorSangchul Lee <sc11.lee@samsung.com>
Wed, 27 Apr 2016 09:45:02 +0000 (18:45 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Fri, 29 Apr 2016 04:49:51 +0000 (13:49 +0900)
dbus method is added.
 - name: UpdateRestriction
 - args: name(string[in]), value(uint32[in]), ret_msg(string[out])

We support "block_recording_media" as the name for now.
It can be called when recording streams of media role should be blocked.

[Version] 5.0.49
[Profile] Common
[Issue Type] New feature

Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
Change-Id: I4f7ef2f3ab7a824456bff57a44fe99a1e6ad284b

Makefile.am
packaging/pulseaudio-modules-tizen.spec
src/stream-manager-priv.h
src/stream-manager-restriction-priv.h [new file with mode: 0644]
src/stream-manager-restriction.c [new file with mode: 0644]
src/stream-manager.c

index 688285b..7eb6812 100644 (file)
@@ -81,6 +81,7 @@ module_policy_la_SOURCES = \
           src/communicator.c   src/communicator.h   \
           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/subscribe-observer.c   src/subscribe-observer.h
 module_policy_la_LDFLAGS = $(MODULE_LDFLAGS) $(PACORE_LDFLAGS) $(PA_LDFLAGS) -L$(pulsemodlibexecdir)
index d3088c0..a978fab 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          5.0.48
+Version:          5.0.49
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 22c75b1..2d1fb4e 100644 (file)
@@ -66,17 +66,24 @@ typedef struct _prior_max_priority_stream {
     const char *role_so;
 } cur_max_priority_stream;
 
+typedef struct _stream_restrictions {
+    bool block_recording_media;
+} stream_restrictions;
+
 struct _stream_manager {
     pa_core *core;
     pa_hal_manager *hal;
     pa_device_manager *dm;
     pa_subscribe_observer *subs_ob;
+
     pa_hashmap *volume_infos;
     pa_hashmap *volume_modifiers;
     pa_hashmap *stream_infos;
     pa_hashmap *stream_parents;
     pa_hashmap *muted_streams;
     cur_max_priority_stream cur_highest_priority;
+    stream_restrictions restrictions;
+
     pa_hook_slot
         *sink_input_new_slot,
         *sink_input_put_slot,
@@ -90,6 +97,7 @@ struct _stream_manager {
         *source_output_state_changed_slot,
         *source_output_move_start_slot,
         *source_output_move_finish_slot;
+
 #ifdef HAVE_DBUS
 #ifdef USE_DBUS_PROTOCOL
     pa_dbus_protocol *dbus_protocol;
@@ -98,6 +106,7 @@ struct _stream_manager {
 #endif
 #endif
     pa_subscription *subscription;
+
     struct {
         pa_communicator *comm;
         pa_hook_slot *comm_hook_device_connection_changed_slot;
diff --git a/src/stream-manager-restriction-priv.h b/src/stream-manager-restriction-priv.h
new file mode 100644 (file)
index 0000000..dcc5ce8
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef foostreammanagerrestrictionprivfoo
+#define foostreammanagerrestrictionprivfoo
+
+#include "stream-manager.h"
+
+/* dbus method args */
+#define STREAM_MANAGER_METHOD_ARGS_BLOCK_RECORDING_MEDIA     "block_recording_media"
+
+int32_t handle_restrictions(pa_stream_manager *m, const char *name, uint32_t value);
+bool check_restrictions(pa_stream_manager *m, void *stream, stream_type_t stream_type);
+
+#endif
diff --git a/src/stream-manager-restriction.c b/src/stream-manager-restriction.c
new file mode 100644 (file)
index 0000000..69f309f
--- /dev/null
@@ -0,0 +1,77 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2016 Sangchul Lee <sc11.lee@samsung.com>
+
+  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 <config.h>
+#endif
+
+#include "stream-manager-priv.h"
+#include "stream-manager-restriction-priv.h"
+
+int32_t handle_restrictions(pa_stream_manager *m, const char *name, uint32_t value) {
+    const char *role;
+    void *s;
+    uint32_t idx;
+
+    pa_assert(m);
+
+    if (pa_streq(name, STREAM_MANAGER_METHOD_ARGS_BLOCK_RECORDING_MEDIA) ) {
+        if (value == 1) {
+            pa_log_info("block recording(media)");
+            m->restrictions.block_recording_media = true;
+            PA_IDXSET_FOREACH(s, m->core->source_outputs, idx) {
+                role = pa_proplist_gets(GET_STREAM_PROPLIST(s, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_ROLE);
+                if (pa_streq(role, "media")) {
+                    pa_log_info("  -- kill source-output(%p, %u)", s, ((pa_source_output*)s)->index);
+                    pa_source_output_kill((pa_source_output*)s);
+                }
+            }
+        } else if (value == 0) {
+            pa_log_info("recording(media) is now available");
+            m->restrictions.block_recording_media = false;
+        } else {
+            pa_log_error("unknown value");
+            return -1;
+        }
+    } else {
+        pa_log_error("unknown name");
+        return -1;
+    }
+
+    return 0;
+}
+
+bool check_restrictions(pa_stream_manager *m, void *stream, stream_type_t type) {
+    const char *role;
+
+    pa_assert(m);
+
+    /* check for media recording */
+    if (m->restrictions.block_recording_media && type == STREAM_SOURCE_OUTPUT) {
+        role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE);
+        if (pa_streq(role, "media")) {
+            pa_log_warn("recording(media) is not allowed");
+            return true;
+        }
+    }
+
+    return false;
+}
\ No newline at end of file
index 64c17c6..4aa649b 100644 (file)
@@ -44,6 +44,7 @@
 #include "stream-manager.h"
 #include "stream-manager-priv.h"
 #include "stream-manager-volume-priv.h"
+#include "stream-manager-restriction-priv.h"
 
 #ifdef HAVE_DBUS
 #define ARR_ARG_MAX  32
@@ -61,6 +62,7 @@
 #define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MUTE            "GetVolumeMute"
 #define STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE    "GetCurrentVolumeType" /* the type that belongs to the stream of the current max priority */
 #define STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS        "UpdateFocusStatus"
+#define STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION         "UpdateRestriction"
 /* signal */
 #define STREAM_MANAGER_SIGNAL_NAME_VOLUME_CHANGED             "VolumeChanged"
 #define STREAM_MANAGER_SIGNAL_NAME_COMMAND                    "Command"
@@ -79,6 +81,7 @@ static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void
 static void handle_get_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_update_restriction(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void send_volume_changed_signal(DBusConnection *conn, const char *direction, const char *volume_type, const uint32_t volume_level);
 static void send_command_signal(DBusConnection *conn, const char *name, int value);
 
@@ -94,6 +97,7 @@ enum method_handler_index {
     METHOD_HANDLER_GET_VOLUME_MUTE,
     METHOD_HANDLER_GET_CURRENT_VOLUME_TYPE,
     METHOD_HANDLER_UPDATE_FOCUS_STATUS,
+    METHOD_HANDLER_UPDATE_RESTRICTION,
     METHOD_HANDLER_MAX
 };
 
@@ -128,11 +132,11 @@ static pa_dbus_arg_info get_volume_max_level_args[]  = { { "io_direction", "s",
                                                            { "ret_msg", "s", "out" } };
 static pa_dbus_arg_info set_volume_mute_args[]  = { { "io_direction", "s", "in" },
                                                             { "type", "s", "in" },
-                                                          { "on/off", "u", "in" },
+                                                              { "on", "u", "in" },
                                                       { "ret_msg", "s", "out" } };
 static pa_dbus_arg_info get_volume_mute_args[]  = { { "io_direction", "s", "in" },
                                                             { "type", "s", "in" },
-                                                         { "on/off", "u", "out" },
+                                                             { "on", "u", "out" },
                                                       { "ret_msg", "s", "out" } };
 static pa_dbus_arg_info get_current_volume_type_args[]  = { { "io_direction", "s", "in" },
                                                                    { "type", "s", "out" },
@@ -140,7 +144,10 @@ static pa_dbus_arg_info get_current_volume_type_args[]  = { { "io_direction", "s
 static pa_dbus_arg_info update_focus_status_args[]  = { { "parent_id", "u", "in" },
                                                      { "focus_status", "u", "in" },
                                                        { "ret_msg", "s", "out" } };
-static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "uu"};
+static pa_dbus_arg_info update_restriction_args[]  = { { "name", "s", "in" },
+                                                      { "value", "u", "in" },
+                                                 { "ret_msg", "s", "out" } };
+static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "uu", "su"};
 
 static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
     [METHOD_HANDLER_GET_STREAM_INFO] = {
@@ -198,6 +205,11 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
         .arguments = update_focus_status_args,
         .n_arguments = sizeof(update_focus_status_args) / sizeof(pa_dbus_arg_info),
         .receive_cb = handle_update_focus_status },
+    [METHOD_HANDLER_UPDATE_RESTRICTION] = {
+        .method_name = STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION,
+        .arguments = update_restriction_args,
+        .n_arguments = sizeof(update_restriction_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_update_restriction },
 };
 
 const char *dbus_str_none = "none";
@@ -273,13 +285,13 @@ static pa_dbus_interface_info stream_manager_interface_info = {
     "  <method name=\"STREAM_MANAGER_METHOD_NAME_SET_VOLUME_MUTE\">"         \
     "   <arg name=\"io_direction\" direction=\"in\" type=\"s\"/>"            \
     "   <arg name=\"type\" direction=\"in\" type=\"s\"/>"                    \
-    "   <arg name=\"on/off\" direction=\"in\" type=\"u\"/>"                  \
+    "   <arg name=\"on\" direction=\"in\" type=\"u\"/>"                      \
     "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                \
     "  </method>"                                                            \
     "  <method name=\"STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MUTE\">"         \
     "   <arg name=\"io_direction\" direction=\"in\" type=\"s\"/>"            \
     "   <arg name=\"type\" direction=\"in\" type=\"s\"/>"                    \
-    "   <arg name=\"on/off\" direction=\"out\" type=\"u\"/>"                 \
+    "   <arg name=\"on\" direction=\"out\" type=\"u\"/>"                     \
     "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                \
     "  </method>"                                                            \
     "  <method name=\"STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE\">" \
@@ -292,6 +304,11 @@ static pa_dbus_interface_info stream_manager_interface_info = {
     "   <arg name=\"focus_status\" direction=\"in\" type=\"u\"/>"            \
     "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                \
     "  </method>"                                                            \
+    "  <method name=\"STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION\">"      \
+    "   <arg name=\"name\" direction=\"in\" type=\"s\"/>"                    \
+    "   <arg name=\"value\" direction=\"in\" type=\"u\"/>"                   \
+    "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                \
+    "  </method>"                                                            \
     "  <signal name=\"STREAM_MANAGER_SIGNAL_NAME_VOLUME_CHANGED\">"          \
     "   <arg name=\"direction\" type=\"s\"/>"                                \
     "   <arg name=\"volume_type\" type=\"s\"/>"                              \
@@ -1146,6 +1163,36 @@ FAILURE:
     return;
 }
 
+static void handle_update_restriction(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    const char *name;
+    uint32_t value = 0;
+    DBusMessage *reply = NULL;
+    pa_stream_manager *m = (pa_stream_manager*)userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_STRING, &name,
+                                       DBUS_TYPE_UINT32, &value,
+                                       DBUS_TYPE_INVALID));
+    pa_log_info("handle_update_restriction(), name[%s], value[%u]", name, value);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    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;
+    }
+
+    pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID));
+FAILURE:
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+    return;
+}
+
 static DBusHandlerResult handle_methods(DBusConnection *conn, DBusMessage *msg, void *userdata) {
        int idx = 0;
     pa_stream_manager *m = (pa_stream_manager*)userdata;
@@ -2634,7 +2681,8 @@ static pa_hook_result_t source_output_new_cb(pa_core *core, pa_source_output_new
     pa_log_info("start source_output_new_new_cb");
 
     process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_PREPARE, true);
-    /* Update buffer attributes from HAL */
+    if (check_restrictions(m, new_data, STREAM_SOURCE_OUTPUT))
+        return PA_HOOK_CANCEL;
     set_buffer_attribute(m, new_data, STREAM_SOURCE_OUTPUT);
     process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_UPDATE_VOLUME, true);
     process_stream(m, new_data, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED, true);