Merge "FM: Close the service and end the process on user switch"
diff --git a/fmapp2/src/com/caf/fmradio/FMRadio.java b/fmapp2/src/com/caf/fmradio/FMRadio.java
index 1da839b..d6cade4 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadio.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadio.java
@@ -3070,7 +3070,7 @@
private ServiceConnection osc = new ServiceConnection() {
public void onServiceConnected(ComponentName classname, IBinder obj) {
mService = IFMRadioService.Stub.asInterface(obj);
- Log.e(LOGTAG, "ServiceConnection: onServiceConnected: ");
+ Log.e(LOGTAG, "ServiceConnection: onServiceConnected");
if (mService != null) {
try {
mService.registerCallbacks(mServiceCallbacks);
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
index 4c0ef18..f605749 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadioService.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -99,6 +99,7 @@
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.os.IBinder.DeathRecipient;
/**
@@ -152,6 +153,11 @@
private boolean misAnalogPathEnabled = false;
private boolean mA2dpDisconnected = false;
private boolean mA2dpConnected = false;
+
+ //Install the death receipient
+ private IBinder.DeathRecipient mDeathRecipient;
+ private FMDeathRecipient mFMdr;
+
//PhoneStateListener instances corresponding to each
private FmRxRdsData mFMRxRDSData=null;
@@ -223,7 +229,9 @@
private static final int FM_OFF_FROM_APPLICATION = 1;
private static final int FM_OFF_FROM_ANTENNA = 2;
private static final int RADIO_TIMEOUT = 1500;
- private static final int RESET_SLIMBUS_DATA_PORT = 1;
+ private static final int DISABLE_SLIMBUS_DATA_PORT = 0;
+ private static final int ENABLE_SLIMBUS_DATA_PORT = 1;
+ private static final int ENABLE_SLIMBUS_CLOCK_DATA = 2;
private static Object mNotchFilterLock = new Object();
@@ -237,7 +245,7 @@
public void onCreate() {
super.onCreate();
- mFmA2dpDisabled = SystemProperties.getBoolean("fm.a2dp.conc.disabled",false);
+ mFmA2dpDisabled = SystemProperties.getBoolean("vendor.fm.a2dp.conc.disabled",false);
mPrefs = new FmSharedPreferences(this);
mCallbacks = null;
TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
@@ -913,12 +921,21 @@
mServiceInUse = true;
/* Application/UI is attached, so get out of lower power mode */
setLowPowerMode(false);
- Log.d(LOGTAG, "onBind");
+ Log.d(LOGTAG, "onBind ");
+ //todo check for the mBinder validity
+ mFMdr = new FMDeathRecipient(this, mBinder);
+ try {
+ mBinder.linkToDeath(mFMdr, 0);
+ Log.d(LOGTAG, "onBind mBinder linked to death" + mBinder);
+ } catch (RemoteException e) {
+ Log.e(LOGTAG,"LinktoDeath Exception: "+e + "FM DR =" + mFMdr);
+ }
return mBinder;
}
@Override
public void onRebind(Intent intent) {
+ Log.d(LOGTAG, "onRebind");
mDelayedStopHandler.removeCallbacksAndMessages(null);
cancelAlarmDealyedServiceStop();
mServiceInUse = true;
@@ -926,8 +943,9 @@
if (isFmOn()) {
setLowPowerMode(false);
startFM();
+ if (mReceiver.isCherokeeChip())
+ mReceiver.EnableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
}
- Log.d(LOGTAG, "onRebind");
}
@Override
@@ -943,14 +961,20 @@
@Override
public boolean onUnbind(Intent intent) {
- mServiceInUse = false;
- Log.d(LOGTAG, "onUnbind");
-
- /* Application/UI is not attached, so go into lower power mode */
- unregisterCallbacks();
- setLowPowerMode(true);
- return true;
- }
+ mServiceInUse = false;
+ Log.d(LOGTAG, "onUnbind");
+ /* Application/UI is not attached, so go into lower power mode */
+ unregisterCallbacks();
+ setLowPowerMode(true);
+ try{
+ Log.d(LOGTAG,"Unlinking FM Death receipient");
+ mBinder.unlinkToDeath(mFMdr,0);
+ }
+ catch(NoSuchElementException e){
+ Log.e(LOGTAG,"No death recipient registered"+e);
+ }
+ return true;
+ }
private String getProcessName() {
int id = Process.myPid();
@@ -1591,7 +1615,7 @@
private Runnable mSpeakerDisableTask = new Runnable() {
public void run() {
- Log.v(LOGTAG, "Disabling Speaker");
+ Log.v(LOGTAG, "*** Disabling Speaker");
AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_NONE);
}
};
@@ -1637,23 +1661,33 @@
stopRecording();
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
+ if (mSpeakerPhoneOn) {
+ Log.v(LOGTAG, "Focus Loss/TLoss - Disabling speaker");
+ AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_NONE);
+ }
if (mReceiver != null)
- mReceiver.EnableSlimbus(RESET_SLIMBUS_DATA_PORT);
+ mReceiver.EnableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
if (true == mPlaybackInProgress) {
stopFM();
}
+ mReceiver.EnableSlimbus(DISABLE_SLIMBUS_DATA_PORT);
mStoppedOnFocusLoss = true;
break;
case AudioManager.AUDIOFOCUS_LOSS:
- Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_LOSS");
+ Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_LOSS mspeakerphone= " +
+ mSpeakerPhoneOn);
//intentional fall through.
if (mSpeakerPhoneOn) {
- mSpeakerDisableHandler.removeCallbacks(mSpeakerDisableTask);
- mSpeakerDisableHandler.postDelayed(mSpeakerDisableTask, 0);
+ mSpeakerDisableHandler.removeCallbacks(mSpeakerDisableTask);
+ mSpeakerDisableHandler.postDelayed(mSpeakerDisableTask, 0);
}
if (true == mPlaybackInProgress) {
stopFM();
}
+
+ //intentional fall through.
+ mReceiver.EnableSlimbus(DISABLE_SLIMBUS_DATA_PORT);
+
if (true == isFmRecordingOn())
stopRecording();
@@ -1665,15 +1699,19 @@
mSession.setActive(false);
break;
case AudioManager.AUDIOFOCUS_GAIN:
- Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_GAIN");
+ Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_GAIN mPlaybackinprogress =" +
+ mPlaybackInProgress);
mStoppedOnFocusLoss = false;
if (mResumeAfterCall) {
Log.v(LOGTAG, "resumeAfterCall");
resumeAfterCall();
break;
}
+
if(false == mPlaybackInProgress)
startFM();
+
+ mReceiver.EnableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
mSession.setActive(true);
break;
default:
@@ -1754,7 +1792,7 @@
NotificationChannel notificationChannel =
new NotificationChannel(FMRADIO_NOTIFICATION_CHANNEL,
context.getString(R.string.app_name),
- NotificationManager.IMPORTANCE_HIGH);
+ NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(notificationChannel);
@@ -1766,8 +1804,7 @@
.setOngoing(true)
.build();
- notificationManager.notify(FMRADIOSERVICE_STATUS, notification);
-
+ startForeground(FMRADIOSERVICE_STATUS, notification);
mFMOn = true;
}
@@ -2215,60 +2252,27 @@
return status;
}
- /*
- * Turn ON FM: Powers up FM hardware, and initializes the FM module
- * .
- * @return true if fm Enable api was invoked successfully, false if the api failed.
- */
- private boolean fmOn() {
- boolean bStatus=false;
- mWakeLock.acquire(10*1000);
- if ( TelephonyManager.CALL_STATE_IDLE != getCallState() ) {
- return bStatus;
- }
+ private boolean fmTurnOnSequence () {
+ boolean bStatus = false;
+ // This sets up the FM radio device
+ FmConfig config = FmSharedPreferences.getFMConfiguration();
- if(mReceiver == null)
- {
- try {
- mReceiver = new FmReceiver(FMRADIO_DEVICE_FD_STRING, fmCallbacks);
- }
- catch (InstantiationException e)
- {
- throw new RuntimeException("FmReceiver service not available!");
- }
- }
+ Log.d(LOGTAG, "fmOn: RadioBand :"+ config.getRadioBand());
+ Log.d(LOGTAG, "fmOn: Emphasis :"+ config.getEmphasis());
+ Log.d(LOGTAG, "fmOn: ChSpacing :"+ config.getChSpacing());
+ Log.d(LOGTAG, "fmOn: RdsStd :"+ config.getRdsStd());
+ Log.d(LOGTAG, "fmOn: LowerLimit :"+ config.getLowerLimit());
+ Log.d(LOGTAG, "fmOn: UpperLimit :"+ config.getUpperLimit());
- if (mReceiver != null)
- {
- if (isFmOn())
- {
- /* FM Is already on,*/
- bStatus = true;
- Log.d(LOGTAG, "mReceiver.already enabled");
- }
- else
- {
- // This sets up the FM radio device
- FmConfig config = FmSharedPreferences.getFMConfiguration();
- Log.d(LOGTAG, "fmOn: RadioBand :"+ config.getRadioBand());
- Log.d(LOGTAG, "fmOn: Emphasis :"+ config.getEmphasis());
- Log.d(LOGTAG, "fmOn: ChSpacing :"+ config.getChSpacing());
- 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);
+ mEventReceived = false;
+ bStatus = mReceiver.enable(FmSharedPreferences.getFMConfiguration(), this);
- if (mReceiver.isCherokeeChip()) {
- bStatus = waitForEvent();
- }
- if (isSpeakerEnabled()) {
- setAudioPath(false);
- } else {
- setAudioPath(true);
- }
- Log.d(LOGTAG, "mReceiver.enable done, Status :" + bStatus);
- }
+ if (isSpeakerEnabled()) {
+ setAudioPath(false);
+ } else {
+ setAudioPath(true);
+ }
+ Log.d(LOGTAG, "mReceiver.enable done, Status :" + bStatus);
if (bStatus == true)
{
@@ -2323,8 +2327,141 @@
stop();
}
- /* reset SSR flag */
- mIsSSRInProgressFromActivity = false;
+ return bStatus;
+ }
+
+ /*
+ * Turn ON FM: Powers up FM hardware, and initializes the FM module
+ * .
+ * @return true if fm Enable api was invoked successfully, false if the api failed.
+ */
+ private boolean fmTurnOnSequenceCherokee () {
+ boolean bStatus = false;
+
+ // Send command to power up SB slave block
+ mEventReceived = false;
+ mReceiver.EnableSlimbus(ENABLE_SLIMBUS_CLOCK_DATA);
+ bStatus = waitForEvent();
+
+ // Send command to enable FM core
+ mEventReceived = false;
+ mReceiver.EnableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
+ bStatus = waitForEvent();
+
+ AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ if ((audioManager != null) & (false == mPlaybackInProgress)) {
+ Log.d(LOGTAG, "mAudioManager.setFmRadioOn = true \n" );
+ int state = getCallState();
+ if (TelephonyManager.CALL_STATE_IDLE != getCallState())
+ {
+ fmActionOnCallState(state);
+ } else {
+ startFM(); // enable FM Audio only when Call is IDLE
+ }
+ Log.d(LOGTAG, "mAudioManager.setFmRadioOn done \n" );
+ }
+
+ // This sets up the FM radio device
+ FmConfig config = FmSharedPreferences.getFMConfiguration();
+ Log.d(LOGTAG, "fmOn: RadioBand :"+ config.getRadioBand());
+ Log.d(LOGTAG, "fmOn: Emphasis :"+ config.getEmphasis());
+ Log.d(LOGTAG, "fmOn: ChSpacing :"+ config.getChSpacing());
+ Log.d(LOGTAG, "fmOn: RdsStd :"+ config.getRdsStd());
+ Log.d(LOGTAG, "fmOn: LowerLimit :"+ config.getLowerLimit());
+ Log.d(LOGTAG, "fmOn: UpperLimit :"+ config.getUpperLimit());
+
+ // Enable FM receiver
+ mEventReceived = false;
+ bStatus = mReceiver.enable(FmSharedPreferences.getFMConfiguration(), this);
+ bStatus = waitForEvent();
+
+ if (isSpeakerEnabled()) {
+ setAudioPath(false);
+ } else {
+ setAudioPath(true);
+ }
+ Log.d(LOGTAG, "mReceiver.enable done, Status :" + bStatus);
+
+ if (bStatus == true) {
+ /* Put the hardware into normal mode */
+ bStatus = setLowPowerMode(false);
+ Log.d(LOGTAG, "setLowPowerMode done, Status :" + bStatus);
+
+ if (mReceiver != null) {
+ bStatus = mReceiver.registerRdsGroupProcessing(FmReceiver.FM_RX_RDS_GRP_RT_EBL|
+ FmReceiver.FM_RX_RDS_GRP_PS_EBL|
+ FmReceiver.FM_RX_RDS_GRP_AF_EBL|
+ FmReceiver.FM_RX_RDS_GRP_PS_SIMPLE_EBL|
+ FmReceiver.FM_RX_RDS_GRP_ECC_EBL|
+ FmReceiver.FM_RX_RDS_GRP_PTYN_EBL|
+ FmReceiver.FM_RX_RDS_GRP_RT_PLUS_EBL);
+ Log.d(LOGTAG, "registerRdsGroupProcessing done, Status :" + bStatus);
+ }
+ bStatus = enableAutoAF(FmSharedPreferences.getAutoAFSwitch());
+ Log.d(LOGTAG, "enableAutoAF done, Status :" + bStatus);
+
+ /* There is no internal Antenna*/
+ bStatus = mReceiver.setInternalAntenna(false);
+ Log.d(LOGTAG, "setInternalAntenna done, Status :" + bStatus);
+
+ /* Read back to verify the internal Antenna mode*/
+ readInternalAntennaAvailable();
+
+ startNotification();
+ bStatus = true;
+ } else {
+ mReceiver = null; // as enable failed no need to disable
+ // failure of enable can be because handle
+ // already open which gets effected if
+ // we disable
+ stop();
+ }
+
+ return bStatus;
+ }
+
+ /*
+ * Turn ON FM: Powers up FM hardware, and initializes the FM module
+ * .
+ * @return true if fm Enable api was invoked successfully, false if the api failed.
+ */
+ private boolean fmOn () {
+ boolean bStatus = false;
+ mWakeLock.acquire(10*1000);
+
+ if (TelephonyManager.CALL_STATE_IDLE != getCallState()) {
+ return bStatus;
+ }
+
+ if (mReceiver == null)
+ {
+ try {
+ mReceiver = new FmReceiver(FMRADIO_DEVICE_FD_STRING, fmCallbacks);
+ }
+ catch (InstantiationException e)
+ {
+ throw new RuntimeException("FmReceiver service not available!");
+ }
+ }
+
+ if (mReceiver != null)
+ {
+ if (isFmOn())
+ {
+ /* FM Is already on,*/
+ bStatus = true;
+ Log.d(LOGTAG, "mReceiver.already enabled");
+ }
+ else
+ {
+ if (mReceiver.isCherokeeChip()) {
+ bStatus = fmTurnOnSequenceCherokee();
+ } else {
+ bStatus = fmTurnOnSequence();
+ }
+ /* reset SSR flag */
+ mIsSSRInProgressFromActivity = false;
+ }
}
return(bStatus);
}
@@ -3197,7 +3334,8 @@
/* Receiver callbacks back from the FM Stack */
FmRxEvCallbacksAdaptor fmCallbacks = new FmRxEvCallbacksAdaptor()
{
- public void FmRxEvEnableReceiver() {
+ public void FmRxEvEnableReceiver()
+ {
Log.d(LOGTAG, "FmRxEvEnableReceiver");
mReceiver.setRawRdsGrpMask();
if (mReceiver != null && mReceiver.isCherokeeChip()) {
@@ -3652,6 +3790,16 @@
{
Log.d(LOGTAG, "FmRxEvRdsPiMatchRegDone");
}
+ public void FmRxEvEnableSlimbus(int status)
+ {
+ Log.e(LOGTAG, "FmRxEvEnableSlimbus status = " + status);
+ if (mReceiver != null && mReceiver.isCherokeeChip()) {
+ synchronized(mEventWaitLock) {
+ mEventReceived = true;
+ mEventWaitLock.notify();
+ }
+ }
+ }
};
@@ -3912,7 +4060,8 @@
else
cancelAlarmRecordTimeout();
}
- private void requestFocus() {
+
+ private void requestFocusImpl() {
if( (false == mPlaybackInProgress) &&
(true == mStoppedOnFocusLoss) && isFmOn()) {
// adding code for audio focus gain.
@@ -3923,6 +4072,33 @@
mStoppedOnFocusLoss = false;
}
}
+
+ private void requestFocusImplCherokee() {
+ Log.d(LOGTAG, "++requestFocusImplCherokee mPlaybackInProgress: " +
+ mPlaybackInProgress + " mStoppedOnFocusLoss: " +
+ mStoppedOnFocusLoss + " isFmOn: " + isFmOn());
+ if( (false == mPlaybackInProgress) &&
+ (true == mStoppedOnFocusLoss) && isFmOn()) {
+ // adding code for audio focus gain.
+ AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ audioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+ startFM();
+ mReceiver.EnableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
+ mStoppedOnFocusLoss = false;
+ }
+ }
+
+ private void requestFocus() {
+ Log.d(LOGTAG, "++requestFocus");
+ if (mReceiver.isCherokeeChip()) {
+ requestFocusImplCherokee();
+ } else {
+ requestFocusImpl();
+ }
+ Log.d(LOGTAG, "--requestFocus");
+ }
+
private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() {
public void onAudioFocusChange(int focusChange) {
mDelayedStopHandler.obtainMessage(FOCUSCHANGE, focusChange, 0).sendToTarget();
@@ -3964,4 +4140,14 @@
private void restoreDefaults () {
mStoppedOnFactoryReset = true;
}
+
+
+ class FMDeathRecipient implements IBinder.DeathRecipient {
+ public FMDeathRecipient(FMRadioService service, IBinder binder) {
+ }
+ public void binderDied() {
+ Log.d(LOGTAG, "** Binder is dead - cleanup audio now ** ");
+ //TODO unregister the fm service here.
+ }
+ }
}
diff --git a/fmapp2/src/com/caf/fmradio/FMTransmitterService.java b/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
index e3cf3d6..1d964c4 100644
--- a/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
+++ b/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
@@ -1018,6 +1018,11 @@
e.printStackTrace();
}
}
+
+ public void FmRxEvEnableSlimbus(int status)
+ {
+ Log.d(LOGTAG, "FmRxEvEnableReceiver status = " + status);
+ }
};
diff --git a/helium/radio-helium.h b/helium/radio-helium.h
index 200e006..79f61bd 100644
--- a/helium/radio-helium.h
+++ b/helium/radio-helium.h
@@ -171,6 +171,7 @@
typedef void (*fm_set_blnd_cb) (int status);
typedef void (*fm_get_stn_prm_cb) (int val, int status);
typedef void (*fm_get_stn_dbg_prm_cb) (int val, int status);
+typedef void (*fm_enable_slimbus_cb) (int status);
typedef struct {
size_t size;
@@ -206,6 +207,7 @@
fm_set_blnd_cb fm_set_blend_cb;
fm_get_stn_prm_cb fm_get_station_param_cb;
fm_get_stn_dbg_prm_cb fm_get_station_debug_param_cb;
+ fm_enable_slimbus_cb enable_slimbus_cb;
} fm_hal_callbacks_t;
/* Opcode OCF */
diff --git a/helium/radio_helium_hal.c b/helium/radio_helium_hal.c
index 1109ca3..a25d888 100644
--- a/helium/radio_helium_hal.c
+++ b/helium/radio_helium_hal.c
@@ -79,7 +79,6 @@
return;
}
rsp = (struct hci_fm_conf_rsp *)ev_rsp;
- hal->jni_cb->thread_evt_cb(0);
radio_hci_req_complete(rsp->status);
hal->jni_cb->enabled_cb();
if (rsp->status == FM_HC_STATUS_SUCCESS)
@@ -394,6 +393,13 @@
clear_all_bit(station_dbg_param_mask_flag);
}
+static void hci_cc_enable_slimbus_rsp(char *ev_buff)
+{
+ ALOGV("%s status %d", __func__, ev_buff[0]);
+ hal->jni_cb->thread_evt_cb(0);
+ hal->jni_cb->enable_slimbus_cb(ev_buff[0]);
+}
+
static inline void hci_cmd_complete_event(char *buff)
{
uint16_t opcode;
@@ -491,6 +497,10 @@
hci_cc_dbg_param_rsp(pbuf);
break;
+ case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_ENABLE_SLIMBUS):
+ hci_cc_enable_slimbus_rsp(pbuf);
+ break;
+
/* case hci_common_cmd_op_pack(HCI_OCF_FM_GET_SPUR_TABLE):
hci_cc_get_spur_tbl(buff);
break;
diff --git a/jni/Android.mk b/jni/Android.mk
index d3df8b9..32382e8 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -27,5 +27,17 @@
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := init.qti.fm.sh
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_EXECUTABLES)
+
+LOCAL_INIT_RC := init.qti.fm.rc
+
+include $(BUILD_PREBUILT)
+
endif # is-vendor-board-platform
endif # BOARD_HAVE_QCOM_FM
diff --git a/jni/android_hardware_fm.cpp b/jni/android_hardware_fm.cpp
index 516e0e4..06d03ce 100644
--- a/jni/android_hardware_fm.cpp
+++ b/jni/android_hardware_fm.cpp
@@ -120,9 +120,11 @@
typedef void (*fm_set_blnd_cb) (int status);
typedef void (*fm_get_stn_prm_cb) (int val, int status);
typedef void (*fm_get_stn_dbg_prm_cb) (int val, int status);
+typedef void (*fm_enable_sb_cb) (int status);
static JNIEnv *mCallbackEnv = NULL;
static jobject mCallbacksObj = NULL;
+static bool mCallbacksObjCreated = false;
static jfieldID sCallbacksField;
jclass javaClassRef;
@@ -150,6 +152,7 @@
jmethodID method_setBlendCallback;
jmethodID method_getStnParamCallback;
jmethodID method_getStnDbgParamCallback;
+jmethodID method_enableSlimbusCallback;
static bool checkCallbackThread() {
JNIEnv* env = AndroidRuntime::getJNIEnv();
@@ -163,12 +166,11 @@
void fm_enabled_cb() {
ALOGD("Entered %s", __func__);
- if (mCallbackEnv != NULL) {
- ALOGE("javaObjectRef creating");
- jobject javaObjectRef = mCallbackEnv->NewObject(javaClassRef, method_enableCallback);
- mCallbacksObj = javaObjectRef;
- ALOGE("javaObjectRef = %p mCallbackobject =%p \n",javaObjectRef,mCallbacksObj);
- }
+
+ if (!checkCallbackThread())
+ return;
+
+ mCallbackEnv->CallVoidMethod(mCallbacksObj, method_enableCallback);
ALOGD("exit %s", __func__);
}
@@ -396,6 +398,7 @@
return;
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_disableCallback);
+ mCallbacksObjCreated = false;
}
void fm_peek_rsp_cb(char *peek_rsp) {
@@ -523,6 +526,24 @@
mCallbackEnv->CallVoidMethod(mCallbacksObj, method_getStnDbgParamCallback, val, status);
}
+static void fm_enable_slimbus_cb(int status)
+{
+ ALOGD("++fm_enable_slimbus_cb mCallbacksObjCreated: %d", mCallbacksObjCreated);
+
+ if (mCallbacksObjCreated == false) {
+ jobject javaObjectRef = mCallbackEnv->NewObject(javaClassRef, method_enableSlimbusCallback);
+ mCallbacksObj = javaObjectRef;
+ mCallbacksObjCreated = true;
+ return;
+ }
+
+ if (!checkCallbackThread())
+ return;
+
+ mCallbackEnv->CallVoidMethod(mCallbacksObj, method_enableSlimbusCallback, status);
+ ALOGV("--fm_enable_slimbus_cb");
+}
+
typedef struct {
size_t size;
@@ -557,6 +578,7 @@
fm_set_blnd_cb fm_set_blend_cb;
fm_get_stn_prm_cb fm_get_station_param_cb;
fm_get_stn_dbg_prm_cb fm_get_station_debug_param_cb;
+ fm_enable_sb_cb fm_enable_slimbus_cb;
} fm_vendor_callbacks_t;
typedef struct {
@@ -598,7 +620,8 @@
fm_def_data_write_cb,
fm_set_blend_cb,
fm_get_station_param_cb,
- fm_get_station_debug_param_cb
+ fm_get_station_debug_param_cb,
+ fm_enable_slimbus_cb
};
#endif
/* native interface */
@@ -1593,6 +1616,7 @@
method_setBlendCallback = env->GetMethodID(javaClassRef, "setBlendCallback", "(I)V");
method_getStnParamCallback = env->GetMethodID(javaClassRef, "getStnParamCallback", "(II)V");
method_getStnDbgParamCallback = env->GetMethodID(javaClassRef, "getStnDbgParamCallback", "(II)V");
+ method_enableSlimbusCallback = env->GetMethodID(javaClassRef, "enableSlimbusCallback", "(I)V");
return;
error:
@@ -1621,6 +1645,7 @@
mCallbacksObj = env->NewGlobalRef(object);
#endif
}
+
static void cleanupNative(JNIEnv *env, jobject object) {
#ifdef FM_SOC_TYPE_CHEROKEE
diff --git a/jni/init.qti.fm.rc b/jni/init.qti.fm.rc
new file mode 100644
index 0000000..5d52259
--- /dev/null
+++ b/jni/init.qti.fm.rc
@@ -0,0 +1,6 @@
+service fm_dl /vendor/bin/init.qti.fm.sh
+ class late_start
+ user system
+ group system
+ disabled
+ oneshot
diff --git a/jni/init.qti.fm.sh b/jni/init.qti.fm.sh
new file mode 100644
index 0000000..e484753
--- /dev/null
+++ b/jni/init.qti.fm.sh
@@ -0,0 +1,90 @@
+#!/vendor/bin/sh
+# Copyright (c) 2009-2011, 2015, 2017 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.
+#
+
+setprop hw.fm.init 0
+
+mode=`getprop hw.fm.mode`
+version=199217
+
+LOG_TAG="qti-fm"
+LOG_NAME="${0}:"
+
+loge ()
+{
+ /vendor/bin/log -t $LOG_TAG -p e "$LOG_NAME $@"
+}
+
+logi ()
+{
+ /vendor/bin/log -t $LOG_TAG -p i "$LOG_NAME $@"
+}
+
+failed ()
+{
+ loge "$1: exit code $2"
+ exit $2
+}
+
+logi "In FM shell Script"
+logi "mode: $mode"
+logi "Version : $version"
+
+#$fm_qsoc_patches <fm_chipVersion> <enable/disable WCM>
+#
+case $mode in
+ "normal")
+ logi "inserting the radio transport module"
+ echo 1 > /sys/module/radio_iris_transport/parameters/fmsmd_set
+ /vendor/bin/fm_qsoc_patches $version 0
+ ;;
+ "wa_enable")
+ /vendor/bin/fm_qsoc_patches $version 1
+ ;;
+ "wa_disable")
+ /vendor/bin/fm_qsoc_patches $version 2
+ ;;
+ *)
+ logi "Shell: Default case"
+ /vendor/bin/fm_qsoc_patches $version 0
+ ;;
+esac
+
+exit_code_fm_qsoc_patches=$?
+
+case $exit_code_fm_qsoc_patches in
+ 0)
+ logi "FM QSoC calibration and firmware download succeeded"
+ ;;
+ *)
+ failed "FM QSoC firmware download and/or calibration failed" $exit_code_fm_qsoc_patches
+ ;;
+esac
+
+setprop hw.fm.init 1
+
+exit 0
diff --git a/qcom/fmradio/FmReceiverJNI.java b/qcom/fmradio/FmReceiverJNI.java
index d9fa79a..1487b7c 100644
--- a/qcom/fmradio/FmReceiverJNI.java
+++ b/qcom/fmradio/FmReceiverJNI.java
@@ -127,6 +127,13 @@
FmReceiver.mCallback.FmRxGetStationDbgParam(val, status);
}
+ public void enableSlimbusCallback(int status)
+ {
+ Log.d(TAG, "++enableSlimbusCallback" );
+ FmReceiver.mCallback.FmRxEvEnableSlimbus(status);
+ Log.d(TAG, "--enableSlimbusCallback" );
+ }
+
public void RtPlusCallback(byte[] rtplus) {
Log.d(TAG, "RtPlusCallback enter " );
if (rtplus == null) {
diff --git a/qcom/fmradio/FmRxEvCallbacks.java b/qcom/fmradio/FmRxEvCallbacks.java
index 267d73d..31a8312 100644
--- a/qcom/fmradio/FmRxEvCallbacks.java
+++ b/qcom/fmradio/FmRxEvCallbacks.java
@@ -47,4 +47,5 @@
public void FmRxEvRTPlus();
public void FmRxEvERTInfo();
public void FmRxEvECCInfo();
+ public void FmRxEvEnableSlimbus(int status);
}
diff --git a/qcom/fmradio/FmRxEvCallbacksAdaptor.java b/qcom/fmradio/FmRxEvCallbacksAdaptor.java
index 59953e8..213cf43 100644
--- a/qcom/fmradio/FmRxEvCallbacksAdaptor.java
+++ b/qcom/fmradio/FmRxEvCallbacksAdaptor.java
@@ -61,4 +61,5 @@
public void FmRxEvSetBlend(int status) {};
public void FmRxGetStationParam(int val, int status) {};
public void FmRxGetStationDbgParam(int val, int status) {};
+ public void FmRxEvEnableSlimbus(int status) {};
}