From a43b64eeb002a25315a519835466a4d80a18f363 Mon Sep 17 00:00:00 2001 From: Jaeyun Date: Thu, 10 Oct 2019 16:23:46 +0900 Subject: [PATCH] [Api/Tizen] handle dpm restriction case Check the pipeline with device policy restricted case. Create dpm handle and when trying to start the pipeline, check device policy and handle error case. Signed-off-by: Jaeyun Jung --- api/capi/meson.build | 1 + api/capi/src/nnstreamer-capi-pipeline.c | 1 + api/capi/src/nnstreamer-capi-tizen.c | 118 ++++++++++++++++++++++++++++++-- packaging/nnstreamer.spec | 1 + 4 files changed, 115 insertions(+), 6 deletions(-) diff --git a/api/capi/meson.build b/api/capi/meson.build index 1adf3cc..a09386f 100644 --- a/api/capi/meson.build +++ b/api/capi/meson.build @@ -48,6 +48,7 @@ if (get_option('enable-tizen')) message('CAPI is in Tizen mode') tizen_deps = [ + dependency('dpm'), dependency('mm-resource-manager'), dependency('mm-camcorder'), dependency('capi-privacy-privilege-manager'), diff --git a/api/capi/src/nnstreamer-capi-pipeline.c b/api/capi/src/nnstreamer-capi-pipeline.c index 12251b3..3a260a7 100644 --- a/api/capi/src/nnstreamer-capi-pipeline.c +++ b/api/capi/src/nnstreamer-capi-pipeline.c @@ -634,6 +634,7 @@ ml_pipeline_destroy (ml_pipeline_h pipe) } gst_object_unref (p->element); + p->element = NULL; } /* Destroy registered callback handles and resources */ diff --git a/api/capi/src/nnstreamer-capi-tizen.c b/api/capi/src/nnstreamer-capi-tizen.c index 542ab8c..6ab6d14 100644 --- a/api/capi/src/nnstreamer-capi-tizen.c +++ b/api/capi/src/nnstreamer-capi-tizen.c @@ -28,6 +28,7 @@ #include #include +#include /* device policy manager */ #include #include #include @@ -109,6 +110,10 @@ typedef struct { gboolean invalid; /**< flag to indicate rm handle is valid */ mm_resource_manager_h rm_h; /**< rm handle */ + device_policy_manager_h dpm_h; /**< dpm handle */ + int dpm_cb_id; /**< dpm callback id */ + gboolean has_video_src; /**< pipeline includes video src */ + gboolean has_audio_src; /**< pipeline includes audio src */ GHashTable *res_handles; /**< hash table of resource handles */ } tizen_mm_handle_s; @@ -260,6 +265,60 @@ ml_tizen_check_privilege (const gchar * privilege) } /** + * @brief Function to check device policy. + */ +static int +ml_tizen_check_dpm_restriction (device_policy_manager_h dpm_handle, int type) +{ + int err = DPM_ERROR_NOT_PERMITTED; + int dpm_is_allowed = 0; + + switch (type) { + case 1: /* camera */ + err = dpm_restriction_get_camera_state (dpm_handle, &dpm_is_allowed); + break; + case 2: /* mic */ + err = dpm_restriction_get_microphone_state (dpm_handle, &dpm_is_allowed); + break; + default: + /* unknown type */ + break; + } + + if (err != DPM_ERROR_NONE || dpm_is_allowed != 1) { + ml_loge ("Failed, device policy is not allowed."); + return ML_ERROR_PERMISSION_DENIED; + } + + return ML_ERROR_NONE; +} + +/** + * @brief Callback to be called when device policy is changed. + */ +static void +ml_tizen_dpm_policy_changed_cb (const char *name, const char *state, void *user_data) +{ + ml_pipeline *p; + + g_return_if_fail (state); + g_return_if_fail (user_data); + + p = (ml_pipeline *) user_data; + + if (g_ascii_strcasecmp (state, "disallowed") == 0) { + g_mutex_lock (&p->lock); + + /* pause the pipeline */ + gst_element_set_state (p->element, GST_STATE_PAUSED); + + g_mutex_unlock (&p->lock); + } + + return; +} + +/** * @brief Function to get key string of resource type to handle hash table. */ static gchar * @@ -465,6 +524,16 @@ ml_tizen_mm_res_release (gpointer handle, gboolean destroy) mm_handle->invalid = FALSE; if (destroy) { + if (mm_handle->dpm_h) { + if (mm_handle->dpm_cb_id > 0) { + dpm_remove_policy_changed_cb (mm_handle->dpm_h, mm_handle->dpm_cb_id); + mm_handle->dpm_cb_id = 0; + } + + dpm_manager_destroy (mm_handle->dpm_h); + mm_handle->dpm_h = NULL; + } + g_hash_table_remove_all (mm_handle->res_handles); g_free (mm_handle); } @@ -474,11 +543,11 @@ ml_tizen_mm_res_release (gpointer handle, gboolean destroy) * @brief Function to initialize mm resource manager. */ static int -ml_tizen_mm_res_initialize (ml_pipeline_h pipe) +ml_tizen_mm_res_initialize (ml_pipeline_h pipe, gboolean has_video_src, gboolean has_audio_src) { ml_pipeline *p; pipeline_resource_s *res; - tizen_mm_handle_s *mm_handle; + tizen_mm_handle_s *mm_handle = NULL; int status = ML_ERROR_STREAMS_PIPE; p = (ml_pipeline *) pipe; @@ -488,8 +557,10 @@ ml_tizen_mm_res_initialize (ml_pipeline_h pipe) /* register new resource handle of tizen mmfw */ if (!res) { res = g_new0 (pipeline_resource_s, 1); - if (!res) + if (!res) { + ml_loge ("Failed to allocate pipeline resource handle."); goto rm_error; + } res->type = g_strdup (TIZEN_RES_MM); g_hash_table_insert (p->resources, g_strdup (TIZEN_RES_MM), res); @@ -498,19 +569,38 @@ ml_tizen_mm_res_initialize (ml_pipeline_h pipe) mm_handle = (tizen_mm_handle_s *) res->handle; if (!mm_handle) { mm_handle = g_new0 (tizen_mm_handle_s, 1); - if (!mm_handle) + if (!mm_handle) { + ml_loge ("Failed to allocate media resource handle."); goto rm_error; + } mm_handle->res_handles = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + /* device policy manager */ + mm_handle->dpm_h = dpm_manager_create (); + if (dpm_add_policy_changed_cb (mm_handle->dpm_h, "camera", + ml_tizen_dpm_policy_changed_cb, pipe, &mm_handle->dpm_cb_id) != DPM_ERROR_NONE) { + ml_loge ("Failed to add device policy callback."); + status = ML_ERROR_PERMISSION_DENIED; + goto rm_error; + } + /* set mm handle */ res->handle = mm_handle; } + mm_handle->has_video_src = has_video_src; + mm_handle->has_audio_src = has_audio_src; status = ML_ERROR_NONE; rm_error: + if (status != ML_ERROR_NONE) { + /* failed to initialize mm handle */ + if (mm_handle) + ml_tizen_mm_res_release (mm_handle, TRUE); + } + return status; } @@ -538,6 +628,17 @@ ml_tizen_mm_res_acquire (ml_pipeline_h pipe, if (!mm_handle) goto rm_error; + /* check dpm state */ + if (mm_handle->has_video_src && + (status = ml_tizen_check_dpm_restriction (mm_handle->dpm_h, 1)) != ML_ERROR_NONE) { + goto rm_error; + } + + if (mm_handle->has_audio_src && + (status = ml_tizen_check_dpm_restriction (mm_handle->dpm_h, 2)) != ML_ERROR_NONE) { + goto rm_error; + } + /* check invalid handle */ if (mm_handle->invalid) ml_tizen_mm_res_release (mm_handle, FALSE); @@ -675,7 +776,12 @@ ml_tizen_mm_convert_element (ml_pipeline_h pipe, gchar ** result, gboolean is_in } /* create camcoder handle (primary camera) */ - cam_info.videodev_type = MM_VIDEO_DEVICE_CAMERA0; + if (video_src) { + cam_info.videodev_type = MM_VIDEO_DEVICE_CAMERA0; + } else { + /* no camera */ + cam_info.videodev_type = MM_VIDEO_DEVICE_NONE; + } if ((err = mm_camcorder_create (&hcam, &cam_info)) != MM_ERROR_NONE) { ml_loge ("Fail to call mm_camcorder_create = %x\n", err); @@ -706,7 +812,7 @@ ml_tizen_mm_convert_element (ml_pipeline_h pipe, gchar ** result, gboolean is_in } /* initialize rm handle */ - status = ml_tizen_mm_res_initialize (pipe); + status = ml_tizen_mm_res_initialize (pipe, (video_src != NULL), (audio_src != NULL)); if (status != ML_ERROR_NONE) goto mm_error; diff --git a/packaging/nnstreamer.spec b/packaging/nnstreamer.spec index d7f77b0..53cb32f 100644 --- a/packaging/nnstreamer.spec +++ b/packaging/nnstreamer.spec @@ -68,6 +68,7 @@ BuildRequires: lcov %define enable_nnfw_runtime -Denable-nnfw-runtime=false %define enable_nnfw_r 0 %if %{with tizen} +BuildRequires: pkgconfig(dpm) BuildRequires: pkgconfig(mm-resource-manager) BuildRequires: pkgconfig(mm-camcorder) BuildRequires: pkgconfig(capi-privacy-privilege-manager) -- 2.7.4