diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java index 52f9f771817936e2dca6da3ce4ae6452c9dff1ee..65885711f9af91cf8cd5e3671b030d61853f821f 100644 --- a/fmapp2/src/com/caf/fmradio/FMRadioService.java +++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java @@ -224,6 +224,7 @@ public class FMRadioService extends Service private static Object mNotchFilterLock = new Object(); private boolean mFmA2dpDisabled; + private boolean mEventReceived = false; public FMRadioService() { } @@ -1448,31 +1449,33 @@ public class FMRadioService extends Service resolver.insert(uri, values); } - private void resumeAfterCall() { - if (getCallState() != TelephonyManager.CALL_STATE_IDLE) - return; - - // start playing again - if (!mResumeAfterCall) - return; + Runnable resumeAfterCall = new Runnable() { + public void run() { + if (getCallState() != TelephonyManager.CALL_STATE_IDLE) + return; - // resume playback only if FM Radio was playing - // when the call was answered - if (isAntennaAvailable() && (!isFmOn()) && mServiceInUse) { - Log.d(LOGTAG, "Resuming after call:"); - if(!fmOn()) { + // start playing again + if (!mResumeAfterCall) return; - } - mResumeAfterCall = false; - if (mCallbacks != null) { - try { - mCallbacks.onEnabled(); - } catch (RemoteException e) { - e.printStackTrace(); + + // resume playback only if FM Radio was playing + // when the call was answered + if (isAntennaAvailable() && (!isFmOn()) && mServiceInUse) { + Log.d(LOGTAG, "Resuming after call:"); + if(!fmOn()) { + return; + } + mResumeAfterCall = false; + if (mCallbacks != null) { + try { + mCallbacks.onEnabled(); + } catch (RemoteException e) { + e.printStackTrace(); + } } } } - } + }; private void fmActionOnCallState( int state ) { //if Call Status is non IDLE we need to Mute FM as well stop recording if @@ -1590,6 +1593,8 @@ public class FMRadioService extends Service stopRecording(); case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK"); + if (mReceiver != null) + mReceiver.EnableSlimbus(RESET_SLIMBUS_DATA_PORT); if (true == mPlaybackInProgress) { stopFM(); } @@ -1620,7 +1625,11 @@ public class FMRadioService extends Service mStoppedOnFocusLoss = false; if (mResumeAfterCall) { Log.v(LOGTAG, "resumeAfterCall"); - resumeAfterCall(); + if (getCallState() != TelephonyManager.CALL_STATE_IDLE) { + mHandler.postDelayed(resumeAfterCall, 100); + return; + } + mHandler.post(resumeAfterCall); break; } if(false == mPlaybackInProgress) @@ -2122,6 +2131,27 @@ public class FMRadioService extends Service misAnalogPathEnabled = analogMode; return true; } + private boolean waitForEvent() { + boolean status = false; + + synchronized (mEventWaitLock) { + Log.d(LOGTAG, "waiting for event"); + try { + if (mEventReceived == false) + mEventWaitLock.wait(RADIO_TIMEOUT); + if (mEventReceived == true) + status = true; + } catch (IllegalMonitorStateException e) { + Log.e(LOGTAG, "Exception caught while waiting for event"); + e.printStackTrace(); + } catch (InterruptedException ex) { + Log.e(LOGTAG, "Exception caught while waiting for event"); + ex.printStackTrace(); + } + } + return status; + } + /* * Turn ON FM: Powers up FM hardware, and initializes the FM module * . @@ -2163,7 +2193,12 @@ public class FMRadioService extends Service Log.d(LOGTAG, "fmOn: RdsStd :"+ config.getRdsStd()); Log.d(LOGTAG, "fmOn: LowerLimit :"+ config.getLowerLimit()); Log.d(LOGTAG, "fmOn: UpperLimit :"+ config.getUpperLimit()); + mEventReceived = false; bStatus = mReceiver.enable(FmSharedPreferences.getFMConfiguration(), this); + + if (mReceiver.isCherokeeChip()) { + bStatus = waitForEvent(); + } if (isSpeakerEnabled()) { setAudioPath(false); } else { @@ -2323,21 +2358,6 @@ public class FMRadioService extends Service if (mReceiver != null) { bStatus = mReceiver.disable(this); - if (bStatus && - (mReceiver.getFMState() == mReceiver.subPwrLevel_FMTurning_Off)) { - synchronized (mEventWaitLock) { - Log.d(LOGTAG, "waiting for disable event"); - try { - mEventWaitLock.wait(RADIO_TIMEOUT); - } catch (IllegalMonitorStateException e) { - Log.e(LOGTAG, "Exception caught while waiting for event"); - e.printStackTrace(); - } catch (InterruptedException ex) { - Log.e(LOGTAG, "Exception caught while waiting for event"); - ex.printStackTrace(); - } - } - } mReceiver = null; } fmOperationsOff(); @@ -2360,21 +2380,11 @@ public class FMRadioService extends Service // This will disable the FM radio device if (mReceiver != null) { + mEventReceived = false; bStatus = mReceiver.disable(this); if (bStatus && (mReceiver.getFMState() == mReceiver.subPwrLevel_FMTurning_Off)) { - synchronized (mEventWaitLock) { - Log.d(LOGTAG, "waiting for disable event"); - try { - mEventWaitLock.wait(RADIO_TIMEOUT); - } catch (IllegalMonitorStateException e) { - Log.e(LOGTAG, "Exception caught while waiting for event"); - e.printStackTrace(); - } catch (InterruptedException ex) { - Log.e(LOGTAG, "Exception caught while waiting for event"); - ex.printStackTrace(); - } - } + bStatus = waitForEvent(); } mReceiver = null; } @@ -3123,14 +3133,23 @@ public class FMRadioService extends Service public void FmRxEvEnableReceiver() { Log.d(LOGTAG, "FmRxEvEnableReceiver"); mReceiver.setRawRdsGrpMask(); + if (mReceiver != null && mReceiver.isCherokeeChip()) { + synchronized(mEventWaitLock) { + mEventReceived = true; + mEventWaitLock.notify(); + } + } } public void FmRxEvDisableReceiver() { Log.d(LOGTAG, "FmRxEvDisableReceiver"); mFMOn = false; FmSharedPreferences.clearTags(); - synchronized (mEventWaitLock) { - mEventWaitLock.notify(); + if (mReceiver != null && mReceiver.isCherokeeChip()) { + synchronized (mEventWaitLock) { + mEventReceived = true; + mEventWaitLock.notify(); + } } } public void FmRxEvRadioReset() diff --git a/jni/android_hardware_fm.cpp b/jni/android_hardware_fm.cpp index a780cbe7bc7c64c1b84ce7d95ba9f16b607a1467..3846589389b03012dd36bc02bfd4bf6993df0925 100644 --- a/jni/android_hardware_fm.cpp +++ b/jni/android_hardware_fm.cpp @@ -153,7 +153,6 @@ jmethodID method_getStnDbgParamCallback; static bool checkCallbackThread() { JNIEnv* env = AndroidRuntime::getJNIEnv(); - ALOGE("Callback env check fail: env: %p, callback: %p", env, mCallbackEnv); if (mCallbackEnv != env || mCallbackEnv == NULL) { ALOGE("Callback env check fail: env: %p, callback: %p", env, mCallbackEnv); @@ -176,18 +175,27 @@ void fm_enabled_cb() { void fm_tune_cb(int Freq) { ALOGD("TUNE:Freq:%d", Freq); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_tuneCallback, (jint) Freq); } void fm_seek_cmpl_cb(int Freq) { ALOGI("SEEK_CMPL: Freq: %d", Freq); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_seekCmplCallback, (jint) Freq); } void fm_scan_next_cb() { ALOGI("SCAN_NEXT"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_scanNxtCallback); } @@ -196,6 +204,9 @@ void fm_srch_list_cb(uint16_t *scan_tbl) ALOGI("SRCH_LIST"); jbyteArray srch_buffer = NULL; + if (!checkCallbackThread()) + return; + srch_buffer = mCallbackEnv->NewByteArray(STD_BUF_SIZE); if (srch_buffer == NULL) { ALOGE(" af list allocate failed :"); @@ -209,12 +220,18 @@ void fm_srch_list_cb(uint16_t *scan_tbl) void fm_stereo_status_cb(bool stereo) { ALOGI("STEREO: %d", stereo); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_stereostsCallback, (jboolean) stereo); } void fm_rds_avail_status_cb(bool rds_avl) { ALOGD("fm_rds_avail_status_cb: %d", rds_avl); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_rdsAvlStsCallback, (jboolean) rds_avl); } @@ -223,10 +240,8 @@ void fm_af_list_update_cb(uint16_t *af_list) ALOGD("AF_LIST"); jbyteArray af_buffer = NULL; - if (!checkCallbackThread()) { - ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); + if (!checkCallbackThread()) return; - } af_buffer = mCallbackEnv->NewByteArray(STD_BUF_SIZE); if (af_buffer == NULL) { @@ -245,10 +260,8 @@ void fm_rt_update_cb(char *rt) jbyteArray rt_buff = NULL; int i,len; - if (!checkCallbackThread()) { - ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); + if (!checkCallbackThread()) return; - } len = (int)(rt[0] & 0xFF); ALOGD(" rt data len=%d :",len); @@ -273,10 +286,8 @@ void fm_ps_update_cb(char *ps) jbyteArray ps_data = NULL; int i,len; int numPs; - if (!checkCallbackThread()) { - ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); + if (!checkCallbackThread()) return; - } numPs = (int)(ps[0] & 0xFF); len = (numPs *8)+5; @@ -307,6 +318,9 @@ void fm_rt_plus_update_cb(char *rt_plus) len = (int)(rt_plus[0] & 0xFF); ALOGD(" rt plus len=%d :",len); + if (!checkCallbackThread()) + return; + RtPlus = mCallbackEnv->NewByteArray(len); if (RtPlus == NULL) { ALOGE(" rt plus data allocate failed :"); @@ -323,10 +337,8 @@ void fm_ert_update_cb(char *ert) jbyteArray ert_buff = NULL; int i,len; - if (!checkCallbackThread()) { - ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); + if (!checkCallbackThread()) return; - } len = (int)(ert[0] & 0xFF); len = len+3; @@ -350,10 +362,8 @@ void fm_ext_country_code_cb(char *ecc) jbyteArray ecc_buff = NULL; int i,len; - if (!checkCallbackThread()) { - ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); + if (!checkCallbackThread()) return; - } len = (int)(ecc[0] & 0xFF); @@ -382,6 +392,9 @@ void rds_grp_cntrs_ext_rsp_cb(char * evt_buffer) void fm_disabled_cb() { ALOGE("DISABLE"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_disableCallback); } @@ -424,6 +437,9 @@ static void fm_get_sig_thres_cb(int val, int status) { ALOGD("Get signal Thres callback"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getSigThCallback, val, status); } @@ -431,6 +447,9 @@ static void fm_get_ch_det_thr_cb(int val, int status) { ALOGD("fm_get_ch_det_thr_cb"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getChDetThrCallback, val, status); } @@ -438,6 +457,9 @@ static void fm_set_ch_det_thr_cb(int status) { ALOGD("fm_set_ch_det_thr_cb"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_setChDetThrCallback, status); } @@ -445,6 +467,9 @@ static void fm_def_data_read_cb(int val, int status) { ALOGD("fm_def_data_read_cb"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_defDataRdCallback, val, status); } @@ -452,6 +477,9 @@ static void fm_def_data_write_cb(int status) { ALOGD("fm_def_data_write_cb"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_defDataWrtCallback, status); } @@ -459,6 +487,9 @@ static void fm_get_blend_cb(int val, int status) { ALOGD("fm_get_blend_cb"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getBlendCallback, val, status); } @@ -466,6 +497,9 @@ static void fm_set_blend_cb(int status) { ALOGD("fm_set_blend_cb"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_setBlendCallback, status); } @@ -473,6 +507,9 @@ static void fm_get_station_param_cb(int val, int status) { ALOGD("fm_get_station_param_cb"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getStnParamCallback, val, status); } @@ -480,6 +517,9 @@ static void fm_get_station_debug_param_cb(int val, int status) { ALOGD("fm_get_station_debug_param_cb"); + if (!checkCallbackThread()) + return; + mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getStnDbgParamCallback, val, status); } @@ -594,6 +634,7 @@ static jint android_hardware_fmradio_FmReceiverJNI_acquireFdNative snprintf(versionStr, sizeof(versionStr), "%d", cap.version); property_set("hw.fm.version", versionStr); } else { + close(fd); return FM_JNI_FAILURE; }