4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "mm_camcorder_internal.h"
21 #include "mm_camcorder_resource.h"
22 #include <murphy/common/glib-glue.h>
24 #define MRP_APP_CLASS_FOR_CAMCORDER "media"
25 #define MRP_RESOURCE_TYPE_MANDATORY TRUE
26 #define MRP_RESOURCE_TYPE_EXCLUSIVE FALSE
28 const char* mm_camcorder_resource_str[MM_CAMCORDER_RESOURCE_MAX] = {
33 #define MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(x_camcorder_resource_manager) \
35 if (!x_camcorder_resource_manager) { \
36 _mmcam_dbg_err("no resource manager instance"); \
37 return MM_ERROR_INVALID_ARGUMENT; \
41 #define MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(x_camcorder_resource_manager) \
43 if (!x_camcorder_resource_manager) { \
44 _mmcam_dbg_err("no resource manager instance"); \
45 return MM_ERROR_INVALID_ARGUMENT; \
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; \
54 static char *__mmcamcorder_resource_state_to_str(mrp_res_resource_state_t st)
56 char *state = "unknown";
58 case MRP_RES_RESOURCE_ACQUIRED:
61 case MRP_RES_RESOURCE_LOST:
64 case MRP_RES_RESOURCE_AVAILABLE:
67 case MRP_RES_RESOURCE_PENDING:
70 case MRP_RES_RESOURCE_ABOUT_TO_LOOSE:
71 state = "about to loose";
77 static void __mmcamcorder_resource_state_callback(mrp_res_context_t *context, mrp_res_error_t err, void *user_data)
80 const mrp_res_resource_set_t *rset;
81 mrp_res_resource_t *resource;
82 mmf_camcorder_t* camcorder = NULL;
84 camcorder = (mmf_camcorder_t*)user_data;
86 mmf_return_if_fail((MMHandleType)camcorder);
87 mmf_return_if_fail(context);
89 _mmcam_dbg_warn("enter - state %d", context->state);
91 _MMCAMCORDER_LOCK_RESOURCE(camcorder);
93 switch (context->state) {
94 case MRP_RES_CONNECTED:
95 _mmcam_dbg_warn(" - connected to Murphy");
96 if ((rset = mrp_res_list_resources(context)) != NULL) {
97 mrp_res_string_array_t *resource_names;
98 resource_names = mrp_res_list_resource_names(rset);
99 if (!resource_names) {
100 _mmcam_dbg_err(" - no resources available");
101 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
104 for (i = 0; i < resource_names->num_strings; i++) {
105 resource = mrp_res_get_resource_by_name(rset, resource_names->strings[i]);
107 _mmcam_dbg_warn(" - available resource: %s", resource->name);
109 mrp_res_free_string_array(resource_names);
111 camcorder->resource_manager.is_connected = TRUE;
112 _MMCAMCORDER_RESOURCE_SIGNAL(camcorder);
114 case MRP_RES_DISCONNECTED:
115 _mmcam_dbg_err(" - disconnected from Murphy : stop camera");
117 if (camcorder->resource_manager.rset) {
118 mrp_res_delete_resource_set(camcorder->resource_manager.rset);
119 camcorder->resource_manager.rset = NULL;
122 if (camcorder->resource_manager.context) {
123 mrp_res_destroy(camcorder->resource_manager.context);
124 camcorder->resource_manager.context = NULL;
125 camcorder->resource_manager.is_connected = FALSE;
128 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
130 _MMCAMCORDER_LOCK_ASM(camcorder);
132 /* set value to inform a status is changed by resource manaer */
133 camcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_BY_RM;
135 /* Stop the camera */
136 __mmcamcorder_force_stop(camcorder);
139 camcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_NORMAL;
141 _MMCAMCORDER_UNLOCK_ASM(camcorder);
143 _MMCAMCORDER_LOCK_RESOURCE(camcorder);
147 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
149 _mmcam_dbg_warn("leave");
155 static void __mmcamcorder_resource_set_state_callback(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data)
158 mmf_camcorder_t *camcorder = (mmf_camcorder_t *)user_data;
159 mrp_res_resource_t *res;
161 mmf_return_if_fail((MMHandleType)camcorder);
163 _MMCAMCORDER_LOCK_RESOURCE(camcorder);
165 if (!mrp_res_equal_resource_set(rs, camcorder->resource_manager.rset)) {
166 _mmcam_dbg_warn("- resource set(%p) is not same as this camcorder handle's(%p)", rs, camcorder->resource_manager.rset);
167 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
171 _mmcam_dbg_log(" - resource set state of camcorder(%p) is changed to [%s]",
172 camcorder, __mmcamcorder_resource_state_to_str(rs->state));
174 for (i = 0; i < MM_CAMCORDER_RESOURCE_MAX; i++) {
175 res = mrp_res_get_resource_by_name(rs, mm_camcorder_resource_str[i]);
177 _mmcam_dbg_warn(" -- %s not present in resource set", mm_camcorder_resource_str[i]);
179 _mmcam_dbg_warn(" -- resource name [%s] -> [%s]",
180 res->name, __mmcamcorder_resource_state_to_str(res->state));
182 if (res->state == MRP_RES_RESOURCE_ACQUIRED) {
183 camcorder->resource_manager.acquire_remain--;
185 if (camcorder->resource_manager.acquire_remain <= 0) {
186 _mmcam_dbg_warn("send signal - resource acquire done");
187 _MMCAMCORDER_RESOURCE_SIGNAL(camcorder);
189 _mmcam_dbg_warn("remained acquire count %d",
190 camcorder->resource_manager.acquire_remain);
192 } else if (res->state == MRP_RES_RESOURCE_LOST) {
193 camcorder->resource_manager.acquire_remain++;
195 if (camcorder->resource_manager.acquire_remain >= camcorder->resource_manager.acquire_count) {
196 _mmcam_dbg_warn("resource release done");
198 if (camcorder->state > MM_CAMCORDER_STATE_NULL) {
199 _mmcam_dbg_warn("send resource signal");
200 _MMCAMCORDER_RESOURCE_SIGNAL(camcorder);
202 _mmcam_dbg_warn("skip resource signal - state %d", camcorder->state);
205 _mmcam_dbg_warn("acquired %d, lost %d",
206 camcorder->resource_manager.acquire_count,
207 camcorder->resource_manager.acquire_remain);
213 mrp_res_delete_resource_set(camcorder->resource_manager.rset);
214 camcorder->resource_manager.rset = mrp_res_copy_resource_set(rs);
216 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
222 static void __mmcamcorder_resource_release_cb(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data)
225 int current_state = MM_CAMCORDER_STATE_NONE;
226 mmf_camcorder_t* camcorder = (mmf_camcorder_t*)user_data;
227 mrp_res_resource_t *res;
229 mmf_return_if_fail((MMHandleType)camcorder);
231 current_state = _mmcamcorder_get_state((MMHandleType)camcorder);
232 if (current_state <= MM_CAMCORDER_STATE_NONE ||
233 current_state >= MM_CAMCORDER_STATE_NUM) {
234 _mmcam_dbg_err("Abnormal state. Or null handle. (%p, %d)", camcorder, current_state);
238 _mmcam_dbg_warn("enter");
240 _MMCAMCORDER_LOCK_RESOURCE(camcorder);
242 if (!mrp_res_equal_resource_set(rs, camcorder->resource_manager.rset)) {
243 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
244 _mmcam_dbg_warn("- resource set(%p) is not same as this camcorder handle's(%p)", rs, camcorder->resource_manager.rset);
248 /* set flag for resource release callback */
249 camcorder->resource_release_cb_calling = TRUE;
251 _mmcam_dbg_log(" - resource set state of camcorder(%p) is changed to [%s]",
252 camcorder, __mmcamcorder_resource_state_to_str(rs->state));
254 for (i = 0; i < MM_CAMCORDER_RESOURCE_MAX; i++) {
255 res = mrp_res_get_resource_by_name(rs, mm_camcorder_resource_str[i]);
257 _mmcam_dbg_warn(" -- %s not present in resource set", mm_camcorder_resource_str[i]);
259 _mmcam_dbg_warn(" -- resource name [%s] -> [%s]", res->name, __mmcamcorder_resource_state_to_str(res->state));
263 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
265 _MMCAMCORDER_LOCK_ASM(camcorder);
267 /* set value to inform a status is changed by resource manager */
268 camcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_BY_RM;
270 /* Stop the camera */
271 __mmcamcorder_force_stop(camcorder);
274 camcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_NORMAL;
276 _MMCAMCORDER_UNLOCK_ASM(camcorder);
278 _MMCAMCORDER_LOCK_RESOURCE(camcorder);
280 /* restore flag for resource release callback */
281 camcorder->resource_release_cb_calling = FALSE;
283 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
285 _mmcam_dbg_warn("leave");
290 int _mmcamcorder_resource_create_resource_set(MMCamcorderResourceManager *resource_manager)
292 if (resource_manager->rset) {
293 _mmcam_dbg_warn(" - resource set was already created, delete it");
294 mrp_res_delete_resource_set(resource_manager->rset);
295 resource_manager->rset = NULL;
298 resource_manager->rset = mrp_res_create_resource_set(resource_manager->context,
299 MRP_APP_CLASS_FOR_CAMCORDER, __mmcamcorder_resource_set_state_callback, (void*)resource_manager->user_data);
301 if (resource_manager->rset == NULL) {
302 _mmcam_dbg_err(" - could not create resource set");
303 return MM_ERROR_RESOURCE_INTERNAL;
306 if (!mrp_res_set_autorelease(TRUE, resource_manager->rset))
307 _mmcam_dbg_warn(" - could not set autorelease flag!");
309 _mmcam_dbg_log("done");
311 return MM_ERROR_NONE;
314 static int __mmcamcorder_resource_include_resource(MMCamcorderResourceManager *resource_manager, const char *resource_name)
316 mrp_res_resource_t *resource = NULL;
317 resource = mrp_res_create_resource(resource_manager->rset,
319 MRP_RESOURCE_TYPE_MANDATORY,
320 MRP_RESOURCE_TYPE_EXCLUSIVE);
321 if (resource == NULL) {
322 _mmcam_dbg_err(" - could not include resource[%s]", resource_name);
323 return MM_ERROR_RESOURCE_INTERNAL;
326 resource_manager->acquire_count++;
327 resource_manager->acquire_remain = resource_manager->acquire_count;
329 _mmcam_dbg_log(" - count[%d] include resource[%s]",
330 resource_manager->acquire_count, resource_name);
332 return MM_ERROR_NONE;
335 static int __mmcamcorder_resource_set_release_cb(MMCamcorderResourceManager *resource_manager)
337 int ret = MM_ERROR_NONE;
338 bool mrp_ret = FALSE;
340 if (resource_manager->rset) {
341 mrp_ret = mrp_res_set_release_callback(resource_manager->rset, __mmcamcorder_resource_release_cb, resource_manager->user_data);
343 _mmcam_dbg_err(" - could not set release callback");
344 ret = MM_ERROR_RESOURCE_INTERNAL;
347 _mmcam_dbg_err(" - resource set is null");
348 ret = MM_ERROR_RESOURCE_INVALID_STATE;
354 int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_manager, void *user_data)
356 GMainContext *mrp_ctx = NULL;
357 GMainLoop *mrp_loop = NULL;
359 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
361 _mmcam_dbg_warn("start");
363 mrp_ctx = g_main_context_new();
365 _mmcam_dbg_err("failed to get create glib context for mrp");
366 return MM_ERROR_RESOURCE_INTERNAL;
369 mrp_loop = g_main_loop_new(mrp_ctx, TRUE);
371 g_main_context_unref(mrp_ctx);
375 _mmcam_dbg_err("failed to get create glib loop for mrp");
376 return MM_ERROR_RESOURCE_INTERNAL;
379 resource_manager->mloop = mrp_mainloop_glib_get(mrp_loop);
381 g_main_loop_unref(mrp_loop);
384 if (!resource_manager->mloop) {
385 _mmcam_dbg_err("failed to get mainloop for mrp");
386 return MM_ERROR_RESOURCE_INTERNAL;
389 _mmcam_dbg_warn("mloop %p", resource_manager->mloop);
391 resource_manager->context = mrp_res_create(resource_manager->mloop, __mmcamcorder_resource_state_callback, user_data);
392 if (!resource_manager->context) {
393 _mmcam_dbg_err("could not get context for mrp");
395 mrp_mainloop_destroy(resource_manager->mloop);
396 resource_manager->mloop = NULL;
398 return MM_ERROR_RESOURCE_INTERNAL;
401 resource_manager->user_data = user_data;
403 _mmcam_dbg_log("done");
405 return MM_ERROR_NONE;
409 int _mmcamcorder_resource_wait_for_connection(MMCamcorderResourceManager *resource_manager, void *hcamcorder)
411 int ret = MM_ERROR_NONE;
413 mmf_return_val_if_fail(resource_manager && hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
415 _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
417 if (resource_manager->is_connected == FALSE) {
420 /* wait for resource manager connected */
421 _mmcam_dbg_warn("not connected. wait for signal...");
423 end_time = g_get_monotonic_time() + (__MMCAMCORDER_RESOURCE_WAIT_TIME * G_TIME_SPAN_SECOND);
425 if (_MMCAMCORDER_RESOURCE_WAIT_UNTIL(hcamcorder, end_time)) {
426 _mmcam_dbg_warn("signal received");
429 _mmcam_dbg_err("connection timeout");
430 ret = MM_ERROR_RESOURCE_INTERNAL;
433 _mmcam_dbg_warn("already connected");
436 _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
442 int _mmcamcorder_resource_manager_prepare(MMCamcorderResourceManager *resource_manager, MMCamcorderResourceType resource_type)
444 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
445 MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
447 return __mmcamcorder_resource_include_resource(resource_manager, mm_camcorder_resource_str[resource_type]);
450 int _mmcamcorder_resource_manager_acquire(MMCamcorderResourceManager *resource_manager)
452 int ret = MM_ERROR_NONE;
453 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
454 MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
456 if (resource_manager->rset == NULL) {
457 _mmcam_dbg_err("- could not acquire resource, resource set is null");
458 ret = MM_ERROR_RESOURCE_INVALID_STATE;
460 ret = __mmcamcorder_resource_set_release_cb(resource_manager);
462 _mmcam_dbg_err("- could not set resource release cb, ret(%d)", ret);
463 ret = MM_ERROR_RESOURCE_INTERNAL;
465 ret = mrp_res_acquire_resource_set(resource_manager->rset);
467 _mmcam_dbg_err("- could not acquire resource, ret(%d)", ret);
468 ret = MM_ERROR_RESOURCE_INTERNAL;
476 int _mmcamcorder_resource_manager_release(MMCamcorderResourceManager *resource_manager)
478 int ret = MM_ERROR_NONE;
479 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
480 MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
482 if (resource_manager->rset == NULL) {
483 _mmcam_dbg_err("- could not release resource, resource set is null");
484 ret = MM_ERROR_RESOURCE_INVALID_STATE;
486 if (resource_manager->rset->state != MRP_RES_RESOURCE_ACQUIRED) {
487 _mmcam_dbg_err("- could not release resource, resource set state is [%s]",
488 __mmcamcorder_resource_state_to_str(resource_manager->rset->state));
489 ret = MM_ERROR_RESOURCE_INVALID_STATE;
491 ret = mrp_res_release_resource_set(resource_manager->rset);
493 _mmcam_dbg_err("- could not release resource, ret(%d)", ret);
494 ret = MM_ERROR_RESOURCE_INTERNAL;
496 _mmcam_dbg_log("resource release done");
505 int _mmcamcorder_resource_manager_deinit(MMCamcorderResourceManager *resource_manager)
507 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
509 _mmcam_dbg_warn("rset %p, context %p, mloop %p",
510 resource_manager->rset, resource_manager->context, resource_manager->mloop);
512 if (resource_manager->rset) {
513 if (resource_manager->rset->state == MRP_RES_RESOURCE_ACQUIRED) {
514 _mmcam_dbg_warn("resource is still acquired. release...");
515 if (mrp_res_release_resource_set(resource_manager->rset))
516 _mmcam_dbg_err("- could not release resource");
519 _mmcam_dbg_warn("delete resource set");
521 mrp_res_delete_resource_set(resource_manager->rset);
522 resource_manager->rset = NULL;
525 if (resource_manager->context) {
526 _mmcam_dbg_warn("destroy resource context");
528 mrp_res_destroy(resource_manager->context);
529 resource_manager->context = NULL;
532 if (resource_manager->mloop) {
533 _mmcam_dbg_warn("destroy resource mainloop");
535 mrp_mainloop_quit(resource_manager->mloop, 0);
536 mrp_mainloop_destroy(resource_manager->mloop);
537 resource_manager->mloop = NULL;
540 _mmcam_dbg_warn("done");
542 return MM_ERROR_NONE;