[Release version 0.10.63] Fix murphy connection error - wait for connection before...
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_resource.c
1 /*
2  * libmm-camcorder
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include "mm_camcorder_internal.h"
21 #include "mm_camcorder_resource.h"
22 #include <murphy/common/glib-glue.h>
23
24 #define MRP_APP_CLASS_FOR_CAMCORDER   "media"
25 #define MRP_RESOURCE_TYPE_MANDATORY TRUE
26 #define MRP_RESOURCE_TYPE_EXCLUSIVE FALSE
27
28 const char* mm_camcorder_resource_str[MM_CAMCORDER_RESOURCE_MAX] = {
29     "camera",
30     "video_overlay"
31 };
32
33 #define MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(x_camcorder_resource_manager) \
34 do { \
35         if (!x_camcorder_resource_manager) { \
36                 _mmcam_dbg_err("no resource manager instance"); \
37                 return MM_ERROR_INVALID_ARGUMENT; \
38         } \
39 } while(0);
40
41 #define MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(x_camcorder_resource_manager) \
42 do { \
43         if (!x_camcorder_resource_manager) { \
44                 _mmcam_dbg_err("no resource manager instance"); \
45                 return MM_ERROR_INVALID_ARGUMENT; \
46         } else { \
47                 if (!x_camcorder_resource_manager->is_connected) { \
48                         _mmcam_dbg_err("not connected to resource server yet"); \
49                         return MM_ERROR_RESOURCE_NOT_INITIALIZED; \
50                 } \
51         } \
52 } while(0);
53
54 static char *__mmcamcorder_resource_state_to_str(mrp_res_resource_state_t st)
55 {
56         char *state = "unknown";
57         switch (st) {
58         case MRP_RES_RESOURCE_ACQUIRED:
59                 state = "acquired";
60                 break;
61         case MRP_RES_RESOURCE_LOST:
62                 state = "lost";
63                 break;
64         case MRP_RES_RESOURCE_AVAILABLE:
65                 state = "available";
66                 break;
67         case MRP_RES_RESOURCE_PENDING:
68                 state = "pending";
69                 break;
70         case MRP_RES_RESOURCE_ABOUT_TO_LOOSE:
71                 state = "about to loose";
72                 break;
73         }
74         return state;
75 }
76
77 static void __mmcamcorder_resource_state_callback(mrp_res_context_t *context, mrp_res_error_t err, void *user_data)
78 {
79         int i = 0;
80         const mrp_res_resource_set_t *rset;
81         mrp_res_resource_t *resource;
82         mmf_camcorder_t* camcorder = NULL;
83
84         if (err != MRP_RES_ERROR_NONE) {
85                 _mmcam_dbg_err(" - error message received from Murphy, err(0x%x)", err);
86                 return;
87         }
88
89         camcorder = (mmf_camcorder_t*)user_data;
90
91         mmf_return_if_fail((MMHandleType)camcorder);
92
93         _mmcam_dbg_log("enter");
94
95         _MMCAMCORDER_LOCK_RESOURCE(camcorder);
96
97         switch (context->state) {
98         case MRP_RES_CONNECTED:
99                 _mmcam_dbg_log(" - connected to Murphy");
100                 if ((rset = mrp_res_list_resources(context)) != NULL) {
101                         mrp_res_string_array_t *resource_names;
102                         resource_names = mrp_res_list_resource_names(rset);
103                         if (!resource_names) {
104                                 _mmcam_dbg_err(" - no resources available");
105                                 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
106                                 return;
107                         }
108                         for (i = 0; i < resource_names->num_strings; i++) {
109                                 resource = mrp_res_get_resource_by_name(rset, resource_names->strings[i]);
110                                 if (resource) {
111                                         _mmcam_dbg_log(" - available resource: %s", resource->name);
112                                 }
113                         }
114                         mrp_res_free_string_array(resource_names);
115                 }
116                 camcorder->resource_manager.is_connected = TRUE;
117                 _MMCAMCORDER_RESOURCE_SIGNAL(camcorder);
118                 break;
119         case MRP_RES_DISCONNECTED:
120                 _mmcam_dbg_log(" - disconnected from Murphy");
121                 if (camcorder->resource_manager.rset) {
122                         mrp_res_delete_resource_set(camcorder->resource_manager.rset);
123                         camcorder->resource_manager.rset = NULL;
124                 }
125                 if (camcorder->resource_manager.context) {
126                         mrp_res_destroy(camcorder->resource_manager.context);
127                         camcorder->resource_manager.context = NULL;
128                         camcorder->resource_manager.is_connected = FALSE;
129                 }
130                 break;
131         }
132
133         _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
134
135         _mmcam_dbg_log("leave");
136
137         return;
138 }
139
140
141 static void __mmcamcorder_resource_set_state_callback(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data)
142 {
143         int i = 0;
144         mmf_camcorder_t *camcorder = (mmf_camcorder_t *)user_data;
145         mrp_res_resource_t *res;
146
147         mmf_return_if_fail((MMHandleType)camcorder);
148
149         _MMCAMCORDER_LOCK_RESOURCE(camcorder);
150
151         if (!mrp_res_equal_resource_set(rs, camcorder->resource_manager.rset)) {
152                 _mmcam_dbg_warn("- resource set(%p) is not same as this camcorder handle's(%p)", rs, camcorder->resource_manager.rset);
153                 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
154                 return;
155         }
156
157         _mmcam_dbg_log(" - resource set state of camcorder(%p) is changed to [%s]",
158                 camcorder, __mmcamcorder_resource_state_to_str(rs->state));
159
160         for (i = 0; i < MM_CAMCORDER_RESOURCE_MAX; i++) {
161                 res = mrp_res_get_resource_by_name(rs, mm_camcorder_resource_str[i]);
162                 if (res == NULL) {
163                         _mmcam_dbg_warn(" -- %s not present in resource set", mm_camcorder_resource_str[i]);
164                 } else {
165                         _mmcam_dbg_log(" -- resource name [%s] -> [%s]",
166                                 res->name, __mmcamcorder_resource_state_to_str(res->state));
167
168                         if (res->state == MRP_RES_RESOURCE_ACQUIRED) {
169                                 camcorder->resource_manager.acquire_count--;
170
171                                 if (camcorder->resource_manager.acquire_count <= 0) {
172                                         _mmcam_dbg_log("send signal - resource acquire done");
173                                         _MMCAMCORDER_RESOURCE_SIGNAL(camcorder);
174                                 } else {
175                                         _mmcam_dbg_warn("remained acquire count %d",
176                                                 camcorder->resource_manager.acquire_count);
177                                 }
178                         }
179                 }
180         }
181
182         mrp_res_delete_resource_set(camcorder->resource_manager.rset);
183         camcorder->resource_manager.rset = mrp_res_copy_resource_set(rs);
184
185         _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
186
187         return;
188 }
189
190
191 static void __mmcamcorder_resource_release_cb(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data)
192 {
193         int i = 0;
194         int current_state = MM_CAMCORDER_STATE_NONE;
195         mmf_camcorder_t* camcorder = (mmf_camcorder_t*)user_data;
196         mrp_res_resource_t *res;
197
198         mmf_return_if_fail((MMHandleType)camcorder);
199
200         current_state = _mmcamcorder_get_state((MMHandleType)camcorder);
201         if (current_state <= MM_CAMCORDER_STATE_NONE ||
202             current_state >= MM_CAMCORDER_STATE_NUM) {
203                 _mmcam_dbg_err("Abnormal state. Or null handle. (%p, %d)", camcorder, current_state);
204                 return;
205         }
206
207         /* set value to inform a status is changed by resource manaer */
208         camcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_BY_RM;
209
210         _MMCAMCORDER_LOCK_ASM(camcorder);
211
212         if (!mrp_res_equal_resource_set(rs, camcorder->resource_manager.rset)) {
213                 _MMCAMCORDER_UNLOCK_ASM(camcorder);
214                 _mmcam_dbg_warn("- resource set(%p) is not same as this camcorder handle's(%p)", rs, camcorder->resource_manager.rset);
215                 return;
216         }
217
218         _mmcam_dbg_log(" - resource set state of camcorder(%p) is changed to [%s]",
219                 camcorder, __mmcamcorder_resource_state_to_str(rs->state));
220
221         for (i = 0; i < MM_CAMCORDER_RESOURCE_MAX; i++) {
222                 res = mrp_res_get_resource_by_name(rs, mm_camcorder_resource_str[i]);
223                 if (res == NULL) {
224                         _mmcam_dbg_warn(" -- %s not present in resource set", mm_camcorder_resource_str[i]);
225                 } else {
226                         _mmcam_dbg_log(" -- resource name [%s] -> [%s]",
227                                 res->name, __mmcamcorder_resource_state_to_str(res->state));
228                 }
229         }
230
231         /* Stop the camera */
232         __mmcamcorder_force_stop(camcorder);
233
234         /* restore value */
235         camcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_NORMAL;
236
237         _MMCAMCORDER_UNLOCK_ASM(camcorder);
238
239         return;
240 }
241
242 static int __mmcamcorder_resource_create_resource_set(MMCamcorderResourceManager *resource_manager)
243 {
244         if (resource_manager->rset) {
245                 _mmcam_dbg_err(" - resource set was already created");
246                 return MM_ERROR_RESOURCE_INVALID_STATE;
247         }
248
249         resource_manager->rset = mrp_res_create_resource_set(resource_manager->context,
250                 MRP_APP_CLASS_FOR_CAMCORDER, __mmcamcorder_resource_set_state_callback, (void*)resource_manager->user_data);
251
252         if (resource_manager->rset == NULL) {
253                 _mmcam_dbg_err(" - could not create resource set");
254                 return MM_ERROR_RESOURCE_INTERNAL;
255         }
256
257         if (!mrp_res_set_autorelease(TRUE, resource_manager->rset)) {
258                 _mmcam_dbg_warn(" - could not set autorelease flag!");
259         }
260
261         return MM_ERROR_NONE;
262 }
263
264 static int __mmcamcorder_resource_include_resource(MMCamcorderResourceManager *resource_manager, const char *resource_name)
265 {
266         mrp_res_resource_t *resource = NULL;
267         resource = mrp_res_create_resource(resource_manager->rset,
268                                 resource_name,
269                                 MRP_RESOURCE_TYPE_MANDATORY,
270                                 MRP_RESOURCE_TYPE_EXCLUSIVE);
271         if (resource == NULL) {
272                 _mmcam_dbg_err(" - could not include resource[%s]", resource_name);
273                 return MM_ERROR_RESOURCE_INTERNAL;
274         }
275
276         resource_manager->acquire_count++;
277
278         _mmcam_dbg_log(" - count[%d] include resource[%s]",
279                 resource_manager->acquire_count, resource_name);
280
281         return MM_ERROR_NONE;
282 }
283
284 static int __mmcamcorder_resource_set_release_cb(MMCamcorderResourceManager *resource_manager)
285 {
286         int ret = MM_ERROR_NONE;
287         bool mrp_ret = FALSE;
288
289         if (resource_manager->rset) {
290                 mrp_ret = mrp_res_set_release_callback(resource_manager->rset, __mmcamcorder_resource_release_cb, resource_manager->user_data);
291                 if (!mrp_ret) {
292                         _mmcam_dbg_err(" - could not set release callback");
293                         ret = MM_ERROR_RESOURCE_INTERNAL;
294                 }
295         } else {
296                 _mmcam_dbg_err(" - resource set is null");
297                 ret = MM_ERROR_RESOURCE_INVALID_STATE;
298         }
299
300         return ret;
301 }
302
303 int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_manager, void *user_data)
304 {
305         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
306
307         resource_manager->mloop = mrp_mainloop_glib_get(g_main_loop_new(NULL, TRUE));
308         if (resource_manager->mloop) {
309                 resource_manager->context = mrp_res_create(resource_manager->mloop, __mmcamcorder_resource_state_callback, user_data);
310                 if (resource_manager->context == NULL) {
311                         _mmcam_dbg_err(" - could not get context for resource manager");
312                         mrp_mainloop_destroy(resource_manager->mloop);
313                         resource_manager->mloop = NULL;
314                         return MM_ERROR_RESOURCE_INTERNAL;
315                 }
316                 resource_manager->user_data = user_data;
317         } else {
318                 _mmcam_dbg_err("- could not get mainloop for resource manager");
319                 return MM_ERROR_RESOURCE_INTERNAL;
320         }
321
322         return MM_ERROR_NONE;
323 }
324
325 int _mmcamcorder_resource_manager_prepare(MMCamcorderResourceManager *resource_manager, MMCamcorderResourceType resource_type)
326 {
327         int ret = MM_ERROR_NONE;
328         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
329         MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
330
331         if (!resource_manager->rset) {
332                 ret = __mmcamcorder_resource_create_resource_set(resource_manager);
333         }
334         if (ret == MM_ERROR_NONE) {
335                 ret = __mmcamcorder_resource_include_resource(resource_manager, mm_camcorder_resource_str[resource_type]);
336         } else {
337                 _mmcam_dbg_err("failed to create resource set 0x%x", ret);
338         }
339
340         return ret;
341 }
342
343 int _mmcamcorder_resource_manager_acquire(MMCamcorderResourceManager *resource_manager)
344 {
345         int ret = MM_ERROR_NONE;
346         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
347         MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
348
349         if (resource_manager->rset == NULL) {
350                 _mmcam_dbg_err("- could not acquire resource, resource set is null");
351                 ret = MM_ERROR_RESOURCE_INVALID_STATE;
352         } else {
353                 ret = __mmcamcorder_resource_set_release_cb(resource_manager);
354                 if (ret) {
355                         _mmcam_dbg_err("- could not set resource release cb, ret(%d)", ret);
356                         ret = MM_ERROR_RESOURCE_INTERNAL;
357                 } else {
358                         ret = mrp_res_acquire_resource_set(resource_manager->rset);
359                         if (ret) {
360                                 _mmcam_dbg_err("- could not acquire resource, ret(%d)", ret);
361                                 ret = MM_ERROR_RESOURCE_INTERNAL;
362                         }
363                 }
364         }
365
366         return ret;
367 }
368
369 int _mmcamcorder_resource_manager_release(MMCamcorderResourceManager *resource_manager)
370 {
371         int ret = MM_ERROR_NONE;
372         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
373         MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
374
375         if (resource_manager->rset == NULL) {
376                 _mmcam_dbg_err("- could not release resource, resource set is null");
377                 ret = MM_ERROR_RESOURCE_INVALID_STATE;
378         } else {
379                 if (resource_manager->rset->state != MRP_RES_RESOURCE_ACQUIRED) {
380                         _mmcam_dbg_err("- could not release resource, resource set state is [%s]",
381                                 __mmcamcorder_resource_state_to_str(resource_manager->rset->state));
382                         ret = MM_ERROR_RESOURCE_INVALID_STATE;
383                 } else {
384                         ret = mrp_res_release_resource_set(resource_manager->rset);
385                         if (ret) {
386                                 _mmcam_dbg_err("- could not release resource, ret(%d)", ret);
387                                 ret = MM_ERROR_RESOURCE_INTERNAL;
388                         } else {
389                                 _mmcam_dbg_log("resource release done");
390                         }
391                 }
392         }
393
394         return ret;
395 }
396
397 int _mmcamcorder_resource_manager_unprepare(MMCamcorderResourceManager *resource_manager)
398 {
399         int ret = MM_ERROR_NONE;
400         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
401         MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
402
403         if (resource_manager->rset == NULL) {
404                 _mmcam_dbg_err("- could not unprepare for resource_manager, _mmcamcorder_resource_manager_prepare() first");
405                 ret = MM_ERROR_RESOURCE_INVALID_STATE;
406         } else {
407                 mrp_res_delete_resource_set(resource_manager->rset);
408                 resource_manager->rset = NULL;
409                 _mmcam_dbg_log("delete resource set done");
410         }
411
412         return ret;
413 }
414
415 int _mmcamcorder_resource_manager_deinit(MMCamcorderResourceManager *resource_manager)
416 {
417         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
418         MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
419
420         if (resource_manager->rset) {
421                 if (resource_manager->rset->state == MRP_RES_RESOURCE_ACQUIRED) {
422                         _mmcam_dbg_warn("resource is still acquired. release...");
423                         if (mrp_res_release_resource_set(resource_manager->rset))
424                                 _mmcam_dbg_err("- could not release resource");
425                 }
426                 _mmcam_dbg_log("delete resource set");
427                 mrp_res_delete_resource_set(resource_manager->rset);
428                 resource_manager->rset = NULL;
429         }
430         if (resource_manager->context) {
431                 _mmcam_dbg_log("destroy resource context");
432                 mrp_res_destroy(resource_manager->context);
433                 resource_manager->context = NULL;
434         }
435         if (resource_manager->mloop) {
436                 _mmcam_dbg_log("destroy resource mainloop");
437                 mrp_mainloop_destroy(resource_manager->mloop);
438                 resource_manager->mloop = NULL;
439         }
440
441         return MM_ERROR_NONE;
442 }