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 if (err != MRP_RES_ERROR_NONE) {
85 _mmcam_dbg_err(" - error message received from Murphy, err(0x%x)", err);
89 camcorder = (mmf_camcorder_t*)user_data;
91 mmf_return_if_fail((MMHandleType)camcorder);
93 _mmcam_dbg_log("enter");
95 _MMCAMCORDER_LOCK_RESOURCE(camcorder);
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);
108 for (i = 0; i < resource_names->num_strings; i++) {
109 resource = mrp_res_get_resource_by_name(rset, resource_names->strings[i]);
111 _mmcam_dbg_log(" - available resource: %s", resource->name);
114 mrp_res_free_string_array(resource_names);
116 camcorder->resource_manager.is_connected = TRUE;
117 _MMCAMCORDER_RESOURCE_SIGNAL(camcorder);
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;
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;
133 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
135 _mmcam_dbg_log("leave");
141 static void __mmcamcorder_resource_set_state_callback(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data)
144 mmf_camcorder_t *camcorder = (mmf_camcorder_t *)user_data;
145 mrp_res_resource_t *res;
147 mmf_return_if_fail((MMHandleType)camcorder);
149 _MMCAMCORDER_LOCK_RESOURCE(camcorder);
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);
157 _mmcam_dbg_log(" - resource set state of camcorder(%p) is changed to [%s]",
158 camcorder, __mmcamcorder_resource_state_to_str(rs->state));
160 for (i = 0; i < MM_CAMCORDER_RESOURCE_MAX; i++) {
161 res = mrp_res_get_resource_by_name(rs, mm_camcorder_resource_str[i]);
163 _mmcam_dbg_warn(" -- %s not present in resource set", mm_camcorder_resource_str[i]);
165 _mmcam_dbg_log(" -- resource name [%s] -> [%s]",
166 res->name, __mmcamcorder_resource_state_to_str(res->state));
168 if (res->state == MRP_RES_RESOURCE_ACQUIRED) {
169 camcorder->resource_manager.acquire_count--;
171 if (camcorder->resource_manager.acquire_count <= 0) {
172 _mmcam_dbg_log("send signal - resource acquire done");
173 _MMCAMCORDER_RESOURCE_SIGNAL(camcorder);
175 _mmcam_dbg_warn("remained acquire count %d",
176 camcorder->resource_manager.acquire_count);
182 mrp_res_delete_resource_set(camcorder->resource_manager.rset);
183 camcorder->resource_manager.rset = mrp_res_copy_resource_set(rs);
185 _MMCAMCORDER_UNLOCK_RESOURCE(camcorder);
191 static void __mmcamcorder_resource_release_cb(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data)
194 int current_state = MM_CAMCORDER_STATE_NONE;
195 mmf_camcorder_t* camcorder = (mmf_camcorder_t*)user_data;
196 mrp_res_resource_t *res;
198 mmf_return_if_fail((MMHandleType)camcorder);
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);
207 /* set value to inform a status is changed by resource manaer */
208 camcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_BY_RM;
210 _MMCAMCORDER_LOCK_ASM(camcorder);
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);
218 _mmcam_dbg_log(" - resource set state of camcorder(%p) is changed to [%s]",
219 camcorder, __mmcamcorder_resource_state_to_str(rs->state));
221 for (i = 0; i < MM_CAMCORDER_RESOURCE_MAX; i++) {
222 res = mrp_res_get_resource_by_name(rs, mm_camcorder_resource_str[i]);
224 _mmcam_dbg_warn(" -- %s not present in resource set", mm_camcorder_resource_str[i]);
226 _mmcam_dbg_log(" -- resource name [%s] -> [%s]",
227 res->name, __mmcamcorder_resource_state_to_str(res->state));
231 /* Stop the camera */
232 __mmcamcorder_force_stop(camcorder);
235 camcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_NORMAL;
237 _MMCAMCORDER_UNLOCK_ASM(camcorder);
242 static int __mmcamcorder_resource_create_resource_set(MMCamcorderResourceManager *resource_manager)
244 if (resource_manager->rset) {
245 _mmcam_dbg_err(" - resource set was already created");
246 return MM_ERROR_RESOURCE_INVALID_STATE;
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);
252 if (resource_manager->rset == NULL) {
253 _mmcam_dbg_err(" - could not create resource set");
254 return MM_ERROR_RESOURCE_INTERNAL;
257 if (!mrp_res_set_autorelease(TRUE, resource_manager->rset)) {
258 _mmcam_dbg_warn(" - could not set autorelease flag!");
261 return MM_ERROR_NONE;
264 static int __mmcamcorder_resource_include_resource(MMCamcorderResourceManager *resource_manager, const char *resource_name)
266 mrp_res_resource_t *resource = NULL;
267 resource = mrp_res_create_resource(resource_manager->rset,
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;
276 resource_manager->acquire_count++;
278 _mmcam_dbg_log(" - count[%d] include resource[%s]",
279 resource_manager->acquire_count, resource_name);
281 return MM_ERROR_NONE;
284 static int __mmcamcorder_resource_set_release_cb(MMCamcorderResourceManager *resource_manager)
286 int ret = MM_ERROR_NONE;
287 bool mrp_ret = FALSE;
289 if (resource_manager->rset) {
290 mrp_ret = mrp_res_set_release_callback(resource_manager->rset, __mmcamcorder_resource_release_cb, resource_manager->user_data);
292 _mmcam_dbg_err(" - could not set release callback");
293 ret = MM_ERROR_RESOURCE_INTERNAL;
296 _mmcam_dbg_err(" - resource set is null");
297 ret = MM_ERROR_RESOURCE_INVALID_STATE;
303 int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_manager, void *user_data)
305 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
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;
316 resource_manager->user_data = user_data;
318 _mmcam_dbg_err("- could not get mainloop for resource manager");
319 return MM_ERROR_RESOURCE_INTERNAL;
322 return MM_ERROR_NONE;
325 int _mmcamcorder_resource_manager_prepare(MMCamcorderResourceManager *resource_manager, MMCamcorderResourceType resource_type)
327 int ret = MM_ERROR_NONE;
328 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
329 MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
331 if (!resource_manager->rset) {
332 ret = __mmcamcorder_resource_create_resource_set(resource_manager);
334 if (ret == MM_ERROR_NONE) {
335 ret = __mmcamcorder_resource_include_resource(resource_manager, mm_camcorder_resource_str[resource_type]);
337 _mmcam_dbg_err("failed to create resource set 0x%x", ret);
343 int _mmcamcorder_resource_manager_acquire(MMCamcorderResourceManager *resource_manager)
345 int ret = MM_ERROR_NONE;
346 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
347 MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
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;
353 ret = __mmcamcorder_resource_set_release_cb(resource_manager);
355 _mmcam_dbg_err("- could not set resource release cb, ret(%d)", ret);
356 ret = MM_ERROR_RESOURCE_INTERNAL;
358 ret = mrp_res_acquire_resource_set(resource_manager->rset);
360 _mmcam_dbg_err("- could not acquire resource, ret(%d)", ret);
361 ret = MM_ERROR_RESOURCE_INTERNAL;
369 int _mmcamcorder_resource_manager_release(MMCamcorderResourceManager *resource_manager)
371 int ret = MM_ERROR_NONE;
372 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
373 MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
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;
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;
384 ret = mrp_res_release_resource_set(resource_manager->rset);
386 _mmcam_dbg_err("- could not release resource, ret(%d)", ret);
387 ret = MM_ERROR_RESOURCE_INTERNAL;
389 _mmcam_dbg_log("resource release done");
397 int _mmcamcorder_resource_manager_unprepare(MMCamcorderResourceManager *resource_manager)
399 int ret = MM_ERROR_NONE;
400 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
401 MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
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;
407 mrp_res_delete_resource_set(resource_manager->rset);
408 resource_manager->rset = NULL;
409 _mmcam_dbg_log("delete resource set done");
415 int _mmcamcorder_resource_manager_deinit(MMCamcorderResourceManager *resource_manager)
417 MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
418 MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
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");
426 _mmcam_dbg_log("delete resource set");
427 mrp_res_delete_resource_set(resource_manager->rset);
428 resource_manager->rset = NULL;
430 if (resource_manager->context) {
431 _mmcam_dbg_log("destroy resource context");
432 mrp_res_destroy(resource_manager->context);
433 resource_manager->context = NULL;
435 if (resource_manager->mloop) {
436 _mmcam_dbg_log("destroy resource mainloop");
437 mrp_mainloop_destroy(resource_manager->mloop);
438 resource_manager->mloop = NULL;
441 return MM_ERROR_NONE;