Implement DPM requests for camera and mic 87/103487/1 accepted/tizen/common/20161214.160413 accepted/tizen/ivi/20161214.015258 accepted/tizen/mobile/20161214.014723 accepted/tizen/tv/20161214.015038 accepted/tizen/wearable/20161214.015129 submit/tizen/20161213.083228
authorVolodymyr Brynza <v.brynza@samsung.com>
Thu, 8 Dec 2016 11:48:09 +0000 (13:48 +0200)
committerVolodymyr Brynza <v.brynza@samsung.com>
Thu, 8 Dec 2016 11:48:09 +0000 (13:48 +0200)
Change-Id: Ic1e57ca37017a0aac694a457e5b62b00ba0cf55b
Signed-off-by: Volodymyr Brynza <v.brynza@samsung.com>
CMakeLists.txt
include/media_streamer_node.h
include/media_streamer_node_policy.h [new file with mode: 0644]
include/media_streamer_priv.h
packaging/capi-media-streamer.spec
src/media_streamer_node.c
src/media_streamer_node_policy.c [new file with mode: 0644]
src/media_streamer_node_resources.c
src/media_streamer_priv.c

index 0c7e7c5..04a307d 100644 (file)
@@ -10,8 +10,8 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 SET(INC_DIR include)
 INCLUDE_DIRECTORIES(${INC_DIR})
 
-SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore elementary murphy-resource murphy-glib")
-SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore evas elementary murphy-resource murphy-glib")
+SET(dependents "dlog glib-2.0 mm-common capi-media-tool iniparser bundle libtbm gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore elementary murphy-resource murphy-glib dpm")
+SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0 cynara-client capi-system-info ecore evas elementary murphy-resource murphy-glib dpm")
 
 INCLUDE(FindPkgConfig)
 pkg_check_modules(${fw_name} REQUIRED ${dependents})
