From d8731b709019c2d20767b0242484e7c5eeeda861 Mon Sep 17 00:00:00 2001 From: Satish kumar sugasi <ssugas@codeaurora.org> Date: Wed, 27 Jan 2016 14:45:45 -0800 Subject: [PATCH] Add Support to enable ECC events and update in UI This does enable ECC bit during RDS group processing and add logic to receive ECC events from SOC and sent the ECC code to application. Change-Id: I61687ea6fe041d2dc4aed16700632be5cdd781d8 --- fmapp2/src/com/caf/fmradio/FMRadio.java | 24 +++++++++ .../src/com/caf/fmradio/FMRadioService.java | 27 ++++++++++ fmapp2/src/com/caf/fmradio/FMStats.java | 4 ++ .../src/com/caf/fmradio/IFMRadioService.aidl | 1 + .../caf/fmradio/IFMRadioServiceCallbacks.aidl | 1 + helium/radio-helium.h | 4 ++ helium/radio_helium_hal.c | 29 ++++++++++- jni/android_hardware_fm.cpp | 49 ++++++++++++++----- qcom/fmradio/FmReceiver.java | 15 ++++++ qcom/fmradio/FmReceiverJNI.java | 11 +++++ qcom/fmradio/FmRxEvCallbacks.java | 1 + qcom/fmradio/FmRxEvCallbacksAdaptor.java | 1 + qcom/fmradio/FmRxRdsData.java | 7 +++ 13 files changed, 160 insertions(+), 14 deletions(-) diff --git a/fmapp2/src/com/caf/fmradio/FMRadio.java b/fmapp2/src/com/caf/fmradio/FMRadio.java index 909a14c..ee8ef3d 100644 --- a/fmapp2/src/com/caf/fmradio/FMRadio.java +++ b/fmapp2/src/com/caf/fmradio/FMRadio.java @@ -218,6 +218,7 @@ public class FMRadio extends Activity /* Bottom row in the station info layout */ private TextView mRadioTextTV; private TextView mERadioTextTV; + private TextView mEContryCodeTV; /* Sleep and Recording Messages */ private TextView mSleepMsgTV; @@ -2805,6 +2806,26 @@ public class FMRadio extends Activity } }; + Runnable mUpdateExtenCountryCode = new Runnable() { + public void run() { + String str = ""; + int value; + if ((mService != null) && isFmOn()) { + try { + /* Get Extended Radio Text and update the display */ + value = mService.getExtenCountryCode(); + str = Integer.toString(value); + Log.d(LOGTAG, "mUpdateExtenCountryCode: Updatable string: [" + str + "]"); + mERadioTextTV.setText(str); + mERadioTextScroller.mOriginalString = str; + mERadioTextScroller.startScroll(); + }catch (RemoteException e) { + e.printStackTrace(); + } + } + } + }; + /* Create runnable for posting */ Runnable mUpdateProgramService = new Runnable() { public void run() { @@ -3124,6 +3145,9 @@ public class FMRadio extends Activity public void onExtenRadioTextChanged() { mHandler.post(mUpdateExtenRadioText); } + public void onExtenCountryCodeChanged() { + mHandler.post(mUpdateExtenCountryCode); + } public void onAlternateFrequencyChanged() { Log.d(LOGTAG, "mServiceCallbacks.onAlternateFrequencyChanged :"); } diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java index 65f33cb..f4b24fb 100644 --- a/fmapp2/src/com/caf/fmradio/FMRadioService.java +++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java @@ -2043,6 +2043,10 @@ public class FMRadioService extends Service return(mService.get().isA2DPConnected()); } + public int getExtenCountryCode() + { + return(mService.get().getExtenCountryCode()); + } } private final IBinder mBinder = new ServiceStub(this); @@ -2741,6 +2745,16 @@ public class FMRadioService extends Service Log.d(LOGTAG, "eRadio Text:[" + str +"]"); return str; } + public int getExtenCountryCode() { + int val = 0; + if (mFMRxRDSData != null) + { + val = mFMRxRDSData.getECountryCode(); + } + Log.d(LOGTAG, "eCountry Code :[" + val +"]"); + return val; + } + /* Retrieves the RDS Program Type (PTY) code. * * @return int - RDS PTY code. @@ -3295,6 +3309,19 @@ public class FMRadioService extends Service e.printStackTrace(); } } + public void FmRxEvECCInfo() + { + Log.d(LOGTAG, "FmRxEvECCInfo"); + try { + if (mReceiver != null) { + mFMRxRDSData = mReceiver.getECCInfo(); + if(mCallbacks != null) + mCallbacks.onExtenCountryCodeChanged(); + } + } catch (RemoteException e) { + e.printStackTrace(); + } + } public void FmRxEvRdsPiMatchAvailable() { Log.d(LOGTAG, "FmRxEvRdsPiMatchAvailable"); diff --git a/fmapp2/src/com/caf/fmradio/FMStats.java b/fmapp2/src/com/caf/fmradio/FMStats.java index c035475..75ba4c6 100644 --- a/fmapp2/src/com/caf/fmradio/FMStats.java +++ b/fmapp2/src/com/caf/fmradio/FMStats.java @@ -2657,6 +2657,10 @@ public class FMStats extends Activity { { Log.d(LOGTAG, "Extended Radio Text changed:"); } + public void onExtenCountryCodeChanged() + { + Log.d(LOGTAG, "Extended ountry Code changed:"); + } public void onAlternateFrequencyChanged() { Log.d(LOGTAG, "mServiceCallbacks.onAlternateFrequencyChanged :"); diff --git a/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl b/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl index a02c593..766961a 100644 --- a/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl +++ b/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl @@ -53,6 +53,7 @@ interface IFMRadioService boolean setIntfDetLowTh(int intfLowTh); boolean setIntfDetHighTh(int intfHighTh); String getExtenRadioText(); + int getExtenCountryCode(); int getSinrSamplesCnt(); int getSinrTh(); int getSearchAlgoType(); diff --git a/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl b/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl index 24aaa70..826b5f3 100644 --- a/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl +++ b/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl @@ -50,4 +50,5 @@ interface IFMRadioServiceCallbacks void onA2DPConnectionstateChanged(boolean state); void onFmAudioPathStarted(); void onFmAudioPathStopped(); + void onExtenCountryCodeChanged(); } diff --git a/helium/radio-helium.h b/helium/radio-helium.h index 5c21bdd..98452d8 100644 --- a/helium/radio-helium.h +++ b/helium/radio-helium.h @@ -163,6 +163,7 @@ typedef void (*rds_grp_cntrs_cb)(char *rds_params); typedef void (*fm_peek_cb)(char *peek_rsp); typedef void (*fm_ssbi_peek_cb)(char *ssbi_peek_rsp); typedef void (*fm_ch_det_th_cb)(char *ch_det_rsp); +typedef void (*fm_ecc_evt_cb)(char *ecc_rsp); typedef struct { size_t size; @@ -185,6 +186,7 @@ typedef struct { fm_peek_cb fm_peek_rsp_cb; fm_ssbi_peek_cb fm_ssbi_peek_rsp_cb; fm_ch_det_th_cb fm_ch_det_th_rsp_cb; + fm_ecc_evt_cb ext_country_code_cb; callback_thread_event thread_evt_cb; } fm_vendor_callbacks_t; @@ -501,6 +503,8 @@ struct hci_fm_blend_table { #define HCI_EV_SEARCH_COMPLETE 0x12 #define HCI_EV_SEARCH_RDS_COMPLETE 0x13 #define HCI_EV_SEARCH_LIST_COMPLETE 0x14 + +#define HCI_EV_EXT_COUNTRY_CODE 0x17 #define HCI_EV_RADIO_TEXT_PLUS_ID 0x18 #define HCI_EV_RADIO_TEXT_PLUS_TAG 0x19 #define HCI_EV_HW_ERR_EVENT 0x1A diff --git a/helium/radio_helium_hal.c b/helium/radio_helium_hal.c index fd673ab..561c92a 100644 --- a/helium/radio_helium_hal.c +++ b/helium/radio_helium_hal.c @@ -558,6 +558,28 @@ static void hci_ev_rt_plus_tag(char *buff) } } +static void hci_ev_ext_country_code(char *buff) +{ + char *data = NULL; + int len = 15; + ALOGD("%s:%s: start", LOG_TAG, __func__); + data = malloc(len); + if (data != NULL) { + data[0] = len; + ALOGI("%s:%s: data length=%d\n", LOG_TAG, __func__,data[0]); + data[1] = buff[RDS_PTYPE]; + data[2] = buff[RDS_PID_LOWER]; + data[3] = buff[RDS_PID_HIGHER]; + data[4] = buff[3]; + memcpy(&data[RDS_OFFSET], &buff[4], len-RDS_OFFSET); + // data[len] = 0x00; + jni_cb->ext_country_code_cb(data); + free(data); + } else { + ALOGE("%s:memory allocation failed\n", LOG_TAG); + } +} + static void hci_ev_ert() { char *data = NULL; @@ -770,9 +792,12 @@ void radio_hci_event_packet(char *evt_buf) case HCI_EV_RADIO_TEXT_PLUS_TAG: hci_ev_rt_plus_tag(((FM_EVT_HDR *)evt_buf)->cmd_params); break; + case HCI_EV_EXT_COUNTRY_CODE: + hci_ev_ext_country_code(((FM_EVT_HDR *)evt_buf)->cmd_params); + break; case HCI_EV_HW_ERR_EVENT: - hci_ev_hw_error(((FM_EVT_HDR *)evt_buf)->cmd_params); - break; + hci_ev_hw_error(((FM_EVT_HDR *)evt_buf)->cmd_params); + break; default: break; } diff --git a/jni/android_hardware_fm.cpp b/jni/android_hardware_fm.cpp index 53e757a..21528bb 100644 --- a/jni/android_hardware_fm.cpp +++ b/jni/android_hardware_fm.cpp @@ -78,7 +78,6 @@ enum search_dir_t { SCAN_DN }; - static JNIEnv *g_jEnv = NULL; static JavaVM *g_jVM = NULL; @@ -89,7 +88,6 @@ char *FM_LIBRARY_NAME = "fm_helium.so"; char *FM_LIBRARY_SYMBOL_NAME = "FM_HELIUM_LIB_INTERFACE"; void *lib_handle; - typedef void (*enb_result_cb)(); typedef void (*tune_rsp_cb)(int Freq); typedef void (*seek_rsp_cb)(int Freq); @@ -109,6 +107,7 @@ typedef void (*rds_grp_cntrs_cb)(char *rds_params); typedef void (*fm_peek_cb)(char *peek_rsp); typedef void (*fm_ssbi_peek_cb)(char *ssbi_peek_rsp); typedef void (*fm_ch_det_th_cb)(char *ch_det_rsp); +typedef void (*fm_ecc_evt_cb)(char *ecc); static JNIEnv *mCallbackEnv = NULL; static jobject mCallbacksObj = NULL; @@ -120,6 +119,7 @@ static jmethodID method_rtCallback; static jmethodID method_ertCallback; static jmethodID method_aflistCallback; static jmethodID method_rtplusCallback; +static jmethodID method_eccCallback; jmethodID method_enableCallback; jmethodID method_tuneCallback; @@ -289,7 +289,7 @@ void fm_rt_plus_update_cb(char *rt_plus) void fm_ert_update_cb(char *ert) { - ALOGE("ERT_EVT"); + ALOGI("ERT_EVT"); jbyteArray ert_buff = NULL; int i,len; @@ -301,19 +301,44 @@ void fm_ert_update_cb(char *ert) len = (int)(ert[0] & 0xFF); len = len+3; - ALOGE(" ert data len=%d :",len); + ALOGI(" ert data len=%d :",len); ert_buff = mCallbackEnv->NewByteArray(len); if (ert_buff == NULL) { - ALOGE(" ps data allocate failed :"); + ALOGE(" ert data allocate failed :"); return; } mCallbackEnv->SetByteArrayRegion(ert_buff, 0, len,(jbyte *)ert); - jbyte* bytes= mCallbackEnv->GetByteArrayElements(ert_buff,0); + // jbyte* bytes= mCallbackEnv->GetByteArrayElements(ert_buff,0); mCallbackEnv->CallVoidMethod(mCallbacksObj, method_ertCallback,ert_buff); mCallbackEnv->DeleteLocalRef(ert_buff); } +void fm_ext_country_code_cb(char *ecc) +{ + ALOGI("Extended Contry code "); + jbyteArray ecc_buff = NULL; + int i,len; + + if (!checkCallbackThread()) { + ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); + return; + } + + len = (int)(ecc[0] & 0xFF); + + ALOGI(" ecc data len=%d :",len); + ecc_buff = mCallbackEnv->NewByteArray(len); + if (ecc_buff == NULL) { + ALOGE(" ecc data allocate failed :"); + return; + } + mCallbackEnv->SetByteArrayRegion(ecc_buff, 0, len,(jbyte *)ecc); + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_eccCallback,ecc_buff); + mCallbackEnv->DeleteLocalRef(ecc_buff); +} + + void rds_grp_cntrs_rsp_cb(char * evt_buffer) { ALOGE("rds_grp_cntrs_rsp_cb"); @@ -376,6 +401,7 @@ typedef struct { fm_peek_cb fm_peek_rsp_cb; fm_ssbi_peek_cb fm_ssbi_peek_rsp_cb; fm_ch_det_th_cb fm_ch_det_th_rsp_cb; + fm_ecc_evt_cb ext_country_code_cb; callback_thread_event thread_evt_cb; } fm_vendor_callbacks_t; @@ -407,6 +433,7 @@ static fm_vendor_callbacks_t fm_callbacks = { fm_peek_rsp_cb, fm_ssbi_peek_rsp_cb, fm_ch_det_th_rsp_cb, + fm_ext_country_code_cb, fm_thread_evt_cb }; #endif @@ -1336,7 +1363,6 @@ static void classInitNative(JNIEnv* env, jclass clazz) { ALOGI("ClassInit native called \n"); #ifdef FM_SOC_TYPE_CHEROKEE - jclass dataClass = env->FindClass("qcom/fmradio/FmReceiverJNI"); javaClassRef = (jclass) env->NewGlobalRef(dataClass); lib_handle = dlopen(FM_LIBRARY_NAME, RTLD_NOW); @@ -1344,7 +1370,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) { ALOGE("%s unable to open %s: %s", __func__, FM_LIBRARY_NAME, dlerror()); goto error; } - ALOGE("Opened %s shared object library successfully", FM_LIBRARY_NAME); + ALOGI("Opened %s shared object library successfully", FM_LIBRARY_NAME); ALOGI("Obtaining handle: '%s' to the shared object library...", FM_LIBRARY_SYMBOL_NAME); vendor_interface = (fm_interface_t *)dlsym(lib_handle, FM_LIBRARY_SYMBOL_NAME); @@ -1356,9 +1382,9 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_psInfoCallback = env->GetMethodID(javaClassRef, "PsInfoCallback", "([B)V"); method_rtCallback = env->GetMethodID(javaClassRef, "RtCallback", "([B)V"); method_ertCallback = env->GetMethodID(javaClassRef, "ErtCallback", "([B)V"); + method_eccCallback = env->GetMethodID(javaClassRef, "EccCallback", "([B)V"); method_rtplusCallback = env->GetMethodID(javaClassRef, "RtPlusCallback", "([B)V"); method_aflistCallback = env->GetMethodID(javaClassRef, "AflistCallback", "([B)V"); - ALOGI("method_psInfoCallback: '%p' env =%p...", method_psInfoCallback, env); method_enableCallback = env->GetMethodID(javaClassRef, "enableCallback", "()V"); method_tuneCallback = env->GetMethodID(javaClassRef, "tuneCallback", "(I)V"); method_seekCmplCallback = env->GetMethodID(javaClassRef, "seekCmplCallback", "(I)V"); @@ -1390,9 +1416,8 @@ static void initNative(JNIEnv *env, jobject object) { ALOGE("%s unable to initialize vendor library: %d", __func__, status); return; } - ALOGE("***** FM HAL Initialization complete *****\n"); + ALOGI("***** FM HAL Initialization complete *****\n"); } - ALOGE("object =%p, env = %p\n",object,env); mCallbacksObj = env->NewGlobalRef(object); #endif } @@ -1485,7 +1510,7 @@ jint JNI_OnLoad(JavaVM *jvm, void *reserved) int status; g_jVM = jvm; - ALOGE("FM : Loading QCOMM FM-JNI"); + ALOGI("FM : Loading QCOMM FM-JNI"); if (jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) { ALOGE("JNI version mismatch error"); return JNI_ERR; diff --git a/qcom/fmradio/FmReceiver.java b/qcom/fmradio/FmReceiver.java index 95a8c5e..8e681e7 100644 --- a/qcom/fmradio/FmReceiver.java +++ b/qcom/fmradio/FmReceiver.java @@ -1600,6 +1600,21 @@ public class FmReceiver extends FmTransceiver return mRdsData; } + public FmRxRdsData getECCInfo() { + byte [] raw_ecc = new byte[STD_BUF_SIZE]; + int ecc_code =0; + int bytes_read; + + raw_ecc = FmReceiverJNI.getPsBuffer(raw_ecc); + bytes_read = raw_ecc[0]; + Log.d (TAG, "bytes_read = " + bytes_read); + if (bytes_read > 0) { + ecc_code = raw_ecc[9] & 0xFF; + mRdsData.setECountryCode(ecc_code); + Log.d(TAG, "ECC code: " + ecc_code ); + } + return mRdsData; + } /*============================================================== FUNCTION: getAFInfo ==============================================================*/ diff --git a/qcom/fmradio/FmReceiverJNI.java b/qcom/fmradio/FmReceiverJNI.java index 1cafe37..d085476 100644 --- a/qcom/fmradio/FmReceiverJNI.java +++ b/qcom/fmradio/FmReceiverJNI.java @@ -113,6 +113,17 @@ class FmReceiverJNI { Log.d(TAG, "RtCallback exit " ); } + public void EccCallback(byte[] ecc) { + Log.i(TAG, "EccCallback enter " ); + if (ecc == null) { + Log.e(TAG, "ECC null return "); + return; + } + mRdsBuffer = Arrays.copyOf(ecc, ecc.length); + FmReceiver.mCallback.FmRxEvECCInfo(); + Log.i(TAG, "EccCallback exit " ); + } + public void PsInfoCallback(byte[] psInfo) { Log.d(TAG, "PsInfoCallback enter " ); if (psInfo == null) { diff --git a/qcom/fmradio/FmRxEvCallbacks.java b/qcom/fmradio/FmRxEvCallbacks.java index 50d2fb2..267d73d 100644 --- a/qcom/fmradio/FmRxEvCallbacks.java +++ b/qcom/fmradio/FmRxEvCallbacks.java @@ -46,4 +46,5 @@ interface FmRxEvCallbacks { public void FmRxEvRdsAfInfo(); public void FmRxEvRTPlus(); public void FmRxEvERTInfo(); + public void FmRxEvECCInfo(); } diff --git a/qcom/fmradio/FmRxEvCallbacksAdaptor.java b/qcom/fmradio/FmRxEvCallbacksAdaptor.java index 458ff59..753d506 100644 --- a/qcom/fmradio/FmRxEvCallbacksAdaptor.java +++ b/qcom/fmradio/FmRxEvCallbacksAdaptor.java @@ -51,5 +51,6 @@ public class FmRxEvCallbacksAdaptor implements FmRxEvCallbacks { public void FmRxEvRdsAfInfo() {}; public void FmRxEvRTPlus() {}; public void FmRxEvERTInfo() {}; + public void FmRxEvECCInfo() {}; } diff --git a/qcom/fmradio/FmRxRdsData.java b/qcom/fmradio/FmRxRdsData.java index f0e5b9e..1f722f1 100644 --- a/qcom/fmradio/FmRxRdsData.java +++ b/qcom/fmradio/FmRxRdsData.java @@ -50,6 +50,7 @@ public class FmRxRdsData { private int mPrgmId; private int mPrgmType; private int mFd; + private int mECountryCode; /* V4L2 controls */ private static final int V4L2_CID_PRIVATE_BASE = 0x8000000; @@ -216,6 +217,12 @@ public class FmRxRdsData { public void setERadioText (String x) { mERadioText = x; } + public void setECountryCode(int x) { + mECountryCode = x; + } + public int getECountryCode() { + return mECountryCode; + } public boolean getFormatDir() { return formatting_dir; } -- GitLab