Revise DPM policy checking codes
[platform/core/api/mediastreamer.git] / src / media_streamer_node_policy.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <gst/gst.h>
18 #include <restriction.h>
19 #include "media_streamer.h"
20 #include "media_streamer_gst.h"
21 #include "media_streamer_priv.h"
22 #include "media_streamer_node.h"
23 #include "media_streamer_node_policy.h"
24
25 #define DPM_ALLOWED 1
26 #define DPM_DISALLOWED 0
27
28 enum {
29         DPM_POLICY_FOR_CAMERA,
30         DPM_POLICY_FOR_MIC,
31         DPM_POLICY_MAX,
32 };
33
34 static void __ms_node_get_dpm_check_needed(media_streamer_node_s *node, media_streamer_policy_type_e *policy)
35 {
36         int subtype;
37
38         ms_debug_fenter();
39
40         ms_retm_if(node == NULL, "node is NULL");
41         ms_retm_if(policy == NULL, "policy is NULL");
42
43         subtype = node->subtype;
44
45         ms_debug("Checking DPM policy for node type %d, subtype %d", node->type, subtype);
46
47         /* Check for node types */
48         switch (subtype) {
49         case MEDIA_STREAMER_NODE_SRC_TYPE_CAMERA:
50         case MEDIA_STREAMER_NODE_SRC_TYPE_VIDEO_CAPTURE:
51                 *policy = POLICY_TYPE_CAMERA;
52                 break;
53         case MEDIA_STREAMER_NODE_SRC_TYPE_AUDIO_CAPTURE:
54                 *policy = POLICY_TYPE_MIC;
55                 break;
56         default:
57                 *policy = POLICY_TYPE_NONE;
58                 break;
59         }
60
61         ms_debug_fleave();
62
63 }
64
65 //LCOV_EXCL_START
66 static void __ms_node_policy_changed_cb(const char *name, const char *value, void *user_data)
67 {
68         media_streamer_node_s *node;
69         media_streamer_s *streamer;
70
71         ms_debug_fenter();
72
73         ms_retm_if(user_data == NULL, "user_data is NULL");
74
75         node = (media_streamer_node_s *) user_data;
76         streamer = (media_streamer_s *) node->parent_streamer;
77         ms_info("Received policy_changed_cb from node [%s]", node->name);
78
79         /* Here we perform action to release resources that
80            were previously acquired. Basically, what we need to do is
81            to unprepare media streamer.*/
82         g_mutex_lock(&streamer->mutex_lock);
83         streamer->is_interrupted = TRUE;
84         if (MEDIA_STREAMER_ERROR_NONE !=
85                 ms_pipeline_unprepare(streamer)) {
86                 ms_error("Failed to unprepare streamer");
87                 streamer->is_interrupted = FALSE;
88                 g_mutex_unlock(&streamer->mutex_lock);
89                 return;
90         }
91         streamer->is_interrupted = FALSE;
92
93         /* Call interrupted_cb with appropriate code */
94         media_streamer_interrupted_cb interrupted_cb =
95                 (media_streamer_interrupted_cb) streamer->interrupted_cb.callback;
96         if (interrupted_cb) {
97                 interrupted_cb(MEDIA_STREAMER_INTERRUPTED_BY_SECURITY,
98                         streamer->interrupted_cb.user_data);
99         } else {
100                 ms_info("Interruption will not be handled because interrupted_cb is NULL");
101         }
102         g_mutex_unlock(&streamer->mutex_lock);
103
104         ms_debug_fleave();
105
106 }
107 //LCOV_EXCL_STOP
108
109 int ms_node_policy_init(media_streamer_node_s *node)
110 {
111         media_streamer_policy_type_e policy = POLICY_TYPE_NONE;
112         int ret = MEDIA_STREAMER_ERROR_NONE;
113         const char *policy_name = NULL;
114         static const char* policy_str[DPM_POLICY_MAX] = {"camera", "microphone"};
115
116         ms_debug_fenter();
117
118         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
119
120         /* Check if node require policy manager */
121         __ms_node_get_dpm_check_needed(node, &policy);
122         if (POLICY_TYPE_NONE == policy) {
123                 ms_info("No policy is needed for %p node type [%d] subtype [%d]",
124                         node, node->type, node->subtype);
125                 return MEDIA_STREAMER_ERROR_NONE;
126         }
127
128         switch (policy) {
129         case POLICY_TYPE_CAMERA:
130                 policy_name = policy_str[DPM_POLICY_FOR_CAMERA];
131                 break;
132         case POLICY_TYPE_MIC:
133                 policy_name = policy_str[DPM_POLICY_FOR_MIC];
134                 break;
135         default:
136                 break;
137         }
138         /* Initialize policy manager */
139         node->dpm_handle = dpm_manager_create();
140         if (node->dpm_handle) {
141                 int dpm_ret = DPM_ERROR_NONE;
142                 dpm_ret = dpm_add_policy_changed_cb(node->dpm_handle, policy_name,
143                                 __ms_node_policy_changed_cb, (void *)node, &node->policy_changed_cb_id);
144
145                 if (dpm_ret != DPM_ERROR_NONE) {
146                         ms_error("add DPM changed cb failed, keep going");
147                         node->policy_changed_cb_id = 0;
148                 }
149                 ms_debug("DPM initialized");
150         }
151
152         ms_debug_fleave();
153
154         return ret;
155 }
156
157 int ms_node_policy_deinit(media_streamer_node_s *node)
158 {
159         media_streamer_policy_type_e policy = POLICY_TYPE_NONE;
160         int ret = MEDIA_STREAMER_ERROR_NONE;
161
162         ms_debug_fenter();
163
164         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
165
166         __ms_node_get_dpm_check_needed(node, &policy);
167         if (POLICY_TYPE_NONE == policy) {
168                 ms_info("No need to check DPM restriction state for node [%p] type [%d] subtype [%d]",
169                         node, node->type, node->subtype);
170                 return MEDIA_STREAMER_ERROR_NONE;
171         }
172
173         ms_retvm_if(node->dpm_handle == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "DPM handle is NULL");
174
175         if (node->policy_changed_cb_id > 0)
176                 dpm_remove_policy_changed_cb(node->dpm_handle, node->policy_changed_cb_id);
177         else
178                 ms_info("invalid dpm cb id");
179
180         ms_debug("DPM released");
181
182         dpm_manager_destroy(node->dpm_handle);
183         node->dpm_handle = NULL;
184
185         ms_debug_fleave();
186
187         return ret;
188 }
189
190 int ms_node_policy_check(media_streamer_node_s *node, gboolean *allowed)
191 {
192         media_streamer_policy_type_e policy = POLICY_TYPE_NONE;
193         int dpm_state = DPM_ALLOWED;
194         int dpm_ret = DPM_ERROR_NONE;
195
196         ms_debug_fenter();
197
198         ms_retvm_if(node == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "node is NULL");
199         ms_retvm_if(allowed == NULL, MEDIA_STREAMER_ERROR_INVALID_PARAMETER, "allowed is NULL");
200
201         *allowed = TRUE;
202
203         __ms_node_get_dpm_check_needed(node, &policy);
204         if (POLICY_TYPE_NONE == policy) {
205                 ms_info("No need to check DPM restriction state for node [%p] type [%d] subtype [%d]",
206                         node, node->type, node->subtype);
207                 return MEDIA_STREAMER_ERROR_NONE;
208         }
209
210         ms_retvm_if(node->dpm_handle == NULL, MEDIA_STREAMER_ERROR_INVALID_OPERATION, "DPM handle is NULL");
211
212         switch (policy) {
213         case POLICY_TYPE_CAMERA:
214                 dpm_ret = dpm_restriction_get_camera_state(node->dpm_handle, &dpm_state);
215                 break;
216         case POLICY_TYPE_MIC:
217                 dpm_ret = dpm_restriction_get_microphone_state(node->dpm_handle, &dpm_state);
218                 break;
219         default:
220                 break;
221         }
222
223         if (dpm_ret != DPM_ERROR_NONE) {
224                 ms_error("Failed to get DPM restriction state");
225                 return MEDIA_STREAMER_ERROR_INVALID_OPERATION;
226         }
227
228         ms_info("DPM state - %d", dpm_state);
229         if (dpm_state == DPM_DISALLOWED) {
230                 ms_error("Policy disallowed by DPM");
231                 *allowed = FALSE;
232         }
233
234         ms_debug_fleave();
235
236         return MEDIA_STREAMER_ERROR_NONE;
237 }