index f79f9e5..add8a37 100644 (file)
@@ -131,3 +131,4 @@ int __ms_node_set_pad_format(media_streamer_node_s *node, const char *pad_name,
 
 gboolean _ms_node_resouces_acquire_iter(const GValue *item, GValue *ret, gpointer user_data);
 gboolean  _ms_node_resouces_release_iter(const GValue *item, GValue *ret, gpointer user_data);
+gboolean _ms_node_policy_check_iter(const GValue *item, GValue *ret, gpointer user_data);
diff --git a/include/media_streamer_node_policy.h b/include/media_streamer_node_policy.h
new file mode 100644 (file)
index 0000000..5f9adef
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MEDIA_STREAMER_NODE_POLICY_H__
+#define __MEDIA_STREAMER_NODE_POLICY_H__
+
+#include <media_streamer_priv.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+       POLICY_TYPE_NONE,
+       POLICY_TYPE_CAMERA,
+       POLICY_TYPE_MIC,
+} media_streamer_policy_type_e;
+
+int __ms_node_policy_init(media_streamer_node_s *node);
+int __ms_node_policy_deinit(media_streamer_node_s *node);
+int _ms_node_policy_check(media_streamer_node_s *node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MEDIA_STREAMER_NODE_POLICY_H__ */
index 14a45f7..bbfd37b 100755 (executable)
@@ -24,6 +24,7 @@ extern "C" {
 
 #include <gst/gst.h>
 #include <stdio.h>
+#include <restriction.h>
 
 #include <media_streamer.h>
 #include <media_streamer_util.h>
@@ -137,6 +138,8 @@ typedef struct {
        void *callbacks_structure;
 
        media_streamer_resource_manager_s resource_manager;
+       device_policy_manager_h dpm_handle;
+       int policy_changed_cb_id;
 } media_streamer_node_s;
 
 typedef struct _media_streamer_wl_info_s {
index 7443f3b..317b737 100644 (file)
@@ -31,6 +31,7 @@ BuildRequires:  pkgconfig(ecore-wayland)
 BuildRequires:  pkgconfig(appcore-efl)
 BuildRequires:  pkgconfig(murphy-resource)
 BuildRequires:  pkgconfig(murphy-glib)
+BuildRequires:  pkgconfig(dpm)
 
 %description
 A MediaStreamer library in Tizen Native API.
index a87724f..ced5323 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <media_streamer_node.h>
 #include <media_streamer_node_resources.h>
+#include <media_streamer_node_policy.h>
 #include <media_streamer_util.h>
 #include <media_streamer_gst.h>
 #include <cynara-client.h>
@@ -579,6 +580,12 @@ int __ms_src_node_create(media_streamer_node_s *node)
                return ret;
        }
 
+       ret = __ms_node_policy_init(node);
+       if (MEDIA_STREAMER_ERROR_NONE != ret) {
+               ms_error("Failed to init policy for node [%s]", node->name);
+               return ret;
+       }
+
        return ret;
 }
 
@@ -702,6 +709,10 @@ void __ms_node_destroy(media_streamer_node_s *node)
        /* Disconnects and clean all node signals */
        g_list_free_full(node->sig_list, __ms_signal_destroy);
 
+       /* Deinitialize policy manager */
+       if (MEDIA_STREAMER_ERROR_NONE != __ms_node_policy_deinit(node))
+               ms_error("Failed to deinitialize policy manager");
+
        /* Deinitialize resource manager */
        if (MEDIA_STREAMER_ERROR_NONE != __ms_node_resouces_deinit(node))
                ms_error("Failed to deinitialize resource manager");
@@ -1598,3 +1609,33 @@ gboolean _ms_node_resouces_release_iter(const GValue *item, GValue *ret, gpointe
 
        return TRUE;
 }
+
+gboolean _ms_node_policy_check_iter(const GValue *item, GValue *ret, gpointer user_data)
+{
+       media_streamer_s *ms_streamer = (media_streamer_s *) user_data;
+       media_streamer_node_s *node = NULL;
+       GstElement *element = NULL;
+       g_value_set_boolean(ret, FALSE);
+
+       element = GST_ELEMENT(g_value_get_object(item));
+       g_object_ref(element);
+
+       node = (media_streamer_node_s *) g_hash_table_lookup(ms_streamer->nodes_table,
+               GST_ELEMENT_NAME(element));
+       if (!node) {
+               /* If we fail to found corresonding node inside streamer
+                       then apprently this element doesn't require resources */
+               ms_info("Failed to found corresonding node [%s] inside streamer", GST_ELEMENT_NAME(element));
+               g_value_set_boolean(ret, TRUE);
+               return TRUE;
+       }
+
+       if (MEDIA_STREAMER_ERROR_NONE != _ms_node_policy_check(node)) {
+               ms_error("Failed to check policy for node [%s]", node->name);
+               return FALSE;
+       }
+
+       g_value_set_boolean(ret, TRUE);
+
+       return TRUE;
+}
diff --git a/src/media_streamer_node_policy.c b/src/media_streamer_node_policy.c
new file mode 100644 (file)
index 0000000..90628b9
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gst/gst.h>
+#include <restriction.h>
+
+#include <media_streamer_node_policy.h>
+#include <media_streamer.h>
+#include <media_streamer_priv.h>
+#include <media_streamer_node.h>
+
+#define DPM_ALLOWED 1
+#define DPM_DISALLOWED 0
+
+enum {
+       DPM_POLICY_FOR_CAMERA,
+       DPM_POLICY_FOR_MIC,
+       DPM_POLICY_MAX,
+};
+const char* policy_str[DPM_POLICY_MAX] = {
+       "camera",
+       "microphone",
+};
+
+static void __ms_node_get_dpm_check_needed(media_streamer_node_s *node,
+       media_streamer_policy_type_e *policy) {
+       int subtype = node->subtype;
+
+       ms_debug("Checking policy for node type %d, subtype %d", node->type, subtype);
+
+       /* Check for node types */
+       switch (subtype) {
+       case MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA:
+       case MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_CAPTURE:
+                       *policy = POLICY_TYPE_CAMERA;
+               break;
+       case MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_CAPTURE:
+                       *policy = POLICY_TYPE_MIC;
+               break;
+       default:
+               break;
+       }
+}
+
+static void __ms_node_policy_changed_cb(const char *name, const char *value, void *user_data)
+{
+       if (user_data == NULL)
+               return;
+
+       media_streamer_node_s *node = (media_streamer_node_s *) user_data;
+       media_streamer_s *streamer = (media_streamer_s *) node->parent_streamer;
+       ms_info("Received policy_changed_cb from node [%s]", node->name);
+
+       /* Here we perform action to release resources relases that
+          were previoursly acquired. Basically what we need to do is
+          to unprepare media streamer.*/
+       g_mutex_lock(&streamer->mutex_lock);
+       streamer->is_interrupted = TRUE;
+       if (MEDIA_STREAMER_ERROR_NONE !=
+               __ms_pipeline_unprepare(streamer)) {
+               ms_error("Failed to unprepare streamer");
+               streamer->is_interrupted = FALSE;
+               g_mutex_unlock(&streamer->mutex_lock);
+               return;
+       }
+       streamer->is_interrupted = FALSE;
+
+       /* Call interrupted_cb with appropriate code */
+       media_streamer_interrupted_cb interrupted_cb =
+               (media_streamer_interrupted_cb) streamer->interrupted_cb.callback;
+       if (interrupted_cb) {
+               interrupted_cb(MEDIA_STREAMER_INTERRUPTED_BY_SECURITY,
+                       streamer->interrupted_cb.user_data);
+       } else {
+               ms_info("Interuption will not be handled because interrupted_cb is NULL");
+       }
+       g_mutex_unlock(&streamer->mutex_lock);
+}
+
+int __ms_node_policy_init(media_streamer_node_s *node)
+{
+       media_streamer_policy_type_e policy = POLICY_TYPE_NONE;
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       const char *policy_name = NULL;
+
+       /* Check if node require policy manager */
+       __ms_node_get_dpm_check_needed(node, &policy);
+       if (POLICY_TYPE_NONE == policy) {
+               ms_info("No policy is needed for %p node type [%d] subtype [%d]",
+                       node, node->type, node->subtype);
+               return MEDIA_STREAMER_ERROR_NONE;
+       }
+
+       switch (policy) {
+       case POLICY_TYPE_CAMERA:
+               policy_name = policy_str[DPM_POLICY_FOR_CAMERA];
+               break;
+       case POLICY_TYPE_MIC:
+               policy_name = policy_str[DPM_POLICY_FOR_MIC];
+               break;
+       default:
+               break;
+       }
+       /* Initialize policy manager */
+       node->dpm_handle = dpm_manager_create();
+       if (node->dpm_handle) {
+               int dpm_ret = DPM_ERROR_NONE;
+               dpm_ret = dpm_add_policy_changed_cb(node->dpm_handle, policy_name,
+                               __ms_node_policy_changed_cb, (void *)node, &node->policy_changed_cb_id);
+
+               if (dpm_ret != DPM_ERROR_NONE) {
+                       ms_error("add DPM changed cb failed, keep going");
+                       node->policy_changed_cb_id = 0;
+               }
+               ms_debug("DPM initialized");
+       }
+
+       return ret;
+}
+
+int __ms_node_policy_deinit(media_streamer_node_s *node)
+{
+       media_streamer_policy_type_e policy = POLICY_TYPE_NONE;
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       /* Check if node require policy manager */
+       __ms_node_get_dpm_check_needed(node, &policy);
+       if (POLICY_TYPE_NONE == policy) {
+               ms_info("No policy is needed for %p node type [%d] subtype [%d]",
+                       node, node->type, node->subtype);
+               return MEDIA_STREAMER_ERROR_NONE;
+       }
+
+       if (node->dpm_handle) {
+               if (node->policy_changed_cb_id > 0) {
+                       dpm_remove_policy_changed_cb(node->dpm_handle, node->policy_changed_cb_id);
+               } else {
+                       ms_info("invalid dpm cb id");
+               }
+               ms_debug("DPM released");
+       }
+
+       dpm_manager_destroy(node->dpm_handle);
+       node->dpm_handle = NULL;
+
+       return ret;
+}
+
+int _ms_node_policy_check(media_streamer_node_s *node)
+{
+       media_streamer_policy_type_e policy = POLICY_TYPE_NONE;
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+       int dpm_state = DPM_ALLOWED;
+       int dpm_ret = DPM_ERROR_NONE;
+
+       /* Check if node require policy manager */
+       __ms_node_get_dpm_check_needed(node, &policy);
+       if (POLICY_TYPE_NONE == policy) {
+               ms_info("No policy is needed for %p node type [%d] subtype [%d]",
+                       node, node->type, node->subtype);
+               return MEDIA_STREAMER_ERROR_NONE;
+       }
+
+       if (node->dpm_handle == NULL) {
+               ms_error("DPM manager handle is NULL");
+               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+       }
+
+       switch (policy) {
+       case POLICY_TYPE_CAMERA:
+               dpm_ret = dpm_restriction_get_camera_state(node->dpm_handle, &dpm_state);
+               break;
+       case POLICY_TYPE_MIC:
+               dpm_ret = dpm_restriction_get_microphone_state(node->dpm_handle, &dpm_state);
+               break;
+       default:
+               break;
+       }
+
+       if (dpm_ret == DPM_ERROR_NONE) {
+                       ms_info("DPM state - %d", dpm_state);
+                       if (dpm_state == DPM_DISALLOWED) {
+                               ms_error("Policy disallowed by DPM");
+                               return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+                       }
+       } else {
+               ms_info("get DPM state failed, continue too work");
+       }
+
+       return ret;
+}
index 5dabe15..3c1545a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index 3fe8485..a6b995d 100644 (file)
@@ -23,6 +23,7 @@
 #define GST_TIME_TO_MSEC(t) (t == GST_CLOCK_TIME_NONE ? t : (int)(((GstClockTime)(t)) / GST_MSECOND))
 
 int __ms_change_resources_state(media_streamer_s *ms_streamer, media_streamer_state_e state);
+int __ms_change_policy_state(media_streamer_s *ms_streamer, media_streamer_state_e state);
 static gboolean media_streamer_resource_relese_cb(media_streamer_resource_manager_s *resource_manager, void *user_data);
 
 int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e state)
@@ -33,6 +34,11 @@ int __ms_state_change(media_streamer_s *ms_streamer, media_streamer_state_e stat
        ms_retvm_if(ms_streamer->state == state, MEDIA_STREAMER_ERROR_NONE, "Media streamer already in this state");
 
        if (!ms_streamer->is_interrupted) {
+               ret = __ms_change_policy_state(ms_streamer, state);
+               if (MEDIA_STREAMER_ERROR_NONE != ret) {
+                       ms_error("Failed to change policy state for streamer %p", ms_streamer);
+                       return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
+               }
                ret = __ms_change_resources_state(ms_streamer, state);
                if (MEDIA_STREAMER_ERROR_NONE != ret) {
                        ms_error("Failed to change resources state for streamer %p", ms_streamer);
@@ -338,3 +344,44 @@ static gboolean media_streamer_resource_relese_cb(
 
        return TRUE;
 }
+
+int __ms_check_policy(media_streamer_s *ms_streamer)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       /* Acquire resources for src bin */
+       ret = __ms_bin_foreach_elements(GST_BIN(ms_streamer->src_bin),
+               _ms_node_policy_check_iter, ms_streamer);
+       if (MEDIA_STREAMER_ERROR_NONE != ret) {
+               ms_error("Failed to check policies for src bin");
+               return ret;
+       }
+
+       return MEDIA_STREAMER_ERROR_NONE;
+}
+
+int __ms_change_policy_state(media_streamer_s *ms_streamer, media_streamer_state_e state)
+{
+       int ret = MEDIA_STREAMER_ERROR_NONE;
+
+       /* According to state graph we need to handle only this state
+        * and different transotions into them */
+       if (state == MEDIA_STREAMER_STATE_READY) {
+               switch (ms_streamer->pend_state) {
+               case MEDIA_STREAMER_STATE_IDLE:
+                       /* After prepare function */
+                       ret = __ms_check_policy(ms_streamer);
+                       break;
+               case MEDIA_STREAMER_STATE_PAUSED:
+               case MEDIA_STREAMER_STATE_PLAYING:
+               case MEDIA_STREAMER_STATE_NONE:
+               case MEDIA_STREAMER_STATE_SEEKING:
+               default:
+                       break;
+               }
+       } else {
+               ms_debug("Ignoring state for policy managements");
+       }
+
+       return ret;
+}