From: jk7744.park Date: Tue, 8 Sep 2015 13:11:06 +0000 (+0900) Subject: tizen 2.3.1 release X-Git-Tag: submit/tizen_2.3.1/20150915.075915^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen_2.3.1;p=framework%2Fapi%2Fradio.git tizen 2.3.1 release --- 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 0000000..dad0dc9 Binary files /dev/null and b/doc/image/capi_media_radio_state_diagram.png differ 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_ */