From f623fd180bc53768b5c07cf0190805685b0a89bc Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Tue, 8 Sep 2015 22:11:06 +0900 Subject: [PATCH] tizen 2.3.1 release --- CMakeLists.txt | 4 +- LICENSE => LICENSE.APLv2 | 0 NOTICE | 3 + capi-media-radio.manifest | 8 + doc/image/capi_media_radio_state_diagram.png | Bin 0 -> 31863 bytes doc/radio_doc.h | 152 ++++++++ include/radio.h | 200 ++++++---- packaging/capi-media-radio.spec | 28 +- src/radio.c | 212 ++++++++--- test/CMakeLists.txt | 22 ++ test/radio_test.c | 530 +++++++++++++++++++++++++++ test/radio_test_type.h | 49 +++ 12 files changed, 1083 insertions(+), 125 deletions(-) rename LICENSE => LICENSE.APLv2 (100%) create mode 100644 NOTICE create mode 100755 capi-media-radio.manifest create mode 100644 doc/image/capi_media_radio_state_diagram.png create mode 100644 doc/radio_doc.h create mode 100644 test/CMakeLists.txt create mode 100644 test/radio_test.c create mode 100644 test/radio_test_type.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c99f3ec..6118bf2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(INC_DIR include) INCLUDE_DIRECTORIES(${INC_DIR}) -SET(dependents "dlog mm-radio capi-base-common") +SET(dependents "dlog mm-radio capi-base-common capi-system-info") SET(pc_dependents "capi-base-common") INCLUDE(FindPkgConfig) @@ -63,7 +63,7 @@ CONFIGURE_FILE( ) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig) -#ADD_SUBDIRECTORY(test) +ADD_SUBDIRECTORY(test) IF(UNIX) diff --git a/LICENSE b/LICENSE.APLv2 similarity index 100% rename from LICENSE rename to LICENSE.APLv2 diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..ccdad52 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE file for Apache License terms and conditions. diff --git a/capi-media-radio.manifest b/capi-media-radio.manifest new file mode 100755 index 0000000..a6040c4 --- /dev/null +++ b/capi-media-radio.manifest @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/doc/image/capi_media_radio_state_diagram.png b/doc/image/capi_media_radio_state_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..dad0dc9bf15018e2b22ecf5a1ce26ce9440128b9 GIT binary patch literal 31863 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

2??=W_GC7% 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 literal 0 HcmV?d00001 diff --git a/doc/radio_doc.h b/doc/radio_doc.h new file mode 100644 index 0000000..7034036 --- /dev/null +++ b/doc/radio_doc.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2011 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_RADIO_DOC_H__ +#define __TIZEN_MEDIA_RADIO_DOC_H__ + + +/** + * @file radio_doc.h + * @brief This file contains high level documentation of the Multimedia Service. + */ + +/** + * @ingroup CAPI_MEDIA_FRAMEWORK + * @defgroup CAPI_MEDIA_RADIO_MODULE Radio + * @brief The @ref CAPI_MEDIA_RADIO_MODULE APIs provide functions for accessing the radio. + * + * @section CAPI_MEDIA_RADIO_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_MEDIA_RADIO_MODULE_OVERVIEW Overview + * + * The Radio API provides support for using the Radio. + * The API allows : + * - Starting and stopping the radio + * - Seeking radio frequency + * - Scanning radio signals + * - Getting the state of the radio + * + * A radio handle (#radio_h) is created by calling the radio_create() function and can be started by using the radio_start() function. + * It provides functions to start (radio_scan_start()) and stop (radio_scan_stop()) radio signal scanning. The radio frequency + * seek up and seek down can be done asynchronously by calling the radio_seek_up() and radio_seek_down() functions respectively. + * It also provides functions to get (radio_get_frequency()) and set (radio_set_frequency()) frequency for the given radio handle. + * + * @subsection CAPI_MEDIA_RADIO_LIFE_CYCLE_STATE_DIAGRAM State Diagram + * The radio API is controlled by a state machine. + * The following diagram shows the life cycle and the states of the Radio. + * @image html capi_media_radio_state_diagram.png + * + * + * @subsection CAPI_MEDIA_RADIO_LIFE_CYCLE_STATE_TRANSITIONS State Transitions + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
FUNCTIONPRE-STATEPOST-STATESYNC TYPE
radio_create()NONEREADYSYNC
radio_destroy()READYNONESYNC
radio_start()READYPLAYINGASYNC
radio_stop()PLAYINGREADYASYNC
radio_scan_start()READYSCANNINGASYNC
radio_scan_stop()SCANNINGREADYASYNC
radio_seek_up()PLAYINGPLAYINGSYNC
radio_seek_down()PLAYINGPLAYINGSYNC
+ * + * + * This API also gives notifications for radio's state change events by a callback mechanism. + * @subsection CAPI_MEDIA_RADIO_LIFE_CYCLE_CALLBACK_OPERATIONS Callback(Event) Operations + * The callback mechanism is used to notify the application about radio events. + *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
REGISTERUNREGISTERCALLBACKDESCRIPTION
radio_set_scan_completed_cb()radio_unset_scan_completed_cb() radio_scan_completed_cb()This callback is invoked when the scan is completed
radio_set_interrupted_cb()radio_unset_interrupted_cb()radio_interrupted_cb()This callback is used to notify when the radio is interrupted
+ * @section CAPI_MEDIA_RADIO_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://tizen.org/feature/fmradio\n + * + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * + * + */ + +#endif /* __TIZEN_MEDIA_RADIO_DOC_H__ */ diff --git a/include/radio.h b/include/radio.h index 57dfaa6..6d354e1 100644 --- a/include/radio.h +++ b/include/radio.h @@ -11,7 +11,7 @@ * 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. +* limitations under the License. */ #ifndef __TIZEN_MEDIA_RADIO_H__ @@ -23,11 +23,10 @@ extern "C" { #endif -#define RADIO_ERROR_CLASS TIZEN_ERROR_MULTIMEDIA_CLASS | 0x70 - /** * @file radio.h * @brief This file contains the radio API. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ /** @@ -36,68 +35,79 @@ extern "C" { */ /** - * @brief Radio handle type. + * @brief Radio type handle. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef struct radio_s *radio_h; /** - * @brief Enumerations of radio state + * @brief Enumeration of radio state. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { RADIO_STATE_READY, /**< Ready to play or scan */ - RADIO_STATE_PLAYING, /**< Playing audio from the tuner */ - RADIO_STATE_SCANNING, /**< Scanning Searching for the next station signal starts from a given starting frequency */ + RADIO_STATE_PLAYING, /**< Playing the audio from the tuner */ + RADIO_STATE_SCANNING, /**< Scanning/Searching for the next station signal that starts from a given starting frequency */ } radio_state_e; /** - * @brief Error codes for radio + * @brief Enumeration of error codes for the radio. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { - RADIO_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ - RADIO_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - RADIO_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ - RADIO_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */ - RADIO_ERROR_INVALID_STATE = RADIO_ERROR_CLASS | 0x01 , /**< Invalid state */ - RADIO_ERROR_SOUND_POLICY = RADIO_ERROR_CLASS | 0x02 , /**< Sound policy error */ + RADIO_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + RADIO_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + RADIO_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + RADIO_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */ + RADIO_ERROR_INVALID_STATE = TIZEN_ERROR_RADIO | 0x01 , /**< Invalid state */ + RADIO_ERROR_SOUND_POLICY = TIZEN_ERROR_RADIO | 0x02 , /**< Sound policy error */ + RADIO_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + RADIO_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ } radio_error_e; /** - * @brief Enumerations of radio interrupted type + * @brief Enumeration of radio interrupted type. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { - RADIO_INTERRUPTED_BY_OTHER_APP = 0, /**< Interrupted by another application*/ - RADIO_INTERRUPTED_BY_CALL_START, /**< Interrupted by call starting*/ - RADIO_INTERRUPTED_BY_CALL_END, /**< Interrupted by call ending*/ - RADIO_INTERRUPTED_BY_EARJACK_UNPLUG, /**< Interrupted by unplugging headphone*/ - RADIO_INTERRUPTED_BY_RESOURCE_CONFLICT, /**< Interrupted by resource conflict*/ - RADIO_INTERRUPTED_BY_ALARM_START, /**< Interrupted by alarm starting*/ - RADIO_INTERRUPTED_BY_ALARM_END, /**< Interrupted by alarm ending*/ + RADIO_INTERRUPTED_COMPLETED = 0, /**< Interrupt completed */ + RADIO_INTERRUPTED_BY_MEDIA, /**< Interrupted by a non-resumable media application */ + RADIO_INTERRUPTED_BY_CALL, /**< Interrupted by an incoming call */ + RADIO_INTERRUPTED_BY_EARJACK_UNPLUG, /**< Interrupted by unplugging headphones */ + RADIO_INTERRUPTED_BY_RESOURCE_CONFLICT, /**< Interrupted by a resource conflict */ + RADIO_INTERRUPTED_BY_ALARM, /**< Interrupted by an alarm */ + RADIO_INTERRUPTED_BY_EMERGENCY, /**< Interrupted by an emergency */ + RADIO_INTERRUPTED_BY_RESUMABLE_MEDIA, /**< Interrupted by a resumable media application */ + RADIO_INTERRUPTED_BY_NOTIFICATION, /**< Interrupted by a notification */ } radio_interrupted_code_e; /** * @brief Called when the scan information is updated. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] frequency The tuned radio frequency [87500 ~ 108000] (kHz) * @param[in] user_data The user data passed from the callback registration function - * @pre It will be invoked by radio_scan_start() + * @pre It will be invoked by radio_scan_start(). * @see radio_scan_start() */ typedef void (*radio_scan_updated_cb)(int frequency, void *user_data); /** * @brief Called when the radio scan is stopped. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] user_data The user data passed from the callback registration function - * @pre It will be invoked when scan is stopped by radio_scan_stop() + * @pre It will be invoked when the scan is stopped by radio_scan_stop(). * @see radio_scan_stop() */ typedef void (*radio_scan_stopped_cb)(void *user_data); /** * @brief Called when the radio scan is completed. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] user_data The user data passed from the callback registration function - * @pre It will be invoked when scan is completed if you register this callback using radio_set_scan_completed_cb() + * @pre It will be invoked when the scan is completed by registering this callback using radio_set_scan_completed_cb(). * @see radio_scan_start() * @see radio_set_scan_completed_cb() * @see radio_unset_scan_completed_cb() @@ -106,9 +116,10 @@ typedef void (*radio_scan_completed_cb)(void *user_data); /** * @brief Called when the radio seek is completed. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] frequency The current frequency [87500 ~ 108000] (kHz) * @param[in] user_data The user data passed from the callback registration function - * @pre It will be invoked when radio seek completed if you register this callback using radio_seek_up() or radio_seek_down() + * @pre It will be invoked when the radio seek is completed by registering this callback using radio_seek_up() or radio_seek_down(). * @see radio_seek_up() * @see radio_seek_down() */ @@ -116,6 +127,7 @@ typedef void (*radio_seek_completed_cb)(int frequency, void *user_data); /** * @brief Called when the radio is interrupted. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] error_code The interrupted error code * @param[in] user_data The user data passed from the callback registration function * @see radio_set_interrupted_cb() @@ -125,63 +137,75 @@ typedef void (*radio_interrupted_cb)(radio_interrupted_code_e code, void *user_d /** * @brief Creates a radio handle. - * @remarks @a radio must be released radio_destroy() by you. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks You must release @a radio using radio_destroy(). * @param[out] radio A new handle to radio * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_OUT_OF_MEMORY Out of memory * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported * @see radio_destroy() */ int radio_create(radio_h *radio); /** * @brief Destroys the radio handle and releases all its resources. - * - * @remarks To completely shutdown radio operation, call this function with a valid radio handle. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks To completely shutdown the radio operation, call this function with a valid radio handle. * * @param[in] radio The handle to radio to be destroyed - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported * @see radio_create() */ int radio_destroy(radio_h radio); /** * @brief Gets the radio's current state. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio * @param[out] state The current state of the radio - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported */ int radio_get_state(radio_h radio, radio_state_e *state); /** - * @brief Starts playing radio. - * + * @brief Starts playing the radio. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_STATE Invalid radio state * @retval #RADIO_ERROR_SOUND_POLICY Sound policy error - * @pre The radio state must be #RADIO_STATE_READY by radio_create(). + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported + * @pre The radio state must be set to #RADIO_STATE_READY by calling radio_create(). * @post The radio state will be #RADIO_STATE_PLAYING. * @see radio_stop() */ int radio_start(radio_h radio); /** - * @brief Stops playing radio. + * @brief Stops playing the radio. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid state * @retval #RADIO_ERROR_INVALID_STATE Invalid radio state - * @pre The radio state must be either #RADIO_STATE_PLAYING by radio_start(). + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported + * @pre The radio state must be set to #RADIO_STATE_PLAYING by calling radio_start(). * @post The radio state will be #RADIO_STATE_READY. * @see radio_start() * @see radio_scan_start() @@ -189,87 +213,104 @@ int radio_start(radio_h radio); int radio_stop(radio_h radio); /** - * @brief Seeks up the effective frequency of radio, asynchronously. + * @brief Seeks up the effective frequency of the radio, asynchronously. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation * @retval #RADIO_ERROR_INVALID_STATE Invalid radio state - * @pre The radio state must be #RADIO_STATE_PLAYING by radio_start(). - * @post It invokes radio_seek_completed_cb() when seek completes. + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported + * @pre The radio state must be set to #RADIO_STATE_PLAYING by calling radio_start(). + * @post It invokes radio_seek_completed_cb() when the seek completes. * @see radio_seek_down() */ int radio_seek_up(radio_h radio,radio_seek_completed_cb callback, void *user_data ); /** - * @brief Seeks down the effective frequency of radio, asynchronously. + * @brief Seeks down the effective frequency of the radio, asynchronously. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation * @retval #RADIO_ERROR_INVALID_STATE Invalid radio state - * @pre The radio state must be #RADIO_STATE_PLAYING by radio_start(). - * @post It invokes radio_seek_completed_cb() when seek completes. + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported + * @pre The radio state must be set to #RADIO_STATE_PLAYING by calling radio_start(). + * @post It invokes radio_seek_completed_cb() when the seek completes. * @see radio_seek_up() */ int radio_seek_down(radio_h radio,radio_seek_completed_cb callback, void *user_data ); /** * @brief Sets the radio frequency. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio - * @param[in] percent The frequency to set [87500 ~ 108000] (kHz) - * @return 0 on success, otherwise a negative error value. + * @param[in] frequency The frequency to set [87500 ~ 108000] (kHz) + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported * @see radio_get_frequency() */ int radio_set_frequency(radio_h radio, int frequency); /** - * @brief Gets the current frequency of radio. + * @brief Gets the current frequency of the radio. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio * @param[out] frequency The current frequency [87500 ~ 108000] (kHz) - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported * @see radio_set_frequency() */ int radio_get_frequency(radio_h radio, int *frequency); /** - * @brief Gets the current signal strength of radio. + * @brief Gets the current signal strength of the radio. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio - * @param[out] strength The current signal strength [0 ~ 65535] (dbuV) - * @return 0 on success, otherwise a negative error value. + * @param[out] strength The current signal strength [-128 ~ 128] (dBm) + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported */ int radio_get_signal_strength(radio_h radio, int *strength); /** * @brief Starts scanning radio signals, asynchronously - * + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation * @retval #RADIO_ERROR_INVALID_STATE Invalid radio state - * @pre The radio state must be #RADIO_STATE_READY by either radio_create() or radio_stop(). - * @post The radio state will be #RADIO_STATE_SCANNING during searching. After scan is completed, radio state will be #RADIO_STATE_READY. + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported + * @pre The radio state must be set to #RADIO_STATE_READY by calling radio_create() or radio_stop(). + * @post The radio state will be #RADIO_STATE_SCANNING during a search. After the scan is completed, the radio state will be #RADIO_STATE_READY. * @post It invokes radio_scan_updated_cb() when the scan information updates. - * @post It invokes radio_scan_completed_cb() when scan completes, if you set a callback with radio_set_scan_completed_cb(). + * @post It invokes radio_scan_completed_cb() when the scan completes, if you set a callback with radio_set_scan_completed_cb(). * @see radio_scan_stop() * @see radio_set_scan_completed_cb() * @see radio_scan_completed_cb() @@ -278,15 +319,18 @@ int radio_scan_start(radio_h radio, radio_scan_updated_cb callback, void *user_d /** * @brief Stops scanning radio signals, asynchronously. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid state * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation * @retval #RADIO_ERROR_INVALID_STATE Invalid radio state - * @pre The radio state must be #RADIO_STATE_SCANNING by radio_scan_start(). + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported + * @pre The radio state must be set to #RADIO_STATE_SCANNING by calling radio_scan_start(). * @post It invokes radio_scan_stopped_cb() when the scan stops. * @post The radio state will be #RADIO_STATE_READY. * @see radio_scan_start() @@ -295,40 +339,49 @@ int radio_scan_stop(radio_h radio, radio_scan_stopped_cb callback, void *user_da /** * @brief Sets the radio's mute status. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @details If the mute status is @c true, no sounds will be played. If @c false, sounds will be played. Until this function is called, by default the radio is not muted. * @param[in] radio The handle to radio - * @param[in] muted New mute status: (@c true = mute, @c false = not muted) - * @return 0 on success, otherwise a negative error value. + * @param[in] muted The new mute status: (@c true = mute, @c false = not muted) + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported * @see radio_is_muted() */ int radio_set_mute(radio_h radio, bool muted); /** * @brief Gets the radio's mute status. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @details If the mute status is @c true, no sounds are played. If @c false, sounds are played. * @param[in] radio The handle to radio * @param[out] muted The current mute status: (@c true = mute, @c false = not muted) - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported * @see radio_set_mute() */ int radio_is_muted(radio_h radio, bool *muted); /** * @brief Registers a callback function to be invoked when the scan finishes. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation - * @post radio_scan_completed_cb() will be invoked + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported + * @post radio_scan_completed_cb() will be invoked. * @see radio_unset_scan_completed_cb() * @see radio_scan_completed_cb() */ @@ -336,25 +389,31 @@ int radio_set_scan_completed_cb(radio_h radio, radio_scan_completed_cb callback, /** * @brief Unregisters the callback function. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported * @see radio_set_scan_completed_cb() */ int radio_unset_scan_completed_cb(radio_h radio); /** * @brief Registers a callback function to be invoked when the radio is interrupted. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio * @param[in] callback The callback function to register * @param[in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation - * @post radio_interrupted_cb() will be invoked + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported + * @post radio_interrupted_cb() will be invoked. * @see radio_unset_interrupted_cb() * @see #radio_interrupted_code_e * @see radio_interrupted_cb() @@ -363,11 +422,14 @@ int radio_set_interrupted_cb(radio_h radio, radio_interrupted_cb callback, void /** * @brief Unregisters the callback function. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] radio The handle to radio - * @return 0 on success, otherwise a negative error value. + * @return @c 0 on success, + * otherwise a negative error value * @retval #RADIO_ERROR_NONE Successful * @retval #RADIO_ERROR_INVALID_PARAMETER Invalid parameter * @retval #RADIO_ERROR_INVALID_OPERATION Invalid operation + * @retval #RADIO_ERROR_NOT_SUPPORTED Not supported * @see radio_set_interrupted_cb() */ int radio_unset_interrupted_cb(radio_h radio); diff --git a/packaging/capi-media-radio.spec b/packaging/capi-media-radio.spec index cf417a8..d2856f1 100644 --- a/packaging/capi-media-radio.spec +++ b/packaging/capi-media-radio.spec @@ -1,30 +1,31 @@ #sbs-git:slp/api/radio capi-media-radio 0.1.0 59dddd8ea3de373c44c66ce2a298ca81240305a8 Name: capi-media-radio Summary: A Radio library in Tizen Native API -Version: 0.1.0 -Release: 9 -Group: TO_BE_FILLED -License: TO_BE_FILLED +Version: 0.1.1 +Release: 12 +Group: Multimedia/API +License: Apache-2.0 Source0: %{name}-%{version}.tar.gz BuildRequires: pkgconfig(dbus-glib-1) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(mm-radio) BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(capi-system-info) BuildRequires: cmake BuildRequires: gettext-devel %description -A Radio library in Tizen Native API +A Radio library in Tizen Native API. -%package devel -Summary: A Radio library in Tizen Native API (Developement) -Group: TO_BE_FILLED +%package devel +Summary: A Radio library in Tizen Native API (Development) +Group: TO_BE_FILLED Requires: %{name} = %{version}-%{release} %description devel -A Radio library in Tizen Native API (Developement) +A Radio library in Tizen Native API (Development). %prep %setup -q @@ -39,6 +40,10 @@ make %{?jobs:-j%jobs} %install rm -rf %{buildroot} %make_install +mkdir -p %{buildroot}/usr/share/license +mkdir -p %{buildroot}/opt/usr/devel +cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name} +cp test/radio_test %{buildroot}/opt/usr/devel %post @@ -46,10 +51,13 @@ rm -rf %{buildroot} %files +%manifest capi-media-radio.manifest %defattr(-,root,root,-) /usr/lib/libcapi-media-radio.so.* +/usr/share/license/%{name} +/opt/usr/devel/* -%files devel +%files devel %defattr(-,root,root,-) /usr/include/media/radio.h /usr/lib/pkgconfig/capi-media-radio.pc diff --git a/src/radio.c b/src/radio.c index 4b085b3..72aa388 100644 --- a/src/radio.c +++ b/src/radio.c @@ -11,7 +11,7 @@ * 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. +* limitations under the License. */ #include @@ -21,7 +21,7 @@ #include #include #include - +#include #ifdef LOG_TAG #undef LOG_TAG @@ -37,13 +37,16 @@ #define RADIO_INSTANCE_CHECK(radio) \ RADIO_CHECK_CONDITION(radio != NULL, RADIO_ERROR_INVALID_PARAMETER,"RADIO_ERROR_INVALID_PARAMETER") - + #define RADIO_STATE_CHECK(radio,expected_state) \ RADIO_CHECK_CONDITION(radio->state == expected_state,RADIO_ERROR_INVALID_STATE,"RADIO_ERROR_INVALID_STATE") #define RADIO_NULL_ARG_CHECK(arg) \ RADIO_CHECK_CONDITION(arg != NULL,RADIO_ERROR_INVALID_PARAMETER,"RADIO_ERROR_INVALID_PARAMETER") +#define RADIO_SUPPORT_CHECK(arg) \ + RADIO_CHECK_CONDITION(arg != false, RADIO_ERROR_NOT_SUPPORTED,"RADIO_ERROR_NOT_SUPPORTED") + /* * Internal Implementation */ @@ -51,6 +54,7 @@ static int __convert_error_code(int code, char *func_name) { int ret = RADIO_ERROR_NONE; char* msg="RADIO_ERROR_NONE"; + LOGI("[%s] Enter code :%x", __func__, code); switch(code) { case MM_ERROR_NONE: @@ -64,6 +68,7 @@ static int __convert_error_code(int code, char *func_name) break; case MM_ERROR_RADIO_NOT_INITIALIZED: case MM_ERROR_RADIO_NO_OP: + case MM_ERROR_RADIO_INVALID_STATE: ret = RADIO_ERROR_INVALID_STATE; msg = "RADIO_ERROR_INVALID_STATE"; break; @@ -80,22 +85,29 @@ static int __convert_error_code(int code, char *func_name) break; case MM_ERROR_RADIO_INTERNAL: case MM_ERROR_RADIO_RESPONSE_TIMEOUT: - case MM_ERROR_RADIO_DEVICE_NOT_OPENED: - case MM_ERROR_RADIO_DEVICE_NOT_FOUND: - default : ret= RADIO_ERROR_INVALID_OPERATION; msg = "RADIO_ERROR_INVALID_OPERATION"; - } + break; + case MM_ERROR_RADIO_DEVICE_NOT_FOUND: + ret = RADIO_ERROR_NOT_SUPPORTED; + msg = "RADIO_ERROR_NOT_SUPPORTED"; + break; + case MM_ERROR_RADIO_DEVICE_NOT_OPENED: + default : + ret= RADIO_ERROR_PERMISSION_DENIED; + msg = "RADIO_ERROR_PERMISSION_DENIED"; + } LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code); - return ret; + return ret; } static radio_state_e __convert_radio_state(MMRadioStateType state) { int converted_state = RADIO_STATE_READY; + LOGI("[%s] Enter state: %d", __func__, state); switch(state) { - + case MM_RADIO_STATE_PLAYING: converted_state = RADIO_STATE_PLAYING; break; @@ -108,28 +120,73 @@ static radio_state_e __convert_radio_state(MMRadioStateType state) converted_state = RADIO_STATE_READY; break; } + LOGI("[%s] Leave converted_state: %d", __func__, converted_state); return converted_state; } + +static radio_interrupted_code_e __convert_interrupted_code(int code) +{ + LOGI("[%s] Enter code: %d", __func__, code); + radio_interrupted_code_e ret = RADIO_INTERRUPTED_BY_RESOURCE_CONFLICT; + switch(code) + { + case MM_MSG_CODE_INTERRUPTED_BY_CALL_END: + case MM_MSG_CODE_INTERRUPTED_BY_ALARM_END: + case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_END: + case MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_END: + ret = RADIO_INTERRUPTED_COMPLETED; + break; + case MM_MSG_CODE_INTERRUPTED_BY_MEDIA: + case MM_MSG_CODE_INTERRUPTED_BY_OTHER_PLAYER_APP: + ret = RADIO_INTERRUPTED_BY_MEDIA; + break; + case MM_MSG_CODE_INTERRUPTED_BY_CALL_START: + ret = RADIO_INTERRUPTED_BY_CALL; + break; + case MM_MSG_CODE_INTERRUPTED_BY_EARJACK_UNPLUG: + ret = RADIO_INTERRUPTED_BY_EARJACK_UNPLUG; + break; + case MM_MSG_CODE_INTERRUPTED_BY_ALARM_START: + ret = RADIO_INTERRUPTED_BY_ALARM; + break; + case MM_MSG_CODE_INTERRUPTED_BY_NOTIFICATION_START: + ret = RADIO_INTERRUPTED_BY_NOTIFICATION; + break; + case MM_MSG_CODE_INTERRUPTED_BY_EMERGENCY_START: + ret = RADIO_INTERRUPTED_BY_EMERGENCY; + break; + case MM_MSG_CODE_INTERRUPTED_BY_RESUMABLE_MEDIA: + ret = RADIO_INTERRUPTED_BY_RESUMABLE_MEDIA; + break; + case MM_MSG_CODE_INTERRUPTED_BY_RESOURCE_CONFLICT: + default : + ret = RADIO_INTERRUPTED_BY_RESOURCE_CONFLICT; + break; + } + LOGE("[%s] interrupted code(%d) => ret(%d)",__FUNCTION__,code, ret); + return ret; +} + static int __set_callback(_radio_event_e type, radio_h radio, void* callback, void *user_data) { RADIO_INSTANCE_CHECK(radio); RADIO_NULL_ARG_CHECK(callback); - radio_s * handle = (radio_s *) radio; + radio_s * handle = (radio_s *) radio; handle->user_cb[type] = callback; handle->user_data[type] = user_data; LOGI("[%s] Event type : %d ",__FUNCTION__, type); - return RADIO_ERROR_NONE; + return RADIO_ERROR_NONE; } static int __unset_callback(_radio_event_e type, radio_h radio) { RADIO_INSTANCE_CHECK(radio); - radio_s * handle = (radio_s *) radio; + radio_s * handle = (radio_s *) radio; handle->user_cb[type] = NULL; handle->user_data[type] = NULL; LOGI("[%s] Event type : %d ",__FUNCTION__, type); - return RADIO_ERROR_NONE; + return RADIO_ERROR_NONE; } static int __msg_callback(int message, void *param, void *user_data) @@ -139,13 +196,13 @@ static int __msg_callback(int message, void *param, void *user_data) LOGI("[%s] Got message type : 0x%x" ,__FUNCTION__, message); switch(message) { - case MM_MESSAGE_RADIO_SCAN_INFO: + case MM_MESSAGE_RADIO_SCAN_INFO: if( handle->user_cb[_RADIO_EVENT_TYPE_SCAN_INFO] ) { ((radio_scan_updated_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_INFO])(msg->radio_scan.frequency,handle->user_data[_RADIO_EVENT_TYPE_SCAN_INFO]); - } - break; - case MM_MESSAGE_RADIO_SCAN_STOP: + } + break; + case MM_MESSAGE_RADIO_SCAN_STOP: if( handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP] ) { ((radio_scan_stopped_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_STOP])(handle->user_data[_RADIO_EVENT_TYPE_SCAN_STOP]); @@ -157,45 +214,78 @@ static int __msg_callback(int message, void *param, void *user_data) ((radio_scan_completed_cb)handle->user_cb[_RADIO_EVENT_TYPE_SCAN_FINISH])(handle->user_data[_RADIO_EVENT_TYPE_SCAN_FINISH]); } break; - case MM_MESSAGE_RADIO_SEEK_FINISH: + case MM_MESSAGE_RADIO_SEEK_FINISH: if( handle->user_cb[_RADIO_EVENT_TYPE_SEEK_FINISH] ) { ((radio_seek_completed_cb)handle->user_cb[_RADIO_EVENT_TYPE_SEEK_FINISH])(msg->radio_scan.frequency, handle->user_data[_RADIO_EVENT_TYPE_SEEK_FINISH]); - } + } break; - case MM_MESSAGE_STATE_INTERRUPTED: + case MM_MESSAGE_STATE_INTERRUPTED: if( handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT] ) { - ((radio_interrupted_cb)handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT])(msg->code,handle->user_data[_RADIO_EVENT_TYPE_INTERRUPT]); + ((radio_interrupted_cb)handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT])(__convert_interrupted_code(msg->code),handle->user_data[_RADIO_EVENT_TYPE_INTERRUPT]); } break; - case MM_MESSAGE_ERROR: + case MM_MESSAGE_READY_TO_RESUME: + if( handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT] ) + { + ((radio_interrupted_cb)handle->user_cb[_RADIO_EVENT_TYPE_INTERRUPT])(RADIO_INTERRUPTED_COMPLETED,handle->user_data[_RADIO_EVENT_TYPE_INTERRUPT]); + } + break; + case MM_MESSAGE_ERROR: __convert_error_code(msg->code,(char*)__FUNCTION__); break; - case MM_MESSAGE_RADIO_SCAN_START: + case MM_MESSAGE_RADIO_SCAN_START: LOGI("[%s] Scan Started"); break; - case MM_MESSAGE_STATE_CHANGED: + case MM_MESSAGE_STATE_CHANGED: handle->state = __convert_radio_state(msg->state.current); LOGI("[%s] State Changed --- from : %d , to : %d" ,__FUNCTION__, __convert_radio_state(msg->state.previous), handle->state); break; case MM_MESSAGE_RADIO_SEEK_START: LOGI("[%s] Seek Started", __FUNCTION__); - break; + break; default: break; } return 1; } +static int __radio_check_system_info_feature_supported() +{ + bool bValue = false; + int nRetVal = false; + + nRetVal = system_info_get_platform_bool("http://tizen.org/feature/fmradio", &bValue); + + if ( nRetVal != SYSTEM_INFO_ERROR_NONE ) + { + LOGE("[%s] SYSTEM_INFO_ERROR : ", __FUNCTION__); + return false; + } + + if ( false == bValue ) + { + LOGI("system_info_get_platform_bool returned Unsupported feature capability\n"); + } + else + { + LOGI("system_info_get_platform_bool returned Supported status feature\n"); + } + + return bValue; +} /* * Public Implementation */ int radio_create(radio_h *radio) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); radio_s * handle; + handle = (radio_s*)malloc( sizeof(radio_s)); if (handle != NULL) memset(handle, 0 , sizeof(radio_s)); @@ -207,15 +297,14 @@ int radio_create(radio_h *radio) int ret = mm_radio_create(&handle->mm_handle); if( ret != MM_ERROR_NONE) { - LOGE("[%s] RADIO_ERROR_INVALID_OPERATION(0x%08x)" ,__FUNCTION__,RADIO_ERROR_INVALID_OPERATION); free(handle); handle=NULL; - return RADIO_ERROR_INVALID_OPERATION; + return __convert_error_code(ret,(char*)__FUNCTION__); } else { *radio = (radio_h)handle; - + ret = mm_radio_set_message_callback(handle->mm_handle, __msg_callback, (void*)handle); if(ret != MM_ERROR_NONE) { @@ -234,6 +323,8 @@ int radio_create(radio_h *radio) int radio_destroy(radio_h radio) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); radio_s * handle = (radio_s *) radio; @@ -243,12 +334,11 @@ int radio_destroy(radio_h radio) { LOGW("[%s] Failed to unrealize (0x%x)" ,__FUNCTION__, ret); } - + ret = mm_radio_destroy(handle->mm_handle); if (ret!= MM_ERROR_NONE) { - LOGE("[%s] RADIO_ERROR_INVALID_OPERATION (0x%08x)" ,__FUNCTION__,RADIO_ERROR_INVALID_OPERATION); - return RADIO_ERROR_INVALID_OPERATION; + return __convert_error_code(ret,(char*)__FUNCTION__); } else { @@ -260,6 +350,8 @@ int radio_destroy(radio_h radio) int radio_get_state(radio_h radio, radio_state_e *state) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); RADIO_NULL_ARG_CHECK(state); radio_s * handle = (radio_s *) radio; @@ -280,9 +372,11 @@ int radio_get_state(radio_h radio, radio_state_e *state) int radio_start(radio_h radio) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); radio_s * handle = (radio_s *) radio; - RADIO_STATE_CHECK(handle,RADIO_STATE_READY); + RADIO_STATE_CHECK(handle,RADIO_STATE_READY); int ret = mm_radio_start(handle->mm_handle); if(ret != MM_ERROR_NONE) @@ -298,10 +392,12 @@ int radio_start(radio_h radio) int radio_stop(radio_h radio) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); radio_s * handle = (radio_s *) radio; - RADIO_STATE_CHECK(handle,RADIO_STATE_PLAYING); - + RADIO_STATE_CHECK(handle,RADIO_STATE_PLAYING); + int ret = mm_radio_stop(handle->mm_handle); if(ret != MM_ERROR_NONE) { @@ -316,10 +412,12 @@ int radio_stop(radio_h radio) int radio_seek_up(radio_h radio,radio_seek_completed_cb callback, void *user_data ) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); radio_s * handle = (radio_s *) radio; RADIO_STATE_CHECK(handle,RADIO_STATE_PLAYING); - + if(callback!=NULL) { __set_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio,callback,user_data); @@ -328,7 +426,7 @@ int radio_seek_up(radio_h radio,radio_seek_completed_cb callback, void *user_dat { __unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio); } - + int ret = mm_radio_seek(handle->mm_handle, MM_RADIO_SEEK_UP); if(ret != MM_ERROR_NONE) { @@ -342,10 +440,12 @@ int radio_seek_up(radio_h radio,radio_seek_completed_cb callback, void *user_dat int radio_seek_down(radio_h radio,radio_seek_completed_cb callback, void *user_data ) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); radio_s * handle = (radio_s *) radio; RADIO_STATE_CHECK(handle,RADIO_STATE_PLAYING); - + if(callback!=NULL) { __set_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio,callback,user_data); @@ -354,7 +454,7 @@ int radio_seek_down(radio_h radio,radio_seek_completed_cb callback, void *user_d { __unset_callback(_RADIO_EVENT_TYPE_SEEK_FINISH,radio); } - + int ret = mm_radio_seek(handle->mm_handle, MM_RADIO_SEEK_DOWN); if(ret != MM_ERROR_NONE) { @@ -368,6 +468,8 @@ int radio_seek_down(radio_h radio,radio_seek_completed_cb callback, void *user_d int radio_set_frequency(radio_h radio, int frequency) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); if(frequency < 87500 || frequency > 108000) { @@ -389,7 +491,10 @@ int radio_set_frequency(radio_h radio, int frequency) int radio_get_frequency(radio_h radio, int *frequency) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); + RADIO_NULL_ARG_CHECK(frequency); radio_s * handle = (radio_s *) radio; int freq; @@ -400,14 +505,17 @@ int radio_get_frequency(radio_h radio, int *frequency) } else { - *frequency = freq; + *frequency = freq; return RADIO_ERROR_NONE; } -} +} int radio_get_signal_strength(radio_h radio, int *strength) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); + RADIO_NULL_ARG_CHECK(strength); radio_s * handle = (radio_s *) radio; int _strength; @@ -425,9 +533,11 @@ int radio_get_signal_strength(radio_h radio, int *strength) int radio_scan_start(radio_h radio, radio_scan_updated_cb callback, void *user_data) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); radio_s * handle = (radio_s *) radio; - RADIO_STATE_CHECK(handle,RADIO_STATE_READY); + RADIO_STATE_CHECK(handle,RADIO_STATE_READY); if(callback!=NULL) { @@ -437,7 +547,7 @@ int radio_scan_start(radio_h radio, radio_scan_updated_cb callback, void *user_d { __unset_callback(_RADIO_EVENT_TYPE_SCAN_INFO,radio); } - + int ret = mm_radio_scan_start(handle->mm_handle); if(ret != MM_ERROR_NONE) { @@ -452,9 +562,11 @@ int radio_scan_start(radio_h radio, radio_scan_updated_cb callback, void *user_d int radio_scan_stop(radio_h radio, radio_scan_stopped_cb callback, void *user_data) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); radio_s * handle = (radio_s *) radio; - RADIO_STATE_CHECK(handle,RADIO_STATE_SCANNING); + RADIO_STATE_CHECK(handle,RADIO_STATE_SCANNING); if(callback!=NULL) { @@ -464,7 +576,7 @@ int radio_scan_stop(radio_h radio, radio_scan_stopped_cb callback, void *user_da { __unset_callback(_RADIO_EVENT_TYPE_SCAN_STOP,radio); } - + int ret = mm_radio_scan_stop(handle->mm_handle); if(ret != MM_ERROR_NONE) { @@ -480,6 +592,8 @@ int radio_scan_stop(radio_h radio, radio_scan_stopped_cb callback, void *user_da int radio_set_mute(radio_h radio, bool muted) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); radio_s * handle = (radio_s *) radio; @@ -497,6 +611,8 @@ int radio_set_mute(radio_h radio, bool muted) int radio_is_muted(radio_h radio, bool *muted) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); RADIO_INSTANCE_CHECK(radio); RADIO_NULL_ARG_CHECK(muted); radio_s * handle = (radio_s *) radio; @@ -506,20 +622,28 @@ int radio_is_muted(radio_h radio, bool *muted) int radio_set_scan_completed_cb(radio_h radio, radio_scan_completed_cb callback, void *user_data) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); return __set_callback(_RADIO_EVENT_TYPE_SCAN_FINISH,radio,callback,user_data); } int radio_unset_scan_completed_cb(radio_h radio) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); return __unset_callback(_RADIO_EVENT_TYPE_SCAN_FINISH,radio); } int radio_set_interrupted_cb(radio_h radio, radio_interrupted_cb callback, void *user_data) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); return __set_callback(_RADIO_EVENT_TYPE_INTERRUPT,radio,callback,user_data); } int radio_unset_interrupted_cb(radio_h radio) { + LOGI("[%s] Enter", __func__); + RADIO_SUPPORT_CHECK(__radio_check_system_info_feature_supported()); return __unset_callback(_RADIO_EVENT_TYPE_INTERRUPT,radio); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..4ffcb36 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,22 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(fw_test "${fw_name}-test") + +INCLUDE_DIRECTORIES(../include) +link_directories(${CMAKE_SOURCE_DIR}/../) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${fw_test} REQUIRED mm-radio) +FOREACH(flag ${${fw_test}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -pie") + +aux_source_directory(. sources) +FOREACH(src ${sources}) + GET_FILENAME_COMPONENT(src_name ${src} NAME_WE) + MESSAGE("${src_name}") + ADD_EXECUTABLE(${src_name} ${src}) + TARGET_LINK_LIBRARIES(${src_name} capi-media-radio ${${fw_test}_LDFLAGS}) +ENDFOREACH() + diff --git a/test/radio_test.c b/test/radio_test.c new file mode 100644 index 0000000..8886db6 --- /dev/null +++ b/test/radio_test.c @@ -0,0 +1,530 @@ +/* + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi , YoungHwan An + * + * 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. + * + */ + +/* testsuite for radio api */ +#include +#include + + +#include "radio.h" +#include "radio_test_type.h" +#include + +#define DEFAULT_TEST_FREQ 107700 +#define MENU_ITEM_MAX 19 +#define _MAX_INPUT_STRING_ 100 + + +/* test items...*/ +int __test_radio_init(void); +int __test_radio_listen_gorealra(void); +int __test_repeat_init_release(void); +int __test_repeat_start_stop(void); +int __test_repeat_seek(void); +int __test_repeat_whole(void); +int __test_manual_api_calling(void); +int __test_radio_hw_debug(void); + + +/* functions*/ +static void __print_menu(void); +static void __run_test(int key); + +int radio_rt_api_test(void); +static int __menu(void); +static void __call_api( int choosen ); +void __radio_seek_completed_cb(int frequency, void *user_data); +void __radio_scan_updated_cb(int freq, void *user_data); +void __radio_scan_stop_cb(void *user_data); +void __radio_set_scan_completed_cb(void *user_param); +void __radio_set_interrupted_cb(radio_interrupted_code_e code, void *user_param); + + + +/* list of tests*/ +test_item_t g_tests[100] = +{ + /* menu string : short string to be displayed to menu + description : detailed description + test function : a pointer to a actual test function + 0 : to be filled with return value of test function + */ + { + "init test", + "check radio init function", + __test_radio_init, + 0 + }, + + { + "listening gorealra", + "let's listen to the gorealra!", + __test_radio_listen_gorealra, + 0 + }, + + { + "repeat_init_release", + "repeat init and release and check if it working and memory usage increment", + __test_repeat_init_release, + 0 + }, + + { + "repeat_start_stop", + "repeat start and stop and check if it working and memory usage increment", + __test_repeat_start_stop, + 0 + }, + + { + "repeat_seek", + "repeat seek and check if it working and memory usage increment", + __test_repeat_seek, + 0 + }, + + { + "repeat_whole", + "repeat whole radio sequence and check if it working and memory usage increment", + __test_repeat_whole, + 0 + }, + + { + "manual api calling test", + "mapping each api to each test manu. just like other testsuite. try to reproduce the bugs with it.", + __test_manual_api_calling, + 0 + }, + + /* add tests here*/ + + /* NOTE : do not remove this last item */ + {"end", "", NULL, 0}, +}; + +int g_num_of_tests = 0; +static radio_h g_my_radio = 0; + +int main(int argc, char **argv) +{ + int key = 0; + + do { + __print_menu(); + + do { + key = getchar(); + + if ( key >= '0' && key <= '9') + { + __run_test( key - '0' ); + } + }while ( key == '\n' ); + if(key == 'Q' || key == 'q') + break; + }while(1); + + printf("radio test client finished\n"); + + return 0; +} + +void __print_menu(void) +{ + int i = 0; + + printf("\n\nFMRadio testing menu\n"); + printf("------------------------------------------\n"); + + for ( i = 0; g_tests[i].func; i++ ) + { + printf( "[%d] %s\n", i, g_tests[i].menu_string ); + } + printf("[q] quit\n"); + + g_num_of_tests = i; + + printf("Choose one : "); +} + +void __run_test(int key) +{ + int ret = 0; + + /* check index */ + printf("#tests : %d key : %d\n", g_num_of_tests, key); + if ( key >= g_num_of_tests || key < 0 ) + { + printf("unassigned key has pressed : %d\n", key); + return; + } + + /* display description*/ + printf( "excuting test : %s\n", g_tests[key].menu_string ); + printf( "description : %s\n", g_tests[key].description ); + + /* calling test function*/ + ret = g_tests[key].func(); + + g_tests[key].result = ret; + + if ( ret ) + { + printf( "TEST FAILED. ret code : %d\n", g_tests[key].result); + } + else + { + printf( "TEST SUCCEDED. ret code : %d\n", g_tests[key].result); + } +} + + +/* test items...*/ +int __test_radio_init(void) +{ + printf("%s\n", __FUNCTION__); + + int ret = RADIO_ERROR_NONE; + radio_h radio; + + RADIO_TEST__( radio_create(&radio); ) + RADIO_TEST__( radio_destroy(radio); ) + return ret; +} + +int __test_radio_listen_gorealra(void) +{ + printf("%s\n", __FUNCTION__); + + int ret = RADIO_ERROR_NONE; + radio_h radio; + + RADIO_TEST__( radio_create(&radio); ) + RADIO_TEST__( radio_set_frequency( radio, DEFAULT_TEST_FREQ ); ) + RADIO_TEST__( radio_start(radio); ) + usleep(5000 * 1000); + RADIO_TEST__( radio_stop(radio); ) + RADIO_TEST__( radio_destroy(radio); ) + return ret; +} + +int __test_repeat_init_release(void) +{ + printf("%s\n", __FUNCTION__); + + int ret = RADIO_ERROR_NONE; + int cnt = 0; + radio_h radio; + + while ( cnt < 1000 ) + { + RADIO_TEST__( radio_create(&radio); ) + RADIO_TEST__( radio_destroy(radio); ) + + cnt++; + + printf("%s : repeat count : %d\n", __FUNCTION__, cnt); + } + + return 0; +} + +int __test_repeat_start_stop(void) +{ + printf("%s\n", __FUNCTION__); + int ret = RADIO_ERROR_NONE; + int cnt = 0; + radio_h radio; + + RADIO_TEST__( radio_create(&radio); ) + RADIO_TEST__( radio_set_frequency( radio, DEFAULT_TEST_FREQ ); ) + + while(cnt < 10) + { + RADIO_TEST__( radio_start(radio); ) + usleep(2000 * 1000); + RADIO_TEST__( radio_stop(radio); ) + + cnt++; + + printf("%s : repeat count : %d\n", __FUNCTION__, cnt); + } + + return 0; +} + +int __test_repeat_seek(void) +{ + printf("__test_repeat_seek\n"); + return 0; +} + +int __test_repeat_whole(void) +{ + printf("__test_repeat_whole\n"); + return 0; +} + +int __test_manual_api_calling(void) +{ + + radio_rt_api_test(); + + return 0; +} + + +int radio_rt_api_test(void) +{ + while(1) + { + int choosen = 0; + + choosen = __menu(); + + if ( choosen == -1) + continue; + + if ( choosen == 0 ) + break; + + __call_api( choosen ); + } + + printf("radio test client finished\n"); + + return 0; +} + +int __menu(void) +{ + int menu_item = 0; + + printf("---------------------------------------------------------\n"); + printf("radio rt api test. try now!\n"); + printf("---------------------------------------------------------\n"); + printf("[1] radio_create\n"); + printf("[2] radio_destroy\n"); + printf("[3] radio_get_state\n"); + printf("[4] radio_start\n"); + printf("[5] radio_stop\n"); + printf("[6] radio_seek_up\n"); + printf("[7] radio_seek_down\n"); + printf("[8] radio_set_frequency(ex.107700)\n"); + printf("[9] radio_get_frequency\n"); + printf("[10] radio_signal_strength\n"); + printf("[11] radio_scan_start\n"); + printf("[12] radio_scan_stop\n"); + printf("[13] radio_set_mute\n"); + printf("[14] radio_is_muted\n"); + printf("[15] radio_set_scan_completed_cb\n"); + printf("[16] radio_unset_scan_completed_cb\n"); + printf("[17] radio_set_interrupted_cb\n"); + printf("[18] radio_unset_interrupted_cb\n"); + + printf("[0] quit\n"); + printf("---------------------------------------------------------\n"); + printf("choose one : "); + + if ( scanf("%d", &menu_item) == 0) + { + char temp[_MAX_INPUT_STRING_]; + if (scanf("%s", temp) ==0) + { + printf("Error while flushing the input buffer - but lets continue\n"); + } + return -1; + } + + + if ( menu_item > MENU_ITEM_MAX ) + menu_item = -1; + + return menu_item; +} + +void __call_api( int choosen ) +{ + int ret = RADIO_ERROR_NONE; + + switch( choosen ) + { + case 1: + { + RADIO_TEST__( radio_create( &g_my_radio ); ) + } + break; + + case 2: + { + RADIO_TEST__( radio_destroy( g_my_radio ); ) + g_my_radio = 0; + } + break; + + case 3: + { + radio_state_e state; + RADIO_TEST__( radio_get_state(g_my_radio, &state); ) + + printf("state : %d\n", state); + } + break; + + case 4: + { + RADIO_TEST__( radio_start(g_my_radio); ) + } + break; + + case 5: + { + RADIO_TEST__( radio_stop(g_my_radio); ) + } + break; + + case 6: + { + RADIO_TEST__( radio_seek_up(g_my_radio, __radio_seek_completed_cb, NULL); ) + + } + break; + + case 7: + { + RADIO_TEST__( radio_seek_down(g_my_radio, __radio_seek_completed_cb, NULL); ) + } + break; + + case 8: + { + int freq = 0; + printf("input freq : "); + if (scanf("%d", &freq) == 0) + return; + + RADIO_TEST__( radio_set_frequency(g_my_radio, freq); ) + } + break; + + case 9: + { + int freq = 0; + RADIO_TEST__( radio_get_frequency(g_my_radio, &freq ); ) + + printf("freq : %d\n", freq); + } + break; + + case 10: + { + int signal_strength = 0; + RADIO_TEST__( radio_get_signal_strength(g_my_radio, &signal_strength); ) + printf("signal strength is : %d \n", signal_strength); + } + break; + + case 11: + { + RADIO_TEST__( radio_scan_start(g_my_radio, &__radio_scan_updated_cb, NULL); ) + } + break; + + case 12: + { + RADIO_TEST__( radio_scan_stop(g_my_radio, &__radio_scan_stop_cb, NULL); ) + } + break; + + case 13: + { + int muted = 0; + printf("select one(0:UNMUTE/1:MUTE) : "); + if ( scanf("%d", &muted) == 0) + return; + RADIO_TEST__( radio_set_mute(g_my_radio, muted); ) + } + break; + + case 14: + { + bool muted = 0; + RADIO_TEST__( radio_is_muted(g_my_radio, &muted); ) + printf("muted : %d \n", muted); + } + break; + + + case 15: + { + RADIO_TEST__( radio_set_scan_completed_cb(g_my_radio, &__radio_set_scan_completed_cb, NULL); ) + } + break; + + case 16: + { + RADIO_TEST__( radio_unset_scan_completed_cb(g_my_radio); ) + } + break; + + case 17: + { + RADIO_TEST__( radio_set_interrupted_cb(g_my_radio, &__radio_set_interrupted_cb, NULL ); ) + } + break; + + case 18: + { + RADIO_TEST__( radio_unset_interrupted_cb(g_my_radio); ) + } + break; + + default: + break; + } +} + + +void __radio_seek_completed_cb(int frequency, void *user_data) +{ + printf("__radio_seek_completed_cb freq is %d\n" , frequency); +} +void __radio_scan_updated_cb(int frequency, void *user_param) +{ + printf("__radio_scan_updated_cb freq is %d\n" , frequency); +} + +void __radio_scan_stop_cb(void *user_param) +{ + printf("__radio_scan_stop_cb\n"); +} + +void __radio_set_scan_completed_cb(void *user_param) +{ + printf("__radio_scan_completed_cb\n"); +} + +void __radio_set_interrupted_cb(radio_interrupted_code_e code, void *user_param) +{ + printf("__radio_set_interrupted_cb\n"); +} + diff --git a/test/radio_test_type.h b/test/radio_test_type.h new file mode 100644 index 0000000..5363cdd --- /dev/null +++ b/test/radio_test_type.h @@ -0,0 +1,49 @@ +/* + * libmm-radio + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: JongHyuk Choi , YoungHwan An + * + * 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 MM_RADIO_TEST_TYPE_H_ +#define MM_RADIO_TEST_TYPE_H_ + +#include +#include + +typedef int (*test_function) (void); + +typedef struct __test_item +{ + char menu_string[80]; + char description[128]; + test_function func; + int result; +} test_item_t; + +#define RADIO_TEST__(x_test) \ + ret = x_test \ + if ( ! ret ) \ + { \ + printf("PASS : %s -- %s:%d\n", #x_test, __FILE__, __LINE__); \ + } \ + else \ + { \ + printf("FAIL : %s ERR-CODE : 0x%x -- %s:%d\n", #x_test, ret, __FILE__, __LINE__); \ + } + +#endif /* MM_RADIO_TEST_TYPE_H_ */ -- 2.7.4