Promotion of fm.lnx.2.1-00033.
CRs Change ID Subject
--------------------------------------------------------------------------------------------------------------
2015038 Ia3fe9c6fb67d5c94bdd8d3a147ea8776bdc5fa3a fm: Fix for NULL pointer exception
2017967 I6bdc7f13afd024be8d3428c83f7117277affc45f fm: Resume FM after telephony state become idle
2013327 I4751988149863be0af60fc5cfd268b91afbb685f FM: Reset slimbus port on AUDIOFOCUS_LOSS_TRANSIENT_CAN_
2011072 Iac42f8f4f1f90c2c5860d90068e09d01638bff80 FM: Fix static analysis issue
2019842 Ia5030308c35f41297ff19079f38e735e962770b2 fm: wait for enable event to complete
Change-Id: I8f73033ae6fb132d94be092caaa55e7a2a984d54
CRs-Fixed: 2011072, 2019842, 2015038, 2017967, 2013327
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
index 52f9f77..6588571 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadioService.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -224,6 +224,7 @@
private static Object mNotchFilterLock = new Object();
private boolean mFmA2dpDisabled;
+ private boolean mEventReceived = false;
public FMRadioService() {
}
@@ -1448,31 +1449,33 @@
resolver.insert(uri, values);
}
- private void resumeAfterCall() {
- if (getCallState() != TelephonyManager.CALL_STATE_IDLE)
- return;
-
- // start playing again
- if (!mResumeAfterCall)
- 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()) {
+ Runnable resumeAfterCall = new Runnable() {
+ public void run() {
+ if (getCallState() != TelephonyManager.CALL_STATE_IDLE)
return;
- }
- mResumeAfterCall = false;
- if (mCallbacks != null) {
- try {
- mCallbacks.onEnabled();
- } catch (RemoteException e) {
- e.printStackTrace();
+
+ // start playing again
+ if (!mResumeAfterCall)
+ 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()) {
+ 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 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 a780cbe..3846589 100644
--- a/jni/android_hardware_fm.cpp
+++ b/jni/android_hardware_fm.cpp
@@ -153,7 +153,6 @@
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_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 @@
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_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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 fm_disabled_cb()
{
ALOGE("DISABLE");
+ if (!checkCallbackThread())
+ return;
+
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_disableCallback);
}
@@ -424,6 +437,9 @@
{
ALOGD("Get signal Thres callback");
+ if (!checkCallbackThread())
+ return;
+
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getSigThCallback, val, status);
}
@@ -431,6 +447,9 @@
{
ALOGD("fm_get_ch_det_thr_cb");
+ if (!checkCallbackThread())
+ return;
+
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getChDetThrCallback, val, status);
}
@@ -438,6 +457,9 @@
{
ALOGD("fm_set_ch_det_thr_cb");
+ if (!checkCallbackThread())
+ return;
+
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_setChDetThrCallback, status);
}
@@ -445,6 +467,9 @@
{
ALOGD("fm_def_data_read_cb");
+ if (!checkCallbackThread())
+ return;
+
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_defDataRdCallback, val, status);
}
@@ -452,6 +477,9 @@
{
ALOGD("fm_def_data_write_cb");
+ if (!checkCallbackThread())
+ return;
+
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_defDataWrtCallback, status);
}
@@ -459,6 +487,9 @@
{
ALOGD("fm_get_blend_cb");
+ if (!checkCallbackThread())
+ return;
+
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getBlendCallback, val, status);
}
@@ -466,6 +497,9 @@
{
ALOGD("fm_set_blend_cb");
+ if (!checkCallbackThread())
+ return;
+
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_setBlendCallback, status);
}
@@ -473,6 +507,9 @@
{
ALOGD("fm_get_station_param_cb");
+ if (!checkCallbackThread())
+ return;
+
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getStnParamCallback, val, status);
}
@@ -480,6 +517,9 @@
{
ALOGD("fm_get_station_debug_param_cb");
+ if (!checkCallbackThread())
+ return;
+
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getStnDbgParamCallback, val, status);
}
@@ -594,6 +634,7 @@
snprintf(versionStr, sizeof(versionStr), "%d", cap.version);
property_set("hw.fm.version", versionStr);
} else {
+ close(fd);
return FM_JNI_FAILURE;
}