M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions
@@ -0,0 +1,191 @@
/*
* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
import android.util.Log;
/**
*
* Class to be used when changing radio settings
* @hide
*/
public class FmConfig {
/**
* FMConfigure FM Radio band setting for US/Europe
*/
private static final int FM_US_BAND =0;
/**
* FMConfigure FM Radio band setting for US/Europe
*/
private static final int FM_EU_BAND =1;
/**
* FMConfigure FM Radio band setting for Japan
*/
private static final int FM_JAPAN_WIDE_BAND =2;
/**
* FMConfigure FM Radio band setting for Japan-Wideband
*/
private static final int FM_JAPAN_STANDARD_BAND =3;
/**
* FMConfigure FM Radio band setting for "User defined" band
*/
private static final int FM_USER_DEFINED_BAND =4;
private static final int V4L2_CID_PRIVATE_BASE =0x8000000;
private static final int V4L2_CID_PRIVATE_TAVARUA_REGION =V4L2_CID_PRIVATE_BASE + 7;
private static final int V4L2_CID_PRIVATE_TAVARUA_EMPHASIS =V4L2_CID_PRIVATE_BASE + 12;
private static final int V4L2_CID_PRIVATE_TAVARUA_RDS_STD =V4L2_CID_PRIVATE_BASE + 13;
private static final int V4L2_CID_PRIVATE_TAVARUA_SPACING =V4L2_CID_PRIVATE_BASE + 14;
private static final String TAG = "FmConfig";
private int mRadioBand;
/**
* FM pre-emphasis/de-emphasis
*
* Possible Values:
*
* FmTransceiver.FM_DE_EMP75,
* FmTransceiver.FM_DE_EMP50
*/
private int mEmphasis;
/**
* Channel spacing
*
* Possible Values:
*
* FmTransceiver.FM_CHSPACE_200_KHZ,
* FmTransceiver.FM_CHSPACE_100_KHZ,
* FmTransceiver.FM_CHSPACE_50_KHZ
*/
private int mChSpacing;
/**
* RDS standard type
*
* Possible Values:
*
* FmTransceiver.FM_RDS_STD_RBDS,
* FmTransceiver.FM_RDS_STD_RDS,
* FmTransceiver.FM_RDS_STD_NONE
*/
private int mRdsStd;
/**
* FM Frequency Band Lower Limit in KHz
*/
private int mBandLowerLimit;
/**
* FM Frequency Band Upper Limit in KHz
*/
private int mBandUpperLimit;
public int getRadioBand(){
return mRadioBand;
}
public void setRadioBand (int band){
mRadioBand = band;
}
public int getEmphasis(){
return mEmphasis;
}
public void setEmphasis (int emp){
mEmphasis = emp;
}
public int getChSpacing (){
return mChSpacing;
}
public void setChSpacing(int spacing) {
mChSpacing = spacing;
}
public int getRdsStd () {
return mRdsStd;
}
public void setRdsStd (int rdsStandard) {
mRdsStd = rdsStandard;
}
public int getLowerLimit(){
return mBandLowerLimit;
}
public void setLowerLimit(int lowLimit){
mBandLowerLimit = lowLimit;
}
public int getUpperLimit(){
return mBandUpperLimit;
}
public void setUpperLimit(int upLimit){
mBandUpperLimit = upLimit;
}
/*
* fmConfigure()
* This method call v4l2 private controls to set regional settings for the
* FM core
*/
protected static boolean fmConfigure (int fd, FmConfig configSettings) {
int re;
Log.d (TAG, "In fmConfigure");
re = FmReceiverJNI.setBandNative (fd, configSettings.getLowerLimit(), configSettings.getUpperLimit() );
if (configSettings.mRadioBand == FM_US_BAND)
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_REGION, FM_US_BAND );
else
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_REGION, FM_USER_DEFINED_BAND );
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_EMPHASIS, configSettings.getEmphasis());
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_RDS_STD, configSettings.getRdsStd() );
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_SPACING, configSettings.getChSpacing() );
/* setControlNative for V4L2_CID_PRIVATE_TAVARUA_REGION triggers the config change*/
if (re < 0)
return false;
return true;
}
}
File diff suppressed because it is too large Load Diff
+271
View File
@@ -0,0 +1,271 @@
/*
* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
class FmReceiverJNI {
/**
* General success
*/
static final int FM_JNI_SUCCESS = 0;
/**
* General failure
*/
static final int FM_JNI_FAILURE = -1;
/**
* native method: Open device
* @return The file descriptor of the device
*
*/
static native int acquireFdNative(String path);
/**
* native method:
* @param fd
* @param control
* @param field
* @return
*/
static native int audioControlNative(int fd, int control, int field);
/**
* native method: cancels search
* @param fd file descriptor of device
* @return May return
* {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int cancelSearchNative(int fd);
/**
* native method: release control of device
* @param fd file descriptor of device
* @return May return
* {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int closeFdNative(int fd);
/**
* native method: get frequency
* @param fd file descriptor of device
* @return Returns frequency in int form
*/
static native int getFreqNative(int fd);
/**
* native method: set frequency
* @param fd file descriptor of device
* @param freq freq to be set in int form
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*
*/
static native int setFreqNative(int fd, int freq);
/**
* native method: get v4l2 control
* @param fd file descriptor of device
* @param id v4l2 id to be retrieved
* @return Returns current value of the
* v4l2 control
*/
static native int getControlNative (int fd, int id);
/**
* native method: set v4l2 control
* @param fd file descriptor of device
* @param id v4l2 control to be set
* @param value value to be set
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int setControlNative (int fd, int id, int value);
/**
* native method: start search
* @param fd file descriptor of device
* @param dir search direction
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int startSearchNative (int fd, int dir);
/**
* native method: get buffer
* @param fd file descriptor of device
* @param buff[] buffer
* @param index index of the buffer to be retrieved
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int getBufferNative (int fd, byte buff[], int index);
/**
* native method: get RSSI value of the
* received signal
* @param fd file descriptor of device
* @return Returns signal strength in int form
* Signal value range from -120 to 10
*/
static native int getRSSINative (int fd);
/**
* native method: set FM band
* @param fd file descriptor of device
* @param low lower band
* @param high higher band
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int setBandNative (int fd, int low, int high);
/**
* native method: get lower band
* @param fd file descriptor of device
* @return Returns lower band in int form
*/
static native int getLowerBandNative (int fd);
/**
* native method: force Mono/Stereo mode
* @param fd file descriptor of device
* @param val force mono/stereo indicator
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int setMonoStereoNative (int fd, int val);
/**
* native method: get Raw RDS data
* @param fd file descriptor of device
* @param buff[] buffer
* @param count number of bytes to be read
* @return Returns number of bytes read
*/
static native int getRawRdsNative (int fd, byte buff[], int count);
/**
* native method: set v4l2 control
* @param fd file descriptor of device
* @param id v4l2 control to be set
* @param value value to be set
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int setNotchFilterNative(int fd, int id, boolean value);
/**
* native method: enable/disable Analog Mode
*/
static native int setAnalogModeNative(boolean value);
/**
* native method: Starts the RT transmission
* @param fd file descriptor of device
* @param buff[] buffer
* @param count number of bytes to be read
* @return Returns number of bytes read
*/
static native int startRTNative(int fd, String str, int count);
/**
* native method: Stops the RT transmission
* @param fd file descriptor of device
* @param buff[] buffer
* @param count number of bytes to be read
* @return Returns number of bytes read
*/
static native int stopRTNative(int fd);
/**
* native method: Starts the PS transmission
* @param fd file descriptor of device
* @param buff[] buffer
* @param count number of bytes to be read
* @return Returns number of bytes read
*/
static native int startPSNative(int fd, String str, int count);
/**
* native method: Stops the PS transmission
* @param fd file descriptor of device
* @param buff[] buffer
* @param count number of bytes to be read
*/
static native int stopPSNative(int fd);
/**
* native method: Sets the Programme type for transmission
* @param fd file descriptor of device
* @param pty program type to be transmited
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int setPTYNative (int fd, int pty);
/**
* native method: Sets the Programme Id for transmission
* @param fd file descriptor of device
* @param pty program Id to be transmited
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int setPINative (int fd, int pi);
/**
* native method: Sets the repeat count for Programme service
* transmission.
* @param fd file descriptor of device
* @param repeatcount number of times PS string to be transmited
* repeatedly.
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int setPSRepeatCountNative(int fd, int repeatCount);
/**
* native method: Sets the power level for the tramsmitter
* transmission.
* @param fd file descriptor of device
* @param powLevel is the level at which transmitter operates.
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int setTxPowerLevelNative(int fd, int powLevel);
/**
* native method: Sets the calibration
* @param fd file descriptor of device
* @return {@link #FM_JNI_SUCCESS}
* {@link #FM_JNI_FAILURE}
*/
static native int SetCalibrationNative(int fd);
}
@@ -0,0 +1,398 @@
/*
* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
import android.util.Log;
class FmRxControls
{
private boolean mStateStereo;
private boolean mStateMute;
private int mFreq;
static final int SEEK_FORWARD = 0;
static final int SEEK_BACKWARD = 1;
static final int SCAN_FORWARD = 2;
static final int SCAN_BACKWARD = 3;
static final int FM_DIGITAL_PATH = 0;
static final int FM_ANALOG_PATH = 1;
private int mSrchMode;
private int mScanTime;
private int mSrchDir;
private int mSrchListMode;
private int mPrgmType;
private int mPrgmId;
private static final String TAG = "FmRxControls";
/* V4l2 Controls */
private static final int V4L2_CID_PRIVATE_BASE = 0x8000000;
private static final int V4L2_CID_PRIVATE_TAVARUA_SRCHMODE = V4L2_CID_PRIVATE_BASE + 1;
private static final int V4L2_CID_PRIVATE_TAVARUA_SCANDWELL = V4L2_CID_PRIVATE_BASE + 2;
private static final int V4L2_CID_PRIVATE_TAVARUA_SRCHON = V4L2_CID_PRIVATE_BASE + 3;
private static final int V4L2_CID_PRIVATE_TAVARUA_STATE = V4L2_CID_PRIVATE_BASE + 4;
private static final int V4L2_CID_PRIVATE_TAVARUA_TRANSMIT_MODE = V4L2_CID_PRIVATE_BASE + 5;
private static final int V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK = V4L2_CID_PRIVATE_BASE + 6;
private static final int V4L2_CID_PRIVATE_TAVARUA_REGION = V4L2_CID_PRIVATE_BASE + 7;
private static final int V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH = V4L2_CID_PRIVATE_BASE + 8;
private static final int V4L2_CID_PRIVATE_TAVARUA_SRCH_PTY = V4L2_CID_PRIVATE_BASE + 9;
private static final int V4L2_CID_PRIVATE_TAVARUA_SRCH_PI = V4L2_CID_PRIVATE_BASE + 10;
private static final int V4L2_CID_PRIVATE_TAVARUA_SRCH_CNT = V4L2_CID_PRIVATE_BASE + 11;
private static final int V4L2_CID_PRIVATE_TAVARUA_EMPHASIS = V4L2_CID_PRIVATE_BASE + 12;
private static final int V4L2_CID_PRIVATE_TAVARUA_RDS_STD = V4L2_CID_PRIVATE_BASE + 13;
private static final int V4L2_CID_PRIVATE_TAVARUA_SPACING = V4L2_CID_PRIVATE_BASE + 14;
private static final int V4L2_CID_PRIVATE_TAVARUA_RDSON = V4L2_CID_PRIVATE_BASE + 15;
private static final int V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC = V4L2_CID_PRIVATE_BASE + 16;
private static final int V4L2_CID_PRIVATE_TAVARUA_LP_MODE = V4L2_CID_PRIVATE_BASE + 17;
private static final int V4L2_CID_PRIVATE_TAVARUA_IOVERC = V4L2_CID_PRIVATE_BASE + 24;
private static final int V4L2_CID_PRIVATE_TAVARUA_INTDET = V4L2_CID_PRIVATE_BASE + 25;
private static final int V4L2_CID_PRIVATE_TAVARUA_MPX_DCC = V4L2_CID_PRIVATE_BASE + 26;
private static final int V4L2_CID_PRIVATE_TAVARUA_AF_JUMP = V4L2_CID_PRIVATE_BASE + 27;
private static final int V4L2_CID_PRIVATE_TAVARUA_RSSI_DELTA = V4L2_CID_PRIVATE_BASE + 28;
private static final int V4L2_CID_PRIVATE_TAVARUA_HLSI = V4L2_CID_PRIVATE_BASE + 29;
private static final int V4L2_CID_PRIVATE_TAVARUA_SET_AUDIO_PATH = V4L2_CID_PRIVATE_BASE + 41;
private static final int V4L2_CTRL_CLASS_USER = 0x980000;
private static final int V4L2_CID_BASE = V4L2_CTRL_CLASS_USER | 0x900;
private static final int V4L2_CID_AUDIO_MUTE = V4L2_CID_BASE + 9;
/*
* Turn on FM Rx/Tx.
* Rx = 1 and Tx = 2
*/
public void fmOn(int fd, int device) {
int re;
FmReceiverJNI.setControlNative(fd, V4L2_CID_PRIVATE_TAVARUA_STATE, device );
setAudioPath(fd, false);
re = FmReceiverJNI.SetCalibrationNative(fd);
if (re != 0)
Log.d(TAG,"Calibration failed");
}
/*
* Turn off FM Rx/Tx
*/
public void fmOff(int fd){
FmReceiverJNI.setControlNative(fd, V4L2_CID_PRIVATE_TAVARUA_STATE, 0 );
}
/*
* set mute control
*/
public void muteControl(int fd, boolean on) {
if (on)
{
int err = FmReceiverJNI.setControlNative(fd, V4L2_CID_AUDIO_MUTE, 3 );
} else
{
int err = FmReceiverJNI.setControlNative(fd, V4L2_CID_AUDIO_MUTE, 0 );
}
}
/*
* Get Interference over channel
*/
public int IovercControl(int fd)
{
int ioverc = FmReceiverJNI.getControlNative(fd, V4L2_CID_PRIVATE_TAVARUA_IOVERC);
Log.d(TAG, "IOVERC value is : "+ioverc);
return ioverc;
}
/*
* Get IntDet
*/
public int IntDet(int fd)
{
int intdet = FmReceiverJNI.getControlNative(fd, V4L2_CID_PRIVATE_TAVARUA_INTDET);
Log.d(TAG, "IOVERC value is : "+intdet);
return intdet;
}
/*
* Get MPX_DCC
*/
public int Mpx_Dcc(int fd)
{
int mpx_dcc = FmReceiverJNI.getControlNative(fd, V4L2_CID_PRIVATE_TAVARUA_MPX_DCC);
Log.d(TAG, "MPX_DCC value is : " + mpx_dcc);
return mpx_dcc;
}
/*
* Set Hi-Low injection
*/
public int setHiLoInj(int fd, int inj)
{
int re = FmReceiverJNI.setControlNative(fd, V4L2_CID_PRIVATE_TAVARUA_HLSI, inj);
return re;
}
/*
* Get RMSSI Delta
*/
public int getRmssiDelta(int fd)
{
int rmssiDel = FmReceiverJNI.getControlNative(fd, V4L2_CID_PRIVATE_TAVARUA_RSSI_DELTA);
return rmssiDel;
}
/*
* Set RMSSI Delta
*/
public int setRmssiDel(int fd, int delta)
{
int re = FmReceiverJNI.setControlNative(fd, V4L2_CID_PRIVATE_TAVARUA_RSSI_DELTA, delta);
return re;
}
/*
* Set the audio path as analog/digital
*/
public int setAudioPath(int fd, boolean value)
{
int mode;
if (value)
mode = FM_ANALOG_PATH;
else
mode = FM_DIGITAL_PATH;
int re = FmReceiverJNI.setControlNative(fd, V4L2_CID_PRIVATE_TAVARUA_SET_AUDIO_PATH, mode);
return re;
}
/*
* Tune FM core to specified freq.
*/
public void setStation(int fd) {
Log.d(TAG, "** Tune Using: "+fd);
int ret = FmReceiverJNI.setFreqNative(fd, mFreq);
Log.d(TAG, "** Returned: "+ret);
}
/*
* Get currently tuned freq
*/
public int getTunedFrequency(int fd) {
int frequency = FmReceiverJNI.getFreqNative(fd);
Log.d(TAG, "getTunedFrequency: "+frequency);
return frequency;
}
public int getFreq (){
return mFreq;
}
public void setFreq (int f){
mFreq = f;
}
/*
* Start search list for auto presets
*/
public int searchStationList (int fd, int mode, int preset_num,
int dir, int pty )
{
int re;
/* set search mode. */
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_SRCHMODE, mode);
if (re != 0) {
return re;
}
/* set number of stations to be returned in the list */
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_SRCH_CNT, preset_num);
if (re != 0) {
return re;
}
// RDS search list?
if (pty > 0 ){
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_SRCH_PTY, pty);
}
if (re != 0) {
return re;
}
/* This triigers the search and once completed the FM core generates
* searchListComplete event */
re = FmReceiverJNI.startSearchNative (fd, dir );
if (re != 0) {
return re;
}
else {
return 0;
}
}
/* Read search list from buffer */
public int[] stationList (int fd)
{
int freq = 0;
int i=0;
int station_num = 0;
float real_freq = 0;
int [] stationList;
byte [] sList = new byte[100];
int tmpFreqByte1=0;
int tmpFreqByte2=0;
float lowBand;
lowBand = (float) (FmReceiverJNI.getLowerBandNative(fd) / 1000.00);
Log.d(TAG, "lowBand: " + lowBand);
FmReceiverJNI.getBufferNative(fd, sList, 0);
if ((int)sList[0] >0) {
station_num = (int)sList[0];
}
stationList = new int[station_num+1];
Log.d(TAG, "station_num: " + station_num);
for (i=0;i<station_num;i++) {
freq = 0;
Log.d(TAG, " Byte1 = " + sList[i*2+1]);
Log.d(TAG, " Byte2 = " + sList[i*2+2]);
tmpFreqByte1 = sList[i*2+1] & 0xFF;
tmpFreqByte2 = sList[i*2+2] & 0xFF;
Log.d(TAG, " tmpFreqByte1 = " + tmpFreqByte1);
Log.d(TAG, " tmpFreqByte2 = " + tmpFreqByte2);
freq = (tmpFreqByte1 & 0x03) << 8;
freq |= tmpFreqByte2;
Log.d(TAG, " freq: " + freq);
real_freq = (float)(freq * 0.05) + lowBand;//tuner.rangelow / FREQ_MUL;
Log.d(TAG, " real_freq: " + real_freq);
stationList[i] = (int)(real_freq*1000);
Log.d(TAG, " stationList: " + stationList[i]);
}
try {
// mark end of list
stationList[station_num] = 0;
}
catch (ArrayIndexOutOfBoundsException e) {
Log.d(TAG, "ArrayIndexOutOfBoundsException !!");
}
return stationList;
}
/* configure various search parameters and start search */
public void searchStations (int fd, int mode, int dwell,
int dir, int pty, int pi){
int re = 0;
Log.d(TAG, "Mode is " + mode + " Dwell is " + dwell);
Log.d(TAG, "dir is " + dir + " PTY is " + pty);
Log.d(TAG, "pi is " + pi + " id " + V4L2_CID_PRIVATE_TAVARUA_SRCHMODE);
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_SRCHMODE, mode);
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_SCANDWELL, dwell);
if (pty != 0)
{
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_SRCH_PTY, pty);
}
if (pi != 0)
{
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_SRCH_PI, pi);
}
re = FmReceiverJNI.startSearchNative (fd, dir );
}
/* force mono/stereo mode */
public int stereoControl(int fd, boolean stereo) {
if (stereo){
return FmReceiverJNI.setMonoStereoNative (fd, 1);
}
else {
return FmReceiverJNI.setMonoStereoNative (fd, 0);
}
}
public void searchRdsStations(int mode,int dwelling,
int direction, int RdsSrchPty, int RdsSrchPI){
}
/* public void searchStationList(int listMode,int direction,
int listMax,int pgmType) {
}
*/
/* cancel search in progress */
public void cancelSearch (int fd){
FmReceiverJNI.cancelSearchNative(fd);
}
/* Set LPM. This disables all FM core interrupts */
public int setLowPwrMode (int fd, boolean lpmOn){
int re=0;
if (lpmOn){
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_LP_MODE, 1);
}
else {
re = FmReceiverJNI.setControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_LP_MODE, 0);
}
return re;
}
/* get current powermode of the FM core. 1 for LPM and 0 Normal mode */
public int getPwrMode (int fd) {
int re=0;
re = FmReceiverJNI.getControlNative (fd, V4L2_CID_PRIVATE_TAVARUA_LP_MODE);
return re;
}
}
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2009, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
interface FmRxEvCallbacks {
public void FmRxEvEnableReceiver();
public void FmRxEvDisableReceiver();
public void FmRxEvRadioTuneStatus(int freq);
public void FmRxEvRdsLockStatus(boolean rdsAvail);
public void FmRxEvStereoStatus(boolean stereo);
public void FmRxEvServiceAvailable(boolean service);
public void FmRxEvSearchInProgress();
public void FmRxEvSearchCancelled();
public void FmRxEvSearchComplete(int freq);
public void FmRxEvSearchListComplete();
public void FmRxEvRdsGroupData();
public void FmRxEvRdsPsInfo();
public void FmRxEvRdsRtInfo();
public void FmRxEvRdsAfInfo();
}
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2009, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
/**
*
* Class to be implemented for event callbacks
* @hide
*/
public class FmRxEvCallbacksAdaptor implements FmRxEvCallbacks {
public void FmRxEvEnableReceiver() {};
public void FmRxEvDisableReceiver() {};
public void FmRxEvRadioTuneStatus(int freq) {};
public void FmRxEvRdsLockStatus(boolean rdsAvail) {};
public void FmRxEvStereoStatus(boolean stereo) {};
public void FmRxEvServiceAvailable(boolean service) {};
public void FmRxEvSearchInProgress() {};
public void FmRxEvSearchCancelled() {};
public void FmRxEvSearchComplete(int freq) {};
public void FmRxEvSearchListComplete() {};
public void FmRxEvRdsGroupData() {};
public void FmRxEvRdsPsInfo() {};
public void FmRxEvRdsRtInfo() {};
public void FmRxEvRdsAfInfo() {};
}
@@ -0,0 +1,220 @@
/*
* Copyright (c) 2009, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
import android.hardware.fmradio.FmReceiver;
import android.hardware.fmradio.FmTransceiver;
import android.util.Log;
class FmRxEventListner {
private final int EVENT_LISTEN = 1;
private enum FmRxEvents {
READY_EVENT,
TUNE_EVENT,
SEEK_COMPLETE_EVENT,
SCAN_NEXT_EVENT,
RAW_RDS_EVENT,
RT_EVENT,
PS_EVENT,
ERROR_EVENT,
BELOW_TH_EVENT,
ABOVE_TH_EVENT,
STEREO_EVENT,
MONO_EVENT,
RDS_AVAL_EVENT,
RDS_NOT_AVAL_EVENT,
TAVARUA_EVT_NEW_SRCH_LIST,
TAVARUA_EVT_NEW_AF_LIST
}
private Thread mThread;
private static final String TAG = "FMRadio";
public void startListner (final int fd, final FmRxEvCallbacks cb) {
/* start a thread and listen for messages */
mThread = new Thread(){
public void run(){
Log.d(TAG, "Starting listener " + fd);
while ((!Thread.currentThread().isInterrupted())) {
try {
int index = 0;
int state = 0;
byte []buff = new byte[64];
int eventCount = FmReceiverJNI.getBufferNative (fd, buff, EVENT_LISTEN);
if (eventCount >= 0)
Log.d(TAG, "Received event. Count: " + eventCount);
else {
Log.d(TAG, "Exiting the FM Rx Event Listener");
break;
}
for ( index = 0; index < eventCount; index++ ) {
Log.d(TAG, "Received <" +buff[index]+ ">" );
switch(buff[index]){
case 0:
Log.d(TAG, "Got READY_EVENT");
if(FmTransceiver.getFMPowerState() == FmTransceiver.subPwrLevel_FMRx_Starting) {
/*Set the state as FMRxOn */
FmTransceiver.setFMPowerState(FmTransceiver.FMState_Rx_Turned_On);
Log.v(TAG, "RxEvtList: CURRENT-STATE : FMRxStarting ---> NEW-STATE : FMRxOn");
cb.FmRxEvEnableReceiver();
}
else if (FmTransceiver.getFMPowerState() == FmTransceiver.subPwrLevel_FMTurning_Off) {
/*Set the state as FMOff */
FmTransceiver.setFMPowerState(FmTransceiver.FMState_Turned_Off);
Log.v(TAG, "RxEvtList: CURRENT-STATE : FMTurningOff ---> NEW-STATE : FMOff");
cb.FmRxEvDisableReceiver();
}
break;
case 1:
Log.d(TAG, "Got TUNE_EVENT");
cb.FmRxEvRadioTuneStatus(FmReceiverJNI.getFreqNative(fd));
break;
case 2:
Log.d(TAG, "Got SEEK_COMPLETE_EVENT");
state = FmReceiver.getSearchState();
switch(state) {
case FmTransceiver.subSrchLevel_SeekInPrg :
case FmTransceiver.subSrchLevel_ScanInProg:
Log.v(TAG, "Current state is " + state);
FmReceiver.setSearchState(FmTransceiver.subSrchLevel_SrchComplete);
Log.v(TAG, "RxEvtList: CURRENT-STATE : Search ---> NEW-STATE : FMRxOn");
cb.FmRxEvSearchComplete(FmReceiverJNI.getFreqNative(fd));
break;
case FmTransceiver.subSrchLevel_SrchAbort:
Log.v(TAG, "Current state is SRCH_ABORTED");
Log.v(TAG, "Aborting on-going search command...");
FmReceiver.setSearchState(FmTransceiver.subSrchLevel_SrchComplete);
Log.v(TAG, "RxEvtList: CURRENT-STATE : Search ---> NEW-STATE : FMRxOn");
cb.FmRxEvSearchCancelled();
break;
}
break;
case 3:
Log.d(TAG, "Got SCAN_NEXT_EVENT");
cb.FmRxEvSearchInProgress();
break;
case 4:
Log.d(TAG, "Got RAW_RDS_EVENT");
cb.FmRxEvRdsGroupData();
break;
case 5:
Log.d(TAG, "Got RT_EVENT");
cb.FmRxEvRdsRtInfo();
break;
case 6:
Log.d(TAG, "Got PS_EVENT");
cb.FmRxEvRdsPsInfo();
break;
case 7:
Log.d(TAG, "Got ERROR_EVENT");
break;
case 8:
Log.d(TAG, "Got BELOW_TH_EVENT");
cb.FmRxEvServiceAvailable (false);
break;
case 9:
Log.d(TAG, "Got ABOVE_TH_EVENT");
cb.FmRxEvServiceAvailable(true);
break;
case 10:
Log.d(TAG, "Got STEREO_EVENT");
cb.FmRxEvStereoStatus (true);
break;
case 11:
Log.d(TAG, "Got MONO_EVENT");
cb.FmRxEvStereoStatus (false);
break;
case 12:
Log.d(TAG, "Got RDS_AVAL_EVENT");
cb.FmRxEvRdsLockStatus (true);
break;
case 13:
Log.d(TAG, "Got RDS_NOT_AVAL_EVENT");
cb.FmRxEvRdsLockStatus (false);
break;
case 14:
Log.d(TAG, "Got NEW_SRCH_LIST");
state = FmReceiver.getSearchState();
switch(state) {
case FmTransceiver.subSrchLevel_SrchListInProg:
Log.v(TAG, "FmRxEventListener: Current state is AUTO_PRESET_INPROGRESS");
FmReceiver.setSearchState(FmTransceiver.subSrchLevel_SrchComplete);
Log.v(TAG, "RxEvtList: CURRENT-STATE : Search ---> NEW-STATE : FMRxOn");
cb.FmRxEvSearchListComplete ();
break;
case FmTransceiver.subSrchLevel_SrchAbort:
Log.v(TAG, "Current state is SRCH_ABORTED");
Log.v(TAG, "Aborting on-going SearchList command...");
FmReceiver.setSearchState(FmTransceiver.subSrchLevel_SrchComplete);
Log.v(TAG, "RxEvtList: CURRENT-STATE : Search ---> NEW-STATE : FMRxOn");
cb.FmRxEvSearchCancelled();
break;
}
break;
case 15:
Log.d(TAG, "Got NEW_AF_LIST");
cb.FmRxEvRdsAfInfo();
break;
default:
Log.d(TAG, "Unknown event");
break;
}
}//end of for
} catch ( Exception ex ) {
Log.d( TAG, "RunningThread InterruptedException");
Thread.currentThread().interrupt();
}
}
}
};
mThread.start();
}
public void stopListener(){
//mThread.stop();
//Thread stop is deprecate API
//Interrupt the thread and check for the thread status
// and return from the run() method to stop the thread
//properly
Log.d( TAG, "stopping the Listener\n");
if( mThread != null ) {
mThread.interrupt();
}
}
}
@@ -0,0 +1,213 @@
/*
* Copyright (c) 2009, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
import android.util.Log;
/**
*
* @hide
*/
public class FmRxRdsData {
private String mRadioText;
private String mPrgmServices;
private int mPrgmId;
private int mPrgmType;
private int mFd;
/* V4L2 controls */
private static final int V4L2_CID_PRIVATE_BASE = 0x8000000;
private static final int V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK = V4L2_CID_PRIVATE_BASE + 6;
private static final int V4L2_CID_PRIVATE_TAVARUA_RDSON = V4L2_CID_PRIVATE_BASE + 15;
private static final int V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC = V4L2_CID_PRIVATE_BASE + 16;
private static final int V4L2_CID_PRIVATE_TAVARUA_RDSD_BUF = V4L2_CID_PRIVATE_BASE + 19;
private static final int V4L2_CID_PRIVATE_TAVARUA_PSALL = V4L2_CID_PRIVATE_BASE + 20;
private static final int V4L2_CID_PRIVATE_TAVARUA_AF_JUMP = V4L2_CID_PRIVATE_BASE + 27;
private static final int RDS_GROUP_RT = 0x1;
private static final int RDS_GROUP_PS = 1 << 1;
private static final int RDS_GROUP_AF = 1 << 2;
private static final int RDS_AF_AUTO = 1 << 6;
private static final int RDS_PS_ALL = 1 << 4;
private static final int RDS_AF_JUMP = 0x1;
private static final String LOGTAG="FmRxRdsData";
public FmRxRdsData (int fd)
{
mFd = fd;
}
/* turn on/off RDS processing */
public int rdsOn (boolean on)
{
int ret;
Log.d(LOGTAG, "In rdsOn: RDS is " + on);
if (on) {
ret = FmReceiverJNI.setControlNative (mFd, V4L2_CID_PRIVATE_TAVARUA_RDSON, 1);
}
else {
ret = FmReceiverJNI.setControlNative (mFd, V4L2_CID_PRIVATE_TAVARUA_RDSON, 0);
}
return ret;
}
/* process raw RDS group filtering */
public int rdsGrpOptions (int grpMask, int buffSize, boolean rdsFilter)
{
int rdsFilt;
int re;
byte rds_group_mask = (byte)FmReceiverJNI.getControlNative(mFd, V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC);
rds_group_mask &= 0xFE;
if (rdsFilter)
rdsFilt = 1;
else
rdsFilt = 0;
rds_group_mask |= rdsFilt;
re = FmReceiverJNI.setControlNative(mFd, V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC, rds_group_mask);
if (re != 0)
return re;
re = FmReceiverJNI.setControlNative(mFd, V4L2_CID_PRIVATE_TAVARUA_RDSD_BUF, buffSize);
if (re != 0)
return re;
re = FmReceiverJNI.setControlNative(mFd, V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK, grpMask);
return re;
}
/* configure RT/PS/AF RDS processing */
public int rdsOptions (int rdsMask)
{
int re=0;
byte rds_group_mask = (byte)FmReceiverJNI.getControlNative(mFd, V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC);
byte rdsFilt = 0;
int psAllVal=rdsMask & RDS_PS_ALL;
Log.d(LOGTAG, "In rdsOptions: rdsMask: " + rdsMask);
rds_group_mask &= 0xC7;
rds_group_mask |= ((rdsMask & 0x07) << 3);
re = FmReceiverJNI.setControlNative(mFd, V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC, rds_group_mask);
re = FmReceiverJNI.setControlNative(mFd, V4L2_CID_PRIVATE_TAVARUA_PSALL, psAllVal >> 4 );
return re;
}
/* Enable auto seek to alternate frequency */
public int enableAFjump(boolean AFenable)
{
int re;
int rds_group_mask = 0;
Log.d(LOGTAG, "In enableAFjump: AFenable : " + AFenable);
rds_group_mask = FmReceiverJNI.getControlNative(mFd, V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC);
Log.d(LOGTAG, "Currently set rds_group_mask : " + rds_group_mask);
if (AFenable)
re = FmReceiverJNI.setControlNative(mFd ,V4L2_CID_PRIVATE_TAVARUA_AF_JUMP, 1);
else
re = FmReceiverJNI.setControlNative(mFd, V4L2_CID_PRIVATE_TAVARUA_AF_JUMP, 0);
rds_group_mask = FmReceiverJNI.getControlNative(mFd, V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC);
if (AFenable)
Log.d(LOGTAG, "After enabling the rds_group_mask is : " + rds_group_mask);
else
Log.d(LOGTAG, "After disabling the rds_group_mask is : " + rds_group_mask);
return re;
}
public String getRadioText () {
return mRadioText;
}
public void setRadioText (String x) {
mRadioText = x;
}
public String getPrgmServices () {
return mPrgmServices;
}
public void setPrgmServices (String x) {
mPrgmServices = x;
}
public int getPrgmId () {
return mPrgmId;
}
public void setPrgmId (int x) {
mPrgmId = x;
}
public int getPrgmType () {
return mPrgmType;
}
public void setPrgmType (int x) {
mPrgmType = x;
}
}
@@ -0,0 +1,622 @@
/*
* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
import android.util.Log;
/** <code>FmTransceiver</code> is the superclass of classes
* <code>FmReceiver</code> and <code>FmTransmitter</code>
* @hide
*/
public class FmTransceiver
{
/* Primary FM States :
* FM will be in one of the 4 states at any point of time
* '0' - FMState_Turned_Off
* '1' - FMState_Rx_Turned_On
* '2' - FMState_Tx_Turned_On
* '3' - FMState_Srch_InProg
*/
public static final int FMState_Turned_Off = 0;
public static final int FMState_Rx_Turned_On = 1;
public static final int FMState_Tx_Turned_On = 2;
public static final int FMState_Srch_InProg = 3;
/* Intermediate FM power levels */
public static final int subPwrLevel_FMRx_Starting = 4;
public static final int subPwrLevel_FMTx_Starting = 5;
public static final int subPwrLevel_FMTurning_Off = 6;
/* Intermediate FM search levels :
* These are the sub-levels of FM Search operations : seek/scan/auto-preset.
* Used internally for distinguishing between the various search operations.
*/
public static final int subSrchLevel_SeekInPrg = 0;
public static final int subSrchLevel_ScanInProg = 1;
public static final int subSrchLevel_SrchListInProg = 2;
public static final int subSrchLevel_SrchComplete = 3;
public static final int subSrchLevel_SrchAbort = 4;
/* Holds the current state of the FM device */
public static int FMState = FMState_Turned_Off;
/**
* FMConfigure FM Radio band setting for US/Europe
*/
public static final int FM_US_BAND =0;
/**
* FMConfigure FM Radio band setting for US/Europe
*/
public static final int FM_EU_BAND =1;
/**
* FMConfigure FM Radio band setting for Japan
*/
public static final int FM_JAPAN_WIDE_BAND =2;
/**
* FMConfigure FM Radio band setting for Japan-Wideband
*/
public static final int FM_JAPAN_STANDARD_BAND =3;
/**
* FMConfigure FM Radio band setting for "User defined" band
*/
public static final int FM_USER_DEFINED_BAND =4;
/**
* FM channel spacing settings = 200KHz
*/
public static final int FM_CHSPACE_200_KHZ =0;
/**
* FM channel spacing settings = 100KHz
*/
public static final int FM_CHSPACE_100_KHZ =1;
/**
* FM channel spacing settings = 50KHz
*/
public static final int FM_CHSPACE_50_KHZ =2;
/**
* FM de-emphasis/pre-emphasis settings = 75KHz
*/
public static final int FM_DE_EMP75 = 0;
/**
* FM de-emphasis/pre-emphasis settings = 50KHz
*/
public static final int FM_DE_EMP50 = 1;
/**
* RDS standard type: RBDS (North America)
*/
public static final int FM_RDS_STD_RBDS =0;
/**
* RDS standard type: RDS (Rest of the world)
*/
public static final int FM_RDS_STD_RDS =1;
/**
* RDS standard type: No RDS
*/
public static final int FM_RDS_STD_NONE =2;
protected static final int FM_RX =1;
protected static final int FM_TX =2;
private final int READY_EVENT = 0x01;
private final int TUNE_EVENT = 0x02;
private final int RDS_EVENT = 0x08;
private final int MUTE_EVENT = 0x04;
private final int SEEK_COMPLETE_EVENT = 0x03;
private static final int V4L2_CID_PRIVATE_BASE = 0x8000000;
private static final int V4L2_CID_PRIVATE_TAVARUA_ANTENNA = V4L2_CID_PRIVATE_BASE + 18;
private static final int V4L2_CID_PRIVATE_TAVARUA_SET_NOTCH_FILTER = V4L2_CID_PRIVATE_BASE + 40;
private final String TAG = "FmTransceiver";
private final String V4L2_DEVICE = "/dev/radio0";
protected static int sFd;
protected FmRxControls mControl;
protected int mPowerMode;
protected FmRxEventListner mRxEvents;
protected FmRxRdsData mRdsData;
protected FmTxEventListner mTxEvents;
public static final int ERROR = -1;
/*==============================================================
FUNCTION: acquire
==============================================================*/
/**
* Allows access to the V4L2 FM device.
*
* This synchronous call allows a client to use the V4L2 FM
* device. This must be the first call issued by the client
* before any receiver interfaces can be used.
*
* This call also powers up the FM Module.
*
* @param device String that is path to radio device
*
* @return true if V4L2 FM device acquired, false if V4L2 FM
* device could not be acquired, possibly acquired by
* other client
* @see #release
*
*/
protected boolean acquire(String device){
boolean bStatus = true;
if (sFd <= 0) { // if previous open fails fd will be -ve.
sFd = FmReceiverJNI.acquireFdNative(V4L2_DEVICE);
if (sFd > 0) {
Log.d(TAG, "Opened "+ sFd);
bStatus = true;
}
else {
Log.d(TAG, "Fail to Open "+ sFd);
bStatus = false;
}
}
else {
Log.d(TAG, "Already Opened:" + sFd);
/*This should be case
* Where User try to opne the device
* secondtime.
* Case where Tx and Rx try to
* acquire the device
*/
bStatus = false;
}
return (bStatus);
}
/*==============================================================
FUNCTION: release
==============================================================*/
/**
* Releases access to the V4L2 FM device.
* <p>
* This synchronous call allows a client to release control of
* V4L2 FM device. This function should be called when the FM
* device is no longer needed. This should be the last call
* issued by the FM client. Once called, the client must call
* #acquire to re-aquire the V4L2 device control before the
* FM device can be used again.
* <p>
* Before the client can release control of the FM receiver
* interface, it must disable the FM receiver, if the client
* enabled it, and unregister any registered callback. If the
* client has ownership of the receiver, it will automatically
* be returned to the system.
* <p>
* This call also powers down the FM Module.
* <p>
* @param device String that is path to radio device
* @return true if V4L2 FM device released, false if V4L2 FM
* device could not be released
* @see #acquire
*/
protected boolean release(String device) {
if (sFd!=0)
{
FmReceiverJNI.closeFdNative(sFd);
sFd = 0;
Log.d(TAG, "Turned off: " + sFd);
} else
{
Log.d(TAG, "Error turning off");
}
return true;
}
/*==============================================================
FUNCTION: registerClient
==============================================================*/
/**
* Registers a callback for FM receiver event notifications.
* <p>
* This is a synchronous call used to register for event
* notifications from the FM receiver driver. Since the FM
* driver performs some tasks asynchronously, this function
* allows the client to receive information asynchronously.
* <p>
* When calling this function, the client must pass a callback
* function which will be used to deliver asynchronous events.
* The argument callback must be a non-NULL value. If a NULL
* value is passed to this function, the registration will
* fail.
* <p>
* The client can choose which events will be sent from the
* receiver driver by simply implementing functions for events
* it wishes to receive.
* <p>
*
* @param callback the callback to handle the events events
* from the FM receiver.
* @return true if Callback registered, false if Callback
* registration failed.
*
* @see #acquire
* @see #unregisterClient
*
*/
public boolean registerClient(FmRxEvCallbacks callback){
boolean bReturnStatus = false;
if (callback!=null)
{
mRxEvents.startListner(sFd, callback);
bReturnStatus = true;
} else
{
Log.d(TAG, "Null, do nothing");
}
return bReturnStatus;
}
/*==============================================================
FUNCTION: unregisterClient
==============================================================*/
/**
* Unregisters a client's event notification callback.
* <p>
* This is a synchronous call used to unregister a client's
* event callback.
* <p>
* @return true always.
*
* @see #acquire
* @see #release
* @see #registerClient
*
*/
public boolean unregisterClient () {
mRxEvents.stopListener();
return true;
}
/*==============================================================
FUNCTION: registerTransmitClient
==============================================================*/
/**
* Registers a callback for FM Transmitter event
* notifications.
* <p>
* This is a synchronous call used to register for event
* notifications from the FM Transmitter driver. Since the FM
* driver performs some tasks asynchronously, this function
* allows the client to receive information asynchronously.
* <p>
* When calling this function, the client must pass a callback
* function which will be used to deliver asynchronous events.
* The argument callback must be a non-NULL value. If a NULL
* value is passed to this function, the registration will
* fail.
* <p>
* The client can choose which events will be sent from the
* receiver driver by simply implementing functions for events
* it wishes to receive.
* <p>
*
* @param callback the callback to handle the events events
* from the FM Transmitter.
* @return true if Callback registered, false if Callback
* registration failed.
*
* @see #acquire
* @see #unregisterTransmitClient
*
*/
public boolean registerTransmitClient( FmTransmitterCallbacks callback){
boolean bReturnStatus = false;
if (callback!=null)
{
mTxEvents.startListner(sFd, callback);
bReturnStatus = true;
} else
{
Log.d(TAG, "Null, do nothing");
}
return bReturnStatus;
}
/*==============================================================
FUNCTION: unregisterTransmitClient
==============================================================*/
/**
* Unregisters Transmitter event notification callback.
* <p>
* This is a synchronous call used to unregister a Transmitter
* client's event callback.
* <p>
* @return true always.
*
* @see #acquire
* @see #release
* @see #registerTransmitClient
*
*/
public boolean unregisterTransmitClient () {
mTxEvents.stopListener();
return true;
}
/*==============================================================
FUNCTION: enable
==============================================================*/
/**
* Initializes the FM device.
* <p>
* This is a synchronous call is used to initialize the FM
* tranceiver. If already initialized this function will
* intialize the tranceiver with default settings. Only after
* successfully calling this function can many of the FM device
* interfaces be used.
* <p>
* When enabling the receiver, the client must also provide
* the regional settings in which the receiver will operate.
* These settings (included in configSettings) are typically
* used for setting up the FM receiver for operating in a
* particular geographical region. These settings can be
* changed after the FM driver is enabled through the use of
* the function #configure.
* <p>
* This call can only be issued by the owner of an FM
* receiver. To issue this call, the client must first
* successfully call #acquire.
* <p>
* @param configSettings the settings to be applied when
* turning on the radio
* @return true if Initialization succeeded, false if
* Initialization failed.
* @see #registerClient
* @see #disable
*
*/
public boolean enable (FmConfig configSettings, int device){
//Acquire the deviceon Enable
if( !acquire("/dev/radio0")){
return false;
}
Log.d(TAG, "turning on " + device);
mControl.fmOn(sFd, device);
Log.d(TAG, "Calling fmConfigure");
return FmConfig.fmConfigure (sFd, configSettings);
}
/*==============================================================
FUNCTION: disable
==============================================================*/
/**
* Disables the FM Device.
* <p>
* This is a synchronous call used to disable the FM
* device. This function is expected to be used when the
* client no longer requires use of the FM device. Once
* called, most functionality offered by the FM device will be
* disabled until the client re-enables the device again via
* #enable.
* <p>
* @return true if disabling succeeded, false if disabling
* failed.
* <p>
* @see #enable
* @see #registerClient
*/
public boolean disable(){
mControl.fmOff(sFd);
/* Release the device on Disable */
release("/dev/radio0");
return true;
}
/*==============================================================
FUNCTION: configure
==============================================================*/
/**
* Reconfigures the device's regional settings
* (FM Band, De-Emphasis, Channel Spacing, RDS/RBDS mode).
* <p>
* This is a synchronous call used to reconfigure settings on
* the FM device. Included in the passed structure are
* settings which typically differ from one geographical
* region to another.
* <p>
* @param configSettings Contains settings for the FM radio
* (FM band, De-emphasis, channel
* spacing, RDS/RBDS mode)
* <p>
* @return true if configure succeeded, false if
* configure failed.
*/
public boolean configure(FmConfig configSettings){
boolean status=true;
int lowerFreq = configSettings.getLowerLimit();
Log.d(TAG, "fmConfigure");
status = FmConfig.fmConfigure (sFd, configSettings);
status = setStation (lowerFreq);
return status;
}
/*==============================================================
FUNCTION: setStation
==============================================================*/
/**
* Tunes the FM device to the specified FM frequency.
* <p>
* This method tunes the FM device to a station specified by the
* provided frequency. Only valid frequencies within the band
* set by enable or configure can be tuned by this function.
* Attempting to tune to frequencies outside of the set band
* will result in an error.
* <p>
* Once tuning to the specified frequency is completed, the
* event callback FmRxEvRadioTuneStatus will be called.
*
* @param frequencyKHz Frequency (in kHz) to be tuned
* (Example: 96500 = 96.5Mhz)
* @return true if setStation call was placed successfully,
* false if setStation failed.
*/
public boolean setStation (int frequencyKHz) {
mControl.setFreq(frequencyKHz);
mControl.setStation(sFd);
return true;
}
/*==============================================================
FUNCTION: SetNotchFilter
==============================================================*/
/**
* Sets the desired notch filter for WAN avoidance.
* <p>
* This method sets the required Notch filter based on the current
* WAN band frequency to achieve the FM-WAN concurrency.
* Application should listen to Data call events and call the function
* on every data call connection set-u, to achieve the FM-WAN concurrency.
*
*/
public void setNotchFilter(boolean value) {
FmReceiverJNI.setNotchFilterNative(sFd, V4L2_CID_PRIVATE_TAVARUA_SET_NOTCH_FILTER, value);
}
/*==============================================================
FUNCTION: SetAnalogMode
==============================================================*/
/**
* Enable/Disable the Analog lowpower mode.
* <p>
* This method enables/disables the analog lowpower mode.
*
*/
public boolean setAnalogMode(boolean value) {
int re = mControl.setAudioPath(sFd, value);
re = FmReceiverJNI.setAnalogModeNative(value);
if (re == 1)
return true;
return false;
}
/*==============================================================
FUNCTION: getInternalAntenna
==============================================================*/
/**
* Returns true if internal FM antenna is available
*
* <p>
* This method returns true is internal FM antenna is
* available, false otherwise
*
* <p>
* @return true/false
*/
public boolean getInternalAntenna()
{
int re = FmReceiverJNI.getControlNative (sFd, V4L2_CID_PRIVATE_TAVARUA_ANTENNA);
if (re == 1)
return true;
return false;
}
/*==============================================================
FUNCTION: setInternalAntenna
==============================================================*/
/**
* Returns true if successful, false otherwise
*
* <p>
* This method sets internal antenna type to true/false
*
* @param intAntenna true is Internal antenna is present
*
* <p>
* @return true/false
*/
public boolean setInternalAntenna(boolean intAnt)
{
int iAntenna ;
if (intAnt)
iAntenna = 1;
else
iAntenna = 0;
int re = FmReceiverJNI.setControlNative (sFd, V4L2_CID_PRIVATE_TAVARUA_ANTENNA, iAntenna);
if (re == 0)
return true;
return false;
}
/*==============================================================
FUNCTION: setFMPowerState
==============================================================*/
/**
* Sets the FM power state
*
* <p>
* This method sets the FM power state.
*
* <p>
*/
static void setFMPowerState(int state)
{
FMState = state;
}
/*==============================================================
FUNCTION: getFMPowerState
==============================================================*/
/**
* Returns :
*
* FMOff - If the FM Radio is turned off
* FMRxOn - If the FM Receiver is currently turned on
* FMTxOn - If the FM Transmitter is currently turned on
* FMReset - If the FM Radio is reset
*
* Gets the FM power state
*
* <p>
* This method gets the FM power state.
*
* <p>
*/
public static int getFMPowerState()
{
return FMState;
}
}
+841
View File
@@ -0,0 +1,841 @@
/*
* Copyright (c) 2009-2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
import android.util.Log;
/**
* This class contains all interfaces and types needed to control the FM transmitter.
* @hide
*/
public class FmTransmitter extends FmTransceiver
{
private final String TAG = "FmTransmitter";
/**
* An object that contains the PS Features that SoC supports
*
* @see #getPSFeatures
*/
public class FmPSFeatures
{
public int maxPSCharacters;
public int maxPSStringRepeatCount;
};
/**
* Command types for the RDS group transmission.
* This is used as argument to #transmitRdsGroupControl to
* control the RDS group transmission.
*
* @see #transmitRdsGroupControl
*/
public static final int RDS_GRPS_TX_PAUSE = 0; /* Pauses the Group transmission*/
public static final int RDS_GRPS_TX_RESUME = 1; /* Resumes the Group transmission*/
public static final int RDS_GRPS_TX_STOP = 2; /* Stops and clear the Group transmission */
public static final int FM_TX_MAX_PS_LEN = (96+1);
public static final int FM_TX_MAX_RT_LEN = (64+1);
private static final int MAX_PS_CHARS = 97;
private static final int MAX_PS_REP_COUNT = 15;
private static final int MAX_RDS_GROUP_BUF_SIZE = 62;
private FmTransmitterCallbacksAdaptor mTxCallbacks;
private boolean mPSStarted = false;
private boolean mRTStarted = false;
private static final int V4L2_CID_PRIVATE_BASE = 0x8000000;
private static final int V4L2_CID_PRIVATE_TAVARUA_ANTENNA = V4L2_CID_PRIVATE_BASE + 18;
/**
* Power settings
*
* @see #setPowerMode
* @see #getPowerMode
*/
public static final int FM_TX_NORMAL_POWER_MODE =0;
public static final int FM_TX_LOW_POWER_MODE =1;
/**
* Transmit Power level settings
*
* @see #setTxPowerLevel
*/
public static final int FM_TX_PWR_LEVEL_0 =0;
public static final int FM_TX_PWR_LEVEL_1 =1;
public static final int FM_TX_PWR_LEVEL_2 =2;
public static final int FM_TX_PWR_LEVEL_3 =3;
public static final int FM_TX_PWR_LEVEL_4 =4;
public static final int FM_TX_PWR_LEVEL_5 =5;
public static final int FM_TX_PWR_LEVEL_6 =6;
public static final int FM_TX_PWR_LEVEL_7 =7;
/**
* Constructor for the transmitter class that takes path to
* radio device and event callback adapter
*/
public FmTransmitter(String path, FmTransmitterCallbacksAdaptor callbacks) throws InstantiationException{
mTxEvents = new FmTxEventListner();
mControl = new FmRxControls();
mTxCallbacks = callbacks;
}
/*==============================================================
FUNCTION: enable
==============================================================*/
/**
* Enables the FM device in Transmit Mode.
* <p>
* This is a synchronous method used to initialize the FM
* device in transmitt mode. If already initialized this function will
* intialize the Fm device with default settings. Only after
* successfully calling this function can many of the FM device
* interfaces be used.
* <p>
* When enabling the transmitter, the application must also
* provide the regional settings in which the transmitter will
* operate. These settings (included in argument
* configSettings) are typically used for setting up the FM
* Transmitter for operating in a particular geographical
* region. These settings can be changed after the FM driver
* is enabled through the use of the function {@link
* #configure}.
* <p>
* This command can only be issued by the owner of an FM
* transmitter.
*
* @param configSettings the settings to be applied when
* turning on the radio
* @return true if Initialization succeeded, false if
* Initialization failed.
* <p>
* @see #enable
* @see #registerTransmitClient
* @see #disable
*
*/
public boolean enable (FmConfig configSettings){
boolean status;
/* Enable the Transceiver common for both
receiver and transmitter
*/
status = super.enable(configSettings, FmTransceiver.FM_TX);
/* Do transmitter Specific Enable Stuff here.*/
if( status == true ) {
registerTransmitClient(mTxCallbacks);
mRdsData = new FmRxRdsData(sFd);
}
return status;
}
/*==============================================================
FUNCTION: setRdsOn
==============================================================*/
/**
*
* This function enables RDSCTRL register for SoC.
*
* <p>
* This API enables the ability of the FM driver
* to send Program Service, RadioText information.
*
*
* @return true if the command was placed successfully, false
* if command failed.
*
*/
public boolean setRdsOn (){
if (mRdsData == null)
return false;
// Enable RDS
int re = mRdsData.rdsOn(true);
if (re ==0)
return true;
return false;
}
/*==============================================================
FUNCTION: disable
==============================================================*/
/**
* Disables the FM Transmitter Device.
* <p>
* This is a synchronous command used to disable the FM
* device. This function is expected to be used when the
* application no longer requires use of the FM device. Once
* called, most functionality offered by the FM device will be
* disabled until the application re-enables the device again
* via {@link #enable}.
*
* <p>
* @return true if disabling succeeded, false if disabling
* failed.
*
* @see #enable
* @see #registerTransmitClient
*/
public boolean disable(){
boolean status = false;
//Stop all the RDS transmissions if there any
if( mPSStarted ){
if( !stopPSInfo() ) {
Log.d(TAG, "FmTrasmitter:stopPSInfo failed\n");
}
}
if( mRTStarted ) {
if(!stopRTInfo()) {
Log.d(TAG, "FmTrasmitter:stopRTInfo failed\n");
}
}
if(!transmitRdsGroupControl(RDS_GRPS_TX_STOP) ) {
Log.d(TAG, "FmTrasmitter:transmitRdsGroupControl failed\n");
}
unregisterTransmitClient();
status = super.disable();
return status;
}
/*==============================================================
FUNCTION: setStation
==============================================================*/
/**
* Tunes the FM device to the specified FM frequency.
* <p>
* This method tunes the FM device to a station specified by the
* provided frequency. Only valid frequencies within the band
* set by enable or configure can be tuned by this function.
* Attempting to tune to frequencies outside of the set band
* will result in an error.
* <p>
* Once tuning to the specified frequency is completed, the
* event callback FmTransmitterCallbacks::onTuneStatusChange will be called.
*
* @param frequencyKHz Frequency (in kHz) to be tuned
* (Example: 96500 = 96.5Mhz)
* @return true if setStation call was placed successfully,
* false if setStation failed.
*/
public boolean setStation (int frequencyKHz) {
//Stop If there is any ongoing RDS transmissions
boolean status = false;
if( mPSStarted ){
Log.d(TAG,"FmTransmitter:setStation mPSStarted");
if( !stopPSInfo() ) return status;
}
if( mRTStarted ) {
Log.d(TAG,"FmTransmitter:setStation mRTStarted");
if(!stopRTInfo()) return status;
}
if(!transmitRdsGroupControl(RDS_GRPS_TX_STOP) )return status;
Log.d(TAG, "FmTrasmitter:SetStation\n");
status = super.setStation(frequencyKHz);
return status;
}
/*==============================================================
FUNCTION: setPowerMode
==============================================================*/
/**
* Puts the driver into or out of low power mode.
*
* <p>
* This is an synchronous command which can put the FM
* device and driver into and out of low power mode. Low power mode
* should be used when the receiver is tuned to a station and only
* the FM audio is required. The typical scenario for low power mode
* is when the FM application is no longer visible.
*
* <p>
* While in low power mode, all normal FM and RDS indications from
* the FM driver will be suppressed. By disabling these indications,
* low power mode can result in fewer interruptions and this may lead
* to a power savings.
*
* <p>
* @param powerMode the new driver operating mode.
*
* @return true if setPowerMode succeeded, false if
* setPowerMode failed.
*/
public boolean setPowerMode(int powerMode){
int re;
if (powerMode == FM_TX_LOW_POWER_MODE) {
re = mControl.setLowPwrMode (sFd, true);
}
else {
re = mControl.setLowPwrMode (sFd, false);
}
if (re == 0)
return true;
return false;
}
/*==============================================================
FUNCTION: getPSFeatures
==============================================================*/
/**
* This function returns the features supported by the FM
* driver when using {@link #setPSInfo}.
* <p>
* This function is used to get the features the FM driver
* supports when transmitting Program Service information.
* Included in the returned features is the number of Program
* Service (PS) characters which can be transmitted using
* {@link #setPSInfo}. If the driver supports continuous
* transmission of Program Service Information, this function
* will return a value greater than 0 for
* FmPSFeatures.maxPSCharacters. Although the RDS/RBDS
* standard defines each Program Service (PS) string as eight
* characters in length, the FM driver may have the ability to
* accept a string that is greater than eight character. This
* extended string will thenbe broken up into multiple strings
* of length eight and transmitted continuously.
* <p>
* When transmitting more than one string, the application may
* want to control the timing of how long each string is
* transmitted. Included in the features returned from this
* function is the maximum Program Service string repeat count
* (FmPSFeatures.maxPSStringRepeatCount). When using the
* function {@link #setPSInfo}, the application can specify how
* many times each string is repeated before the next string is
* transmitted.
*
* @return the Program service maximum characters and repeat
* count
*
* @see #setPSInfo
*
*/
public FmPSFeatures getPSFeatures(){
FmPSFeatures psFeatures = new FmPSFeatures();
psFeatures.maxPSCharacters = MAX_PS_CHARS;
psFeatures.maxPSStringRepeatCount = MAX_PS_REP_COUNT;
return psFeatures;
}
/*==============================================================
FUNCTION: startPSInfo
==============================================================*/
/**
* Continuously transmit RDS/RBDS Program Service information
* over an already tuned station.
* <p>
* This is a synchronous function used to continuously transmit Program
* Service information over an already tuned station. While
* Program Service information can be transmitted using {@link
* #transmitRdsGroups} and 0A/0B groups, this function makes
* the same output possible with limited input needed from the
* application.
* <p>
* Included in the Program Service information is an RDS/RBDS
* program type (PTY), and one or more Program Service
* strings. The program type (PTY) is used to describe the
* content being transmitted and follows the RDS/RBDS program
* types described in the RDS/RBDS specifications.
* <p>
* Program Service information also includes an eight
* character string. This string can be used to display any
* information, but is typically used to display information
* about the audio being transmitted. Although the RDS/RBDS
* standard defines a Program Service (PS) string as eight
* characters in length, the FM driver may have the ability to
* accept a string that is greater than eight characters. This
* extended string will then be broken up into multiple eight
* character strings which will be transmitted continuously.
* All strings passed to this function must be terminated by a
* null character (0x00).
* <p>
* When transmitting more than one string, the application may
* want to control the timing of how long each string is
* transmitted. To control this timing and to ensure that the FM
* receiver receives each string, the application can specify
* how many times each string is repeated before the next string
* is transmitted. This command can only be issued by the owner
* of an FM transmitter.
* <p>
* Maximux Programme service string lenght that can be sent is
* FM_TX_MAX_PS_LEN. If the application sends PS string longer than
* this threshold, string will be truncated to FM_TX_MAX_PS_LEN.
*
* @param psStr the program service strings to transmit
* @param pty the program type to use in the program Service
* information.
* @param pi the program type to use in the program Service
* information.
* @param repeatCount the number of times each 8 char string is
* repeated before next string
*
* @return true if PS information was successfully sent to the
* driver, false if PS information could not be sent
* to the driver.
*
* @see #getPSFeatures
* @see #stopPSInfo
*/
public boolean startPSInfo(String psStr, int pty, int pi, int repeatCount){
//Set the PTY
if((pty < 0) || (pty > 31 )) {
Log.d(TAG,"pTy is expected from 0 to 31");
return false;
}
int err = FmReceiverJNI.setPTYNative( sFd, pty );
if( err < 0 ){
Log.d(TAG,"setPTYNative is failure");
return false;
}
if((pi < 0) || (pi > 65535)) {
Log.d(TAG,"pi is expected from 0 to 65535");
return false;
}
//Set the PI
err = FmReceiverJNI.setPINative( sFd, pi );
if( err < 0 ){
Log.d(TAG,"setPINative is failure");
return false;
}
if((repeatCount < 0) || (repeatCount > 15)) {
Log.d(TAG,"repeat count is expected from 0 to 15");
return false;
}
err = FmReceiverJNI.setPSRepeatCountNative( sFd, repeatCount );
if( err < 0 ){
Log.d(TAG,"setPSRepeatCountNative is failure");
return false;
}
if( psStr.length() > FM_TX_MAX_PS_LEN ){
/*truncate the PS string to
MAX possible length*/
psStr = psStr.substring( 0, FM_TX_MAX_PS_LEN );
}
err = FmReceiverJNI.startPSNative( sFd, psStr , psStr.length() );
Log.d(TAG,"return for startPS is "+err);
if( err < 0 ){
Log.d(TAG, "FmReceiverJNI.startPSNative returned false\n");
return false;
} else {
Log.d(TAG,"startPSNative is successful");
mPSStarted = true;
return true;
}
}
/*==============================================================
FUNCTION: stopPSInfo
==============================================================*/
/**
* Stops an active Program Service transmission.
*
* <p>
* This is a synchrnous function used to stop an active Program Service transmission
* started by {@link #startPSInfo}.
*
* @return true if Stop PS information was successfully sent to
* the driver, false if Stop PS information could not
* be sent to the driver.
*
* @see #getPSFeatures
* @see #startPSInfo
*
*/
public boolean stopPSInfo(){
int err =0;
if( (err =FmReceiverJNI.stopPSNative( sFd )) < 0 ){
Log.d(TAG,"return for startPS is "+err);
return false;
} else{
Log.d(TAG,"stopPSNative is successful");
mPSStarted = false;
return true;
}
}
/*==============================================================
FUNCTION: startRTInfo
==============================================================*/
/**
* Continuously transmit RDS/RBDS RadioText information over an
* already tuned station.
*
* <p>
* This is a synchronous function used to continuously transmit RadioText
* information over an already tuned station. While RadioText
* information can be transmitted using
* {@link #transmitRdsGroups} and 2A/2B groups, this function
* makes the same output possible with limited input needed from
* the application.
* <p>
* Included in the RadioText information is an RDS/RBDS program type (PTY),
* and a single string of up to 64 characters. The program type (PTY) is used
* to describe the content being transmitted and follows the RDS/RBDS program
* types described in the RDS/RBDS specifications.
* <p>
* RadioText information also includes a string that consists of up to 64
* characters. This string can be used to display any information, but is
* typically used to display information about the audio being transmitted.
* This RadioText string is expected to be at 64 characters in length, or less
* than 64 characters and terminated by a return carriage (0x0D). All strings
* passed to this function must be terminated by a null character (0x00).
* <p>
* <p>
* Maximux Radio Text string length that can be sent is
* FM_TX_MAX_RT_LEN. If the application sends RT string longer than
* this threshold, string will be truncated to FM_TX_MAX_RT_LEN.
*
* @param rtStr the Radio Text string to transmit
* @param pty the program type to use in the Radio text
* transmissions.
* @param pi the program identifier to use in the Radio text
* transmissions.
*
* @return true if RT information String was successfully sent
* to the driver, false if RT information string
* could not be sent to the driver.
*
* @see #stopRTInfo
*/
public boolean startRTInfo(String rtStr, int pty, int pi){
if((pty < 0) || (pty > 31 )) {
Log.d(TAG,"pTy is expected from 0 to 31");
return false;
}
//Set the PTY
int err = FmReceiverJNI.setPTYNative( sFd, pty );
if( err < 0 ){
Log.d(TAG,"setPTYNative is failure");
return false;
}
if((pi < 0) || (pi > 65535)) {
Log.d(TAG,"pi is expected from 0 to 65535");
return false;
}
err = FmReceiverJNI.setPINative( sFd, pi );
if( err < 0 ){
Log.d(TAG,"setPINative is failure");
return false;
}
if( rtStr.length() > FM_TX_MAX_RT_LEN )
{
//truncate it to max length
rtStr = rtStr.substring( 0, FM_TX_MAX_RT_LEN );
}
err = FmReceiverJNI.startRTNative( sFd, rtStr, rtStr.length() );
if( err < 0 ){
Log.d(TAG, "FmReceiverJNI.startRTNative returned false\n");
return false;
} else {
Log.d(TAG,"mRTStarted is true");
mRTStarted = true;
return true;
}
}
/*==============================================================
FUNCTION: stopRTInfo
==============================================================*/
/**
* Stops an active Radio Text information transmission.
*
* <p>
* This is a synchrnous function used to stop an active Radio Text
* transmission started by {@link #startRTInfo}.
*
* @return true if Stop RT information was successfully sent to
* the driver, false if Stop RT information could not
* be sent to the driver.
*
* @see #startRTInfo
*
*/
public boolean stopRTInfo(){
if( FmReceiverJNI.stopRTNative( sFd ) < 0 ){
Log.d(TAG,"stopRTNative is failure");
return false;
} else{
Log.d(TAG,"mRTStarted is false");
mRTStarted = false;
return true;
}
}
/*==============================================================
FUNCTION: getRdsGroupBufSize
==============================================================*/
/**
* Get the maximum number of RDS/RBDS groups which can be passed
* to the FM driver.
* <p>
* This is a function used to determine the maximum RDS/RBDS
* buffer size for use when calling {@link #transmitRdsGroups}
*
* @return the maximum number of RDS/RBDS groups which can be
* passed to the FM driver at any one time.
*
*/
public int getRdsGroupBufSize(){
return MAX_RDS_GROUP_BUF_SIZE;
}
/*==============================================================
FUNCTION: transmitRdsGroups
==============================================================*/
/**
* This function will transmit RDS/RBDS groups
* over an already tuned station.
* This is an asynchronous function used to transmit RDS/RBDS
* groups over an already tuned station. This functionality is
* is currently unsupported.
* <p>
* This function accepts a buffer (rdsGroups) containing one or
* more RDS groups. When sending this buffer, the application
* must also indicate how many groups should be taken from this
* buffer (numGroupsToTransmit). It may be possible that the FM
* driver can not accept the number of group contained in the
* buffer and will indicate how many group were actually
* accepted through the return value.
*
* <p>
* The FM driver will indicate to the application when it is
* ready to accept more data via both the
* "onRDSGroupsAvailable()" and "onRDSGroupsComplete()" events
* callbacks. The "onRDSGroupsAvailable()" callback will
* indicate to the application that the FM driver can accept
* additional groups even though all groups may not have been
* passed to the FM transmitter. The onRDSGroupsComplete()
* callback will indicate when the FM driver has a complete
* buffer to transmit RDS data. In many cases all data passed to
* the FM driver will be passed to the FM hardware and only a
* onRDSGroupsComplete() event will be generated by the
* FM driver.
* <p> If the application attempts to send more groups than the
* FM driver can handle, the application must wait until it
* receives a onRDSGroupsAvailable or a onRDSGroupsComplete
* event before attempting to transmit more groups. Failure to
* do so may result in no group being consumed by the FM driver.
* <p> It is important to note that switching between continuous
* and non-continuous transmission of RDS groups can only happen
* when no RDS/RBDS group transmission is underway. If an
* RDS/RBDS group transmission is already underway, the
* application must wait for a onRDSGroupsComplete. If the application
* wishes to switch from continuous to non-continuous (or
* vice-versa) without waiting for the current transmission to
* complete, the application can clear all remaining groups
* using the {@link #transmitRdsGroupControl} command.
* <p>
* Once completed, this command will generate a
* onRDSGroupsComplete event to all registered applications.
*
* @param rdsGroups The RDS/RBDS groups buffer to transmit.
* @param numGroupsToTransmit The number of groups in the buffer
* to transmit.
*
* @return The number of groups the FM driver actually accepted.
* A value >0 indicates the command was successfully
* accepted and a return value of "-1" indicates error.
*
* @see #transmitRdsGroupControl
*/
public int transmitRdsGroups(byte[] rdsGroups, long numGroupsToTransmit){
/*
* This functionality is currently unsupported
*/
return -1;
}
/*==============================================================
FUNCTION: transmitContRdsGroups
==============================================================*/
/**
* This function will continuously transmit RDS/RBDS groups over an already tuned station.
* <p>
* This is an asynchronous function used to continuously
* transmit RDS/RBDS groups over an already tuned station.
* This functionality is currently unsupported.
* <p>
* This function accepts a buffer (rdsGroups) containing one or
* more RDS groups. When sending this buffer, the application
* must also indicate how many groups should be taken from this
* buffer (numGroupsToTransmit). It may be possible that the FM
* driver can not accept the number of group contained in the
* buffer and will indicate how many group were actually
* accepted through the return value.
*
* <p>
* Application can send a complete RDS group buffer for the transmission.
* This data will be sent continuously to the driver. Only single RDS
* group can be continuously transmitter at a time. So, application has to
* send the complete RDS buffer it intends to transmit. trying to pass the
* single buffer in two calls will be interprted as two different RDS/RBDS
* groups and hence all the unset groups will be cleared.
* <p>
* As continuous RDS/RBDS group transmission is done over single buffer,
* Application has to wait for the "onContRDSGroupsComplete()" callback
* to initiate the further RDS/RBDS group transmissions. Failure to
* do so may result in no group being consumed by the FM driver.
* <p> It is important to note that switching between continuous
* and non-continuous transmission of RDS groups can only happen
* when no RDS/RBDS group transmission is underway. If an
* RDS/RBDS group transmission is already underway, the
* application must wait for a onRDSGroupsComplete or onContRDSGroupsComplete.
* If the application wishes to switch from continuous to non-continuous (or
* vice-versa) without waiting for the current transmission to
* complete, the application can clear all remaining groups
* using the {@link #transmitRdsGroupControl} command.
* <p>
* Once completed, this command will generate a
* onRDSContGroupsComplete event to all registered applications.
*
* @param rdsGroups The RDS/RBDS groups buffer to transmit.
* @param numGroupsToTransmit The number of groups in the buffer
* to transmit.
*
* @return The number of groups the FM driver actually accepted.
* A value >0 indicates the command was successfully
* accepted and a return value of "-1" indicates error.
*
* @see #transmitRdsGroupControl
*/
public int transmitRdsContGroups(byte[] rdsGroups, long numGroupsToTransmit){
/*
* This functionality is currently unsupported.
*/
return -1;
}
/*==============================================================
FUNCTION: transmitRdsGroupControl
==============================================================*/
/**
* Pause/Resume RDS/RBDS group transmission, or stop and clear
* all RDS groups.
* <p>
* This is a function used to pause/resume RDS/RBDS
* group transmission, or stop and clear all RDS groups. This
* function can be used to control continuous and
* non-continuous RDS/RBDS group transmissions. This functionality
* is currently unsupported.
* <p>
* @param ctrlCmd The Tx RDS group control.This should be one of the
* contants RDS_GRPS_TX_PAUSE/RDS_GRPS_TX_RESUME/RDS_GRPS_TX_STOP
*
* @return true if RDS Group Control command was
* successfully sent to the driver, false if RDS
* Group Control command could not be sent to the
* driver.
*
* @see #rdsGroupControlCmdType
* @see #transmitRdsGroups
*/
public boolean transmitRdsGroupControl(int ctrlCmd){
boolean bStatus = true;
/*
* This functionality is currently unsupported.
*/
int val = 0;
switch( ctrlCmd ) {
case RDS_GRPS_TX_PAUSE:break;
case RDS_GRPS_TX_RESUME:break;
case RDS_GRPS_TX_STOP:break;
default:
/*Shouldn't reach here*/
bStatus = false;
}
return bStatus;
}
/*==============================================================
FUNCTION: setTxPowerLevel
==============================================================*/
/**
* Sets the transmitter power level.
*
* <p>
* This is a function used for setting the power level of
* Tx device.
* <p>
* @param powLevel The Tx power level value to be set. The value should be
* in range 0-7.If input is -ve level will be set to 0
* and if it is above 7 level will be set to max i.e.,7.
*
* @return true on success, false on failure.
*
*/
public boolean setTxPowerLevel(int powLevel){
boolean bStatus = true;
int err = FmReceiverJNI.setTxPowerLevelNative( sFd, powLevel );
if( err < 0 ){
Log.d(TAG,"setTxPowerLevel is failure");
return false;
}
return bStatus;
}
};
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
/** @hide
* The interface that provides the applications to get callback
* for asynchronous events.
* An Adapter that implements this interface needs to be used to
* register to receive the callbacks using {@link
* #FmTransmitter}.
* <p>
* Application has to register for these callbacks by sending
* a valid instance of TransmitterCallbacks's adapter while
* instantiating the FMTransmitter.
*
* @see #FmTransmitter
*/
public interface FmTransmitterCallbacks
{
/**
* The callback indicates that the transmitter is tuned to a
* new frequency Typically received after setStation.
*/
public void onTuneStatusChange(int freq);
/**
* The callback to indicate to the application that the FM
* driver can accept additional groups even though all groups
* may not have been passed to the FM transmitter.
*
* Application can start to send down the remaining groups
* to the available group buffers upon recieving this callback.
*/
public void onRDSGroupsAvailable();
/**
* The callback will indicate the succesful completion of #transmitRdsGroups.
* This indicates that the FM driver has a complete buffer to transmit the
* RDS/RBDS data to the Application. Application can free to switch between continuous or
* non-continuous RDS/RBDS group transmissions.
*/
public void onRDSGroupsComplete();
/**
* The callback will indicate the succesful completion of #transmitRdsContGroups.
* This indicates that the FM driver has a complete buffer to transmit the
* RDS/RBDS data to the Application. Application can free to switch between continuous or
* non-continuous RDS/RBDS group transmissions.
*
*/
public void onContRDSGroupsComplete();
};
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
/**
* @hide
* Class to be implemented for Tx events callbacks
*
*/
public class FmTransmitterCallbacksAdaptor implements FmTransmitterCallbacks
{
public void onTuneStatusChange(int freq) {};
public void onRDSGroupsAvailable() {};
public void onRDSGroupsComplete() {};
public void onContRDSGroupsComplete() {};
};
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2011, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package android.hardware.fmradio;
import android.util.Log;
class FmTxEventListner {
private final int EVENT_LISTEN = 1;
private final int TUNE_EVENT = 1; /*Tune completion event*/
private final int TXRDSDAT_EVENT = 16; /*RDS Group available event*/
private final int TXRDSDONE_EVENT = 17; /*RDS group complete event */
private Thread mThread;
private static final String TAG = "FMTxEventListner";
public void startListner (final int fd, final FmTransmitterCallbacks cb) {
/* start a thread and listen for messages */
mThread = new Thread(){
public void run(){
Log.d(TAG, "Starting Tx Event listener " + fd);
while ((!Thread.currentThread().isInterrupted())) {
try {
int index = 0;
byte []buff = new byte[128];
Log.d(TAG, "getBufferNative called");
int eventCount = FmReceiverJNI.getBufferNative (fd, buff, EVENT_LISTEN);
Log.d(TAG, "Received event. Count: " + eventCount);
for ( index = 0; index < eventCount; index++ ) {
Log.d(TAG, "Received <" +buff[index]+ ">" );
switch(buff[index]){
case TUNE_EVENT:
Log.d(TAG, "Got TUNE_EVENT");
cb.onTuneStatusChange(FmReceiverJNI.getFreqNative(fd));
break;
case TXRDSDAT_EVENT:
Log.d(TAG, "Got TXRDSDAT_EVENT");
cb.onRDSGroupsAvailable();
break;
case TXRDSDONE_EVENT:
Log.d(TAG, "Got TXRDSDONE_EVENT");
cb.onContRDSGroupsComplete();
break;
default:
Log.d(TAG, "Unknown event");
break;
}//switch
}//for
} catch ( Exception ex ) {
Log.d( TAG, "RunningThread InterruptedException");
Thread.currentThread().interrupt();
}//try
}//while
Log.d(TAG, "Came out of the while loop");
}
};
mThread.start();
}
public void stopListener(){
//
Log.d(TAG, "Thread Stopped\n");
//Thread stop is deprecate API
//Interrupt the thread and check for the thread status
// and return from the run() method to stop the thread
//properly
Log.d( TAG, "stopping the Listener\n");
if( mThread != null ) {
mThread.interrupt();
}
Log.d(TAG, "Thread Stopped\n");
}
}