From: Seungbae Shin Date: Wed, 28 Feb 2018 07:50:15 +0000 (+0900) Subject: Seperates privilege implementations from CAudioInput X-Git-Tag: accepted/tizen/unified/20181107.082100~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fapi%2Faudio-io.git;a=commitdiff_plain;h=4d0fed17af4a54e451772f5c1227b0ed9541b9a7 Seperates privilege implementations from CAudioInput [Version] 0.5.12 [Issue Type] Revise Change-Id: I174b9cf04881acb0ff03fec1968e2f50aca8ec56 --- diff --git a/include/cpp_audio_in_privilege.h b/include/cpp_audio_in_privilege.h new file mode 100644 index 0000000..266366e --- /dev/null +++ b/include/cpp_audio_in_privilege.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TIZEN_MEDIA_AUDIO_IN_PRIVILEGE_H__ +#define __TIZEN_MEDIA_AUDIO_IN_PRIVILEGE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +bool cpp_audio_in_has_record_privilege(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_MEDIA_AUDIO_IN_PRIVILEGE_H__ */ diff --git a/packaging/capi-media-audio-io.spec b/packaging/capi-media-audio-io.spec index 742b39c..3b9dd97 100644 --- a/packaging/capi-media-audio-io.spec +++ b/packaging/capi-media-audio-io.spec @@ -1,6 +1,6 @@ Name: capi-media-audio-io Summary: An Audio Input & Audio Output library in Tizen Native API -Version: 0.5.11 +Version: 0.5.12 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/cpp/CAudioInput.cpp b/src/cpp/CAudioInput.cpp index 6302501..6c365e6 100644 --- a/src/cpp/CAudioInput.cpp +++ b/src/cpp/CAudioInput.cpp @@ -17,9 +17,9 @@ #include -#include #include "CAudioIODef.h" #include +#include "cpp_audio_in_privilege.h" #define RECORDER_PRIVILEGE "http://tizen.org/privilege/recorder" #define CLIENT_NAME "AUDIO_IO_PA_CLIENT" @@ -27,11 +27,6 @@ using namespace std; using namespace tizen_media_audio; -struct PrivilegeData { - bool isPrivilegeAllowed; - pa_threaded_mainloop *paMainloop; -}; - /** * class CAudioInput inherited by CAudioIO */ @@ -91,114 +86,16 @@ bool CAudioInput::__IsReady() { return CAudioIO::IsReady(); } -static void __contextStateChangeCb(pa_context* c, void* user_data) { - pa_threaded_mainloop *paMainloop = static_cast(user_data); - assert(paMainloop); - assert(c); - - switch (pa_context_get_state(c)) { - case PA_CONTEXT_READY: - AUDIO_IO_LOGD("The context is ready"); - pa_threaded_mainloop_signal(paMainloop, 0); - break; - - case PA_CONTEXT_FAILED: - case PA_CONTEXT_TERMINATED: - AUDIO_IO_LOGD("The context is lost"); - pa_threaded_mainloop_signal(paMainloop, 0); - break; - - case PA_CONTEXT_UNCONNECTED: - case PA_CONTEXT_CONNECTING: - case PA_CONTEXT_AUTHORIZING: - case PA_CONTEXT_SETTING_NAME: - break; - } -} - -static void __checkPrivilegeCb(pa_context *c, int success, void *user_data) { - AUDIO_IO_LOGD("pa_context[%p], success[%d], user_data[%p]", c, success, user_data); - assert(c); - assert(user_data); - - PrivilegeData *prData = static_cast(user_data); - prData->isPrivilegeAllowed = success ? true : false; - - pa_threaded_mainloop_signal(prData->paMainloop, 0); -} - -static bool __IsPrivilegeAllowed() { - pa_operation *o; - pa_context *c; - int err = 0; - PrivilegeData prData; - - prData.paMainloop = pa_threaded_mainloop_new(); - if (prData.paMainloop == NULL) - THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pa_threaded_mainloop_new()"); - - c = pa_context_new(pa_threaded_mainloop_get_api(prData.paMainloop), CLIENT_NAME); - if (c == NULL) - THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pa_context_new()"); - - pa_context_set_state_callback(c, __contextStateChangeCb, prData.paMainloop); - - if (pa_context_connect(c, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0) - THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pa_context_connect()"); - - pa_threaded_mainloop_lock(prData.paMainloop); - - if (pa_threaded_mainloop_start(prData.paMainloop) < 0) { - pa_threaded_mainloop_unlock(prData.paMainloop); - THROW_ERROR_MSG(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed pa_threaded_mainloop_start()"); - } - - while (true) { - pa_context_state_t state; - state = pa_context_get_state(c); - - if (state == PA_CONTEXT_READY) - break; - - if (!PA_CONTEXT_IS_GOOD(state)) { - err = pa_context_errno(c); - pa_threaded_mainloop_unlock(prData.paMainloop); - THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, - "pa_context's state is not good : err[%d]", err); - } - - /* Wait until the context is ready */ - pa_threaded_mainloop_wait(prData.paMainloop); - } - - o = pa_context_check_privilege(c, RECORDER_PRIVILEGE, __checkPrivilegeCb, &prData); - if (!o) { - pa_threaded_mainloop_unlock(prData.paMainloop); - THROW_ERROR_MSG(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed to pa_context_check_privilege()"); - } - while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) - pa_threaded_mainloop_wait(prData.paMainloop); - pa_operation_unref(o); - - pa_threaded_mainloop_unlock(prData.paMainloop); - pa_threaded_mainloop_stop(prData.paMainloop); - pa_context_disconnect(c); - pa_context_unref(c); - pa_threaded_mainloop_free(prData.paMainloop); - - return prData.isPrivilegeAllowed; -} - void CAudioInput::initialize() { if (__IsInit() == true) return; - if (__IsPrivilegeAllowed() == false) + if (cpp_audio_in_has_record_privilege() == false) THROW_ERROR_MSG(CAudioError::EError::ERROR_PERMISSION_DENIED, "No privilege for record"); try { CAudioIO::initialize(); - __setInit(true); + __setInit(true); } catch (CAudioError& e) { finalize(); throw; diff --git a/src/cpp/cpp_audio_in_privilege.cpp b/src/cpp/cpp_audio_in_privilege.cpp new file mode 100644 index 0000000..ae914ca --- /dev/null +++ b/src/cpp/cpp_audio_in_privilege.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cpp_audio_in_privilege.h" +#include "CAudioIODef.h" +#include +#include + +#define RECORDER_PRIVILEGE "http://tizen.org/privilege/recorder" +#define CLIENT_NAME "AUDIO_IO_PA_CLIENT" + +using namespace std; +using namespace tizen_media_audio; + + +struct PrivilegeData { + bool isPrivilegeAllowed; + pa_threaded_mainloop *paMainloop; +}; + +static void __contextStateChangeCb(pa_context* c, void* user_data) { + pa_threaded_mainloop *paMainloop = (pa_threaded_mainloop *)user_data; + assert(paMainloop); + assert(c); + + switch (pa_context_get_state(c)) { + case PA_CONTEXT_READY: + AUDIO_IO_LOGD("The context is ready"); + pa_threaded_mainloop_signal(paMainloop, 0); + break; + + case PA_CONTEXT_FAILED: + case PA_CONTEXT_TERMINATED: + AUDIO_IO_LOGD("The context is lost"); + pa_threaded_mainloop_signal(paMainloop, 0); + break; + + case PA_CONTEXT_UNCONNECTED: + case PA_CONTEXT_CONNECTING: + case PA_CONTEXT_AUTHORIZING: + case PA_CONTEXT_SETTING_NAME: + break; + } +} + +static void __checkPrivilegeCb(pa_context *c, int success, void *user_data) { + AUDIO_IO_LOGD("pa_context[%p], success[%d], user_data[%p]", c, success, user_data); + assert(c); + assert(user_data); + + PrivilegeData *prData = (PrivilegeData *)user_data; + prData->isPrivilegeAllowed = success ? true : false; + + pa_threaded_mainloop_signal(prData->paMainloop, 0); +} + +bool cpp_audio_in_has_record_privilege(void) { + pa_operation *o; + pa_context *c; + int err = 0; + PrivilegeData prData; + + prData.paMainloop = pa_threaded_mainloop_new(); + if (prData.paMainloop == NULL) + THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pa_threaded_mainloop_new()"); + + c = pa_context_new(pa_threaded_mainloop_get_api(prData.paMainloop), CLIENT_NAME); + if (c == NULL) + THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pa_context_new()"); + + pa_context_set_state_callback(c, __contextStateChangeCb, prData.paMainloop); + + if (pa_context_connect(c, NULL, PA_CONTEXT_NOFLAGS, NULL) < 0) + THROW_ERROR_MSG(CAudioError::EError::ERROR_OUT_OF_MEMORY, "Failed pa_context_connect()"); + + pa_threaded_mainloop_lock(prData.paMainloop); + + if (pa_threaded_mainloop_start(prData.paMainloop) < 0) { + pa_threaded_mainloop_unlock(prData.paMainloop); + THROW_ERROR_MSG(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed pa_threaded_mainloop_start()"); + } + + while (true) { + pa_context_state_t state; + state = pa_context_get_state(c); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + err = pa_context_errno(c); + pa_threaded_mainloop_unlock(prData.paMainloop); + THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INTERNAL_OPERATION, + "pa_context's state is not good : err[%d]", err); + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(prData.paMainloop); + } + + o = pa_context_check_privilege(c, RECORDER_PRIVILEGE, __checkPrivilegeCb, &prData); + if (!o) { + pa_threaded_mainloop_unlock(prData.paMainloop); + THROW_ERROR_MSG(CAudioError::EError::ERROR_FAILED_OPERATION, "Failed to pa_context_check_privilege()"); + } + while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) + pa_threaded_mainloop_wait(prData.paMainloop); + pa_operation_unref(o); + + pa_threaded_mainloop_unlock(prData.paMainloop); + pa_threaded_mainloop_stop(prData.paMainloop); + pa_context_disconnect(c); + pa_context_unref(c); + pa_threaded_mainloop_free(prData.paMainloop); + + return prData.isPrivilegeAllowed; +}