Merge remote-tracking branch 'origin/fm.lnx.2.1-rel' into fm.lnx.2.9.1-rel

Change-Id: I9d61fbe8961676660c08a02ddf377894baf0e203
diff --git a/fm_hci/fm_hci.c b/fm_hci/fm_hci.c
index c48edd5..9d0dafc 100644
--- a/fm_hci/fm_hci.c
+++ b/fm_hci/fm_hci.c
@@ -229,7 +229,6 @@
                             pthread_cond_signal(&hci->cmd_credits_cond);
                         } else if (pbuf->evt_code == FM_HW_ERR_EVENT) {
                               ALOGI("%s: FM H/w Err Event Recvd. Event Code: 0x%2x", __func__, pbuf->evt_code);
-                              lib_running =0;
                               hci->vendor->ssr_cleanup(0x22);
                               status  = power(hci, FM_RADIO_DISABLE);
                               if (status < 0) {
@@ -677,6 +676,12 @@
         return;
     }
     event_notification(hci, HC_EVENT_EXIT);
+    pthread_mutex_lock(&hci->event_lock);
+again:
+    pthread_cond_wait(&hci->event_cond, &hci->event_lock);
+    if (!(ready_events & HC_EVENT_EXIT_DONE))
+        goto again;
+    pthread_mutex_unlock(&hci->event_lock);
 }
 
 int fm_hci_init(fm_hci_hal_t *hci_hal)
@@ -785,6 +790,7 @@
     vendor_close(hci);
     pthread_cond_broadcast(&hci->event_cond);
     pthread_cond_broadcast(&hci->cmd_credits_cond);
+    event_notification(hci, HC_EVENT_EXIT_DONE);
     stop_rx_thread(hci);
     stop_tx_thread(hci);
     ALOGD("Tx, Rx Threads join done");
diff --git a/fm_hci/fm_hci.h b/fm_hci/fm_hci.h
index 8818068..2cfb30e 100644
--- a/fm_hci/fm_hci.h
+++ b/fm_hci/fm_hci.h
@@ -46,6 +46,7 @@
 #define HC_EVENT_LPM_IDLE_TIMEOUT      0x0100
 #define HC_EVENT_EXIT                  0x0200
 #define HC_EVENT_EPILOG                0x0400
+#define HC_EVENT_EXIT_DONE             0x8000
 
 #define MAX_FM_CMD_CNT                 100
 #define FM_CMD                         0x11
diff --git a/fmapp2/res/layout/rename_dialog.xml b/fmapp2/res/layout/rename_dialog.xml
index 2374c9c..bef5432 100644
--- a/fmapp2/res/layout/rename_dialog.xml
+++ b/fmapp2/res/layout/rename_dialog.xml
@@ -40,7 +40,6 @@
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:inputType="text"
-        android:textColor="#FFF"
         android:singleLine="true"
         android:maxLength="16">
      <requestFocus />
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
index 54654fa..76904eb 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadioService.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -156,7 +156,7 @@
    private File mA2DPSampleFile = null;
    //Track FM playback for reenter App usecases
    private boolean mPlaybackInProgress = false;
-   private boolean mStoppedOnFocusLoss = false;
+   private boolean mStoppedOnFocusLoss = true;
    private boolean mStoppedOnFactoryReset = false;
    private File mSampleFile = null;
    long mSampleStart = 0;
@@ -219,9 +219,13 @@
    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 Object mNotchFilterLock = new Object();
 
+   private boolean mFmA2dpDisabled;
+   private boolean mEventReceived = false;
+
    public FMRadioService() {
    }
 
@@ -229,6 +233,7 @@
    public void onCreate() {
       super.onCreate();
 
+      mFmA2dpDisabled = SystemProperties.getBoolean("fm.a2dp.conc.disabled",false);
       mPrefs = new FmSharedPreferences(this);
       mCallbacks = null;
       TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
@@ -253,7 +258,6 @@
       mSession.setFlags(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY |
                              MediaSession.FLAG_HANDLES_MEDIA_BUTTONS);
       mSession.setActive(true);
-      registerAudioBecomeNoisy();
       if ( false == SystemProperties.getBoolean("ro.fm.mulinst.recording.support",true)) {
            mSingleRecordingInstanceSupported = true;
       }
@@ -270,7 +274,8 @@
       mA2dpDeviceSupportInHal = valueStr.contains("=true");
       Log.d(LOGTAG, " is A2DP device Supported In HAL"+mA2dpDeviceSupportInHal);
 
-      getA2dpStatusAtStart();
+      if (!mFmA2dpDisabled)
+          getA2dpStatusAtStart();
    }
 
    @Override
@@ -608,7 +613,6 @@
      */
     public void registerHeadsetListener() {
         if (mHeadsetReceiver == null) {
-            boolean fm_a2dp_disabled = SystemProperties.getBoolean("fm.a2dp.conc.disabled",true);
             mHeadsetReceiver = new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
@@ -683,7 +687,7 @@
             AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
             IntentFilter iFilter = new IntentFilter();
             iFilter.addAction(Intent.ACTION_HEADSET_PLUG);
-            if (!fm_a2dp_disabled) {
+            if (!mFmA2dpDisabled) {
                 iFilter.addAction(mA2dpDeviceState.getActionSinkStateChangedString());
             }
             iFilter.addAction("HDMI_CONNECTED");
@@ -741,8 +745,10 @@
                         Log.d(LOGTAG, "Music Service command : "+cmd+ " received");
                         if (cmd != null && cmd.equals("pause")) {
                             if (isFmOn()) {
-                                fmOperationsOff();
-                                mStoppedOnFocusLoss = true;
+                                AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+                                audioManager.abandonAudioFocus(mAudioFocusListener);
+                                mDelayedStopHandler.obtainMessage(FOCUSCHANGE, AudioManager.AUDIOFOCUS_LOSS, 0).sendToTarget();
+
                                 if (isOrderedBroadcast()) {
                                     abortBroadcast();
                                 }
@@ -1052,12 +1058,14 @@
            return;
        }
 
-       AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-       int granted = audioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
-              AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
-       if(granted != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
-          Log.d(LOGTAG, "audio focuss couldnot be granted");
-          return;
+       if (mStoppedOnFocusLoss) {
+           AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+           int granted = audioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
+                   AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+           if (granted != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
+               Log.d(LOGTAG, "audio focuss couldnot be granted");
+               return;
+           }
        }
        mSession.setActive(true);
 
@@ -1104,6 +1112,7 @@
    private void resetFM(){
        Log.d(LOGTAG, "resetFM");
        mPlaybackInProgress = false;
+       configureAudioDataPath(false);
    }
 
    private boolean getRecordServiceStatus() {
@@ -1440,6 +1449,32 @@
        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()) {
+                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
    //any. Similarly once call is ended FM should be unmuted.
@@ -1470,50 +1505,9 @@
                mCallStatus = bTempCall;
                mMuted = bTempMute;
            }
+       } else if (TelephonyManager.CALL_STATE_IDLE == state) {
+           resumeAfterCall();
        }
-       else if (state == TelephonyManager.CALL_STATE_IDLE) {
-          // start playing again
-          if (mResumeAfterCall)
-          {
-             // resume playback only if FM Radio was playing
-             // when the call was answered
-              if (isAntennaAvailable() && (!isFmOn()) && mServiceInUse)
-              {
-                   Log.d(LOGTAG, "Resuming after call:");
-                   do {
-                       granted = audioManager.requestAudioFocus(mAudioFocusListener,
-                               AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
-                       ++count;
-                       try {
-                           Thread.sleep(100);
-                       } catch (Exception ex) {
-                           Log.d( LOGTAG, "InterruptedException");
-                       }
-                   } while(granted != AudioManager.AUDIOFOCUS_REQUEST_GRANTED && count != 3);
-
-                   if(true != fmOn()) {
-                       return;
-                   }
-
-                   mResumeAfterCall = false;
-                   if(mCallbacks != null) {
-                      try {
-                           mCallbacks.onEnabled();
-                      } catch (RemoteException e) {
-                           e.printStackTrace();
-                      }
-                   }
-              }
-          } else {
-              if (!isFmOn() && (mServiceInUse) && (mCallbacks != null)) {
-                  try {
-                      mCallbacks.onDisabled();
-                  } catch (RemoteException e) {
-                      e.printStackTrace();
-                  }
-              }
-          }
-       }//idle
    }
 
     /* Handle Phone Call + FM Concurrency */
@@ -1588,7 +1582,7 @@
               stopRecording();
               break;
           case FOCUSCHANGE:
-              if( false == isFmOn() ) {
+              if( !isFmOn() && !mResumeAfterCall) {
                   Log.v(LOGTAG, "FM is not running, not handling change");
                   return;
               }
@@ -1599,10 +1593,12 @@
                           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();
-                          mStoppedOnFocusLoss = true;
                       }
+                      mStoppedOnFocusLoss = true;
                       break;
                   case AudioManager.AUDIOFOCUS_LOSS:
                       Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_LOSS");
@@ -1626,9 +1622,14 @@
                       break;
                   case AudioManager.AUDIOFOCUS_GAIN:
                       Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_GAIN");
+                      mStoppedOnFocusLoss = false;
+                      if (mResumeAfterCall) {
+                          Log.v(LOGTAG, "resumeAfterCall");
+                          resumeAfterCall();
+                          break;
+                      }
                       if(false == mPlaybackInProgress)
                           startFM();
-                      mStoppedOnFocusLoss = false;
                       mSession.setActive(true);
                       break;
                   default:
@@ -2126,6 +2127,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
    *                                                                                 .
@@ -2167,7 +2189,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 {
@@ -2258,7 +2285,12 @@
          Log.d(LOGTAG, "audioManager.setFmRadioOn = false \n" );
          stopFM();
          unMute();
-         audioManager.abandonAudioFocus(mAudioFocusListener);
+         // If call is active, we will use audio focus to resume fm after call ends.
+         // So don't abandon audiofocus automatically
+         if (getCallState() == TelephonyManager.CALL_STATE_IDLE) {
+             audioManager.abandonAudioFocus(mAudioFocusListener);
+             mStoppedOnFocusLoss = true;
+         }
          //audioManager.setParameters("FMRadioOn=false");
          Log.d(LOGTAG, "audioManager.setFmRadioOn false done \n" );
       }
@@ -2315,40 +2347,61 @@
       }
    }
 
-  /*
-   * Turn OFF FM: Disable the FM Host and hardware                                  .
-   *                                                                                 .
-   * @return true if fm Disable api was invoked successfully, false if the api failed.
-   */
-   private boolean fmOff() {
+   private boolean fmOffImpl() {
       boolean bStatus=false;
 
       // This will disable the FM radio device
       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();
       stop();
+
       return(bStatus);
    }
 
+   private boolean fmOffImplCherokee() {
+      boolean bStatus=false;
+
+      fmOperationsOff();
+      stop();
+      try {
+          Thread.sleep(200);
+      } catch (Exception ex) {
+          Log.d( LOGTAG, "RunningThread InterruptedException");
+      }
+
+      // This will disable the FM radio device
+      if (mReceiver != null)
+      {
+         mEventReceived = false;
+         bStatus = mReceiver.disable(this);
+         if (bStatus &&
+                 (mReceiver.getFMState() == mReceiver.subPwrLevel_FMTurning_Off)) {
+             bStatus = waitForEvent();
+         }
+         mReceiver = null;
+      }
+      return(bStatus);
+   }
+  /*
+   * Turn OFF FM: Disable the FM Host and hardware                                  .
+   *                                                                                 .
+   * @return true if fm Disable api was invoked successfully, false if the api failed.
+   */
+   private boolean fmOff() {
+       if (mReceiver != null) {
+           if (mReceiver.isCherokeeChip()) {
+               return fmOffImplCherokee();
+           } else {
+              return fmOffImpl();
+           }
+       }
+       return false;
+   }
+
    private boolean fmOff(int off_from) {
        if (off_from == FM_OFF_FROM_APPLICATION || off_from == FM_OFF_FROM_ANTENNA) {
            Log.d(LOGTAG, "FM application close button pressed or antenna removed");
@@ -3076,14 +3129,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()
@@ -3781,7 +3843,7 @@
    }
    private void requestFocus() {
       if( (false == mPlaybackInProgress) &&
-          (true  == mStoppedOnFocusLoss) ) {
+          (true  == mStoppedOnFocusLoss) && isFmOn()) {
            // adding code for audio focus gain.
            AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
            audioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
diff --git a/fmapp2/src/com/caf/fmradio/FMStats.java b/fmapp2/src/com/caf/fmradio/FMStats.java
index 1e7a25d..a0bc184 100644
--- a/fmapp2/src/com/caf/fmradio/FMStats.java
+++ b/fmapp2/src/com/caf/fmradio/FMStats.java
@@ -3265,27 +3265,32 @@
         int ret;
         Log.d(LOGTAG,"freq is "+freq);
         result.setFreq(Integer.toString(freq));
+        boolean isCherokeeChip = isCherokeeChip();
         if((null != mService)) {
             try {
-                ret = mService.getRssi();
-                 if (ret != 0) {
-                     Log.e(LOGTAG, "getrssi cmd failed: ret = " + ret);
-                     return null;
-                 }
-                lastCmdSent = CMD_STNPARAM_RSSI;
-                Log.e(LOGTAG, "wait for response of mService.getRssi");
-                synchronized (obj) {
-                    try {
-                        obj.wait();
-                    } catch (InterruptedException e) {
-                        Log.e(LOGTAG, "getRSSI:THREAD interrupted");
-                        e.printStackTrace();
-                        return null;
+                if (isCherokeeChip) {
+                    ret = mService.getRssi();
+                     if (ret != 0) {
+                         Log.e(LOGTAG, "getrssi cmd failed: ret = " + ret);
+                         return null;
+                     }
+                    lastCmdSent = CMD_STNPARAM_RSSI;
+                    Log.e(LOGTAG, "wait for response of mService.getRssi");
+                    synchronized (obj) {
+                        try {
+                            obj.wait();
+                        } catch (InterruptedException e) {
+                            Log.e(LOGTAG, "getRSSI:THREAD interrupted");
+                            e.printStackTrace();
+                            return null;
+                        }
                     }
+                } else {
+                    nRssi = mService.getRssi();
                 }
                 Log.e(LOGTAG, "Got response of mService.getRssi");
                 if (nRssi != Integer.MAX_VALUE) {
-                    result.setRSSI(Integer.toString(nRssi));
+                    result.setRSSI(Integer.toString((byte)nRssi));
                 } else {
                     return null;
                 }
@@ -3297,17 +3302,21 @@
 
             if(!isRomeChip()) {
                 try {
-                    mService.getIoC();
-                    lastCmdSent = CMD_STNDBGPARAM_IOVERC;
-                    Log.e(LOGTAG, "wait for response of mService.getIoC");
-                    synchronized (obj) {
-                        try {
-                            obj.wait();
-                        } catch (InterruptedException e) {
-                            Log.e(LOGTAG, "getIOC:THREAD interrupted");
-                            e.printStackTrace();
-                            return null;
+                    if (isCherokeeChip) {
+                        mService.getIoC();
+                        lastCmdSent = CMD_STNDBGPARAM_IOVERC;
+                        Log.e(LOGTAG, "wait for response of mService.getIoC");
+                        synchronized (obj) {
+                            try {
+                                obj.wait();
+                            } catch (InterruptedException e) {
+                                Log.e(LOGTAG, "getIOC:THREAD interrupted");
+                                e.printStackTrace();
+                                return null;
+                            }
                         }
+                    } else {
+                        nIoC = mService.getIoC();
                     }
                     Log.e(LOGTAG, "GOT response of mService.getIoC");
                     if (nIoC != Integer.MAX_VALUE)
@@ -3321,23 +3330,27 @@
                 }
             }
 
-            if(isTransportLayerSMD() || isRomeChip() || isCherokeeChip()) {
+            if(isTransportLayerSMD() || isRomeChip() || isCherokeeChip) {
                 try {
-                    mService.getSINR();
-                    lastCmdSent = CMD_STNPARAM_SINR;
-                    Log.e(LOGTAG, "wait for response of mService.getSINR");
-                    synchronized (obj) {
-                        try {
-                            obj.wait();
-                        } catch (InterruptedException e) {
-                            Log.e(LOGTAG, "getSINR:THREAD interrupted");
-                            e.printStackTrace();
-                            return null;
+                    if (isCherokeeChip) {
+                        mService.getSINR();
+                        lastCmdSent = CMD_STNPARAM_SINR;
+                        Log.e(LOGTAG, "wait for response of mService.getSINR");
+                        synchronized (obj) {
+                            try {
+                                obj.wait();
+                            } catch (InterruptedException e) {
+                                Log.e(LOGTAG, "getSINR:THREAD interrupted");
+                                e.printStackTrace();
+                                return null;
+                            }
                         }
+                    } else {
+                        nSINR = mService.getSINR();
                     }
                     Log.e(LOGTAG, "Got response of mService.getSINR");
                     if (nSINR != Integer.MAX_VALUE) {
-                        result.setSINR(Integer.toString(nSINR));
+                        result.setSINR(Integer.toString((byte)nSINR));
                     } else {
                         return null;
                     }
@@ -3362,17 +3375,21 @@
 
             if(!isRomeChip()) {
                 try {
-                    mService.getIntDet();
-                    lastCmdSent = CMD_STNDBGPARAM_INFDETOUT;
-                    Log.e(LOGTAG, "wait for response of mService.getIntDet");
-                    synchronized (obj) {
-                        try {
-                            obj.wait();
-                        } catch (InterruptedException e) {
-                            Log.e(LOGTAG, "getIntDet:THREAD interrupted");
-                            e.printStackTrace();
-                            return null;
+                    if (isCherokeeChip) {
+                        mService.getIntDet();
+                        lastCmdSent = CMD_STNDBGPARAM_INFDETOUT;
+                        Log.e(LOGTAG, "wait for response of mService.getIntDet");
+                        synchronized (obj) {
+                            try {
+                                obj.wait();
+                            } catch (InterruptedException e) {
+                                Log.e(LOGTAG, "getIntDet:THREAD interrupted");
+                                e.printStackTrace();
+                                return null;
+                            }
                         }
+                    } else {
+                        nIntDet = mService.getIntDet();
                     }
                     Log.e(LOGTAG, "Got response of mService.getIntDet");
                     if (nIntDet != Integer.MAX_VALUE)
diff --git a/fmapp2/src/com/caf/fmradio/FmSharedPreferences.java b/fmapp2/src/com/caf/fmradio/FmSharedPreferences.java
index 2e2aa70..70a7d1c 100644
--- a/fmapp2/src/com/caf/fmradio/FmSharedPreferences.java
+++ b/fmapp2/src/com/caf/fmradio/FmSharedPreferences.java
@@ -342,7 +342,8 @@
       }
    }
    public static void addTags(int index, String s) {
-     if ((index >= 0) && (index <FmSharedPreferences.MAX_NUM_TAG_TYPES)) {
+     if ((index >= 0) && (index <FmSharedPreferences.MAX_NUM_TAG_TYPES) &&
+             s != null && !s.isEmpty()) {
           if(tagList[index] == null) {
              tagList[index] = new TreeSet<String>();
           }
diff --git a/helium/radio-helium-commands.h b/helium/radio-helium-commands.h
index c5dfba9..46ed651 100644
--- a/helium/radio-helium-commands.h
+++ b/helium/radio-helium-commands.h
@@ -115,5 +115,8 @@
     HCI_FM_HELIUM_AUDIO_MODE,
     HCI_FM_HELIUM_RMSSI,
     HCI_FM_HELIUM_AUDIO_MUTE,
+
+    /*FM VSC command to enable/disable slimbus data port*/
+    HCI_FM_HELIUM_AUDIO = 0x00980940,
 };
 #endif /* __RADIO_CHEROKEE_COMMANDS_H */
diff --git a/helium/radio-helium.h b/helium/radio-helium.h
index 070dafa..200e006 100644
--- a/helium/radio-helium.h
+++ b/helium/radio-helium.h
@@ -245,6 +245,7 @@
 #define HCI_OCF_FM_RDS_RT_REQ               0x0008
 #define HCI_OCF_FM_RDS_PS_REQ               0x0009
 
+#define HCI_OCF_FM_ENABLE_SLIMBUS           (0x000E)
 
 /* HCI common control commands opcode */
 #define HCI_OCF_FM_TUNE_STATION_REQ         0x0001
@@ -1231,6 +1232,7 @@
 int hci_fm_default_data_write_req(struct hci_fm_def_data_wr_req * data_wrt);
 int hci_fm_get_station_dbg_param_req();
 int hci_fm_get_station_cmd_param_req();
+int hci_fm_enable_slimbus(uint8_t enable);
 
 struct fm_hal_t {
     struct radio_helium_device *radio;
diff --git a/helium/radio_helium_hal.c b/helium/radio_helium_hal.c
index 3fa4587..5d9137e 100644
--- a/helium/radio_helium_hal.c
+++ b/helium/radio_helium_hal.c
@@ -1338,6 +1338,7 @@
 
     case HCI_FM_HELIUM_RDS_GRP_COUNTERS:
          ALOGD("%s: rds_grp counter read  value=%d ", LOG_TAG,val);
+         saved_val = hal->radio->g_rds_grp_proc_ps;
          ret = hci_fm_get_rds_grpcounters_req(val);
          if (ret < 0) {
              hal->radio->g_rds_grp_proc_ps = saved_val;
@@ -1347,6 +1348,7 @@
 
     case HCI_FM_HELIUM_RDS_GRP_COUNTERS_EXT:
          ALOGD("%s: rds_grp counter read  value=%d ", LOG_TAG,val);
+         saved_val = hal->radio->g_rds_grp_proc_ps;
          ret = hci_fm_get_rds_grpcounters_ext_req(val);
          if (ret < 0) {
             hal->radio->g_rds_grp_proc_ps = saved_val;
@@ -1423,7 +1425,10 @@
         hal->radio->recv_conf.band_low_limit = val;
         break;
     case HCI_FM_HELIUM_AUDIO_MODE:
-        hal->radio->stereo_mode.stereo_mode = ~val;
+        hal->radio->stereo_mode.stereo_mode = (char)val ? 0:1;
+        hal->radio->stereo_mode.sig_blend  = 1;
+        hal->radio->stereo_mode.intf_blend = 0;
+        hal->radio->stereo_mode.most_switch =0;
         hci_set_fm_stereo_mode_req(&hal->radio->stereo_mode);
         break;
     case HCI_FM_HELIUM_RIVA_ACCS_ADDR:
@@ -1601,6 +1606,10 @@
              ALOGI("%s: command sent sucessfully", __func__, val);
          }
          break;
+    case HCI_FM_HELIUM_AUDIO:
+         ALOGE("%s slimbus port", val ? "enable" : "disable");
+         ret = hci_fm_enable_slimbus(val);
+         break;
     default:
         ALOGE("%s:%s: Not a valid FM CMD!!", LOG_TAG, __func__);
         ret = 0;
diff --git a/helium/radio_helium_hal_cmds.c b/helium/radio_helium_hal_cmds.c
index 520ec12..b783c53 100644
--- a/helium/radio_helium_hal_cmds.c
+++ b/helium/radio_helium_hal_cmds.c
@@ -461,3 +461,13 @@
                                   HCI_OCF_FM_LOW_PASS_FILTER_CTRL);
     return send_fm_cmd_pkt(opcode, sizeof(enable_lpf), &enable_lpf);
 }
+int hci_fm_enable_slimbus(uint8_t val) {
+    ALOGE("%s", __func__);
+    uint16_t opcode = 0;
+
+    opcode = hci_opcode_pack(HCI_OGF_FM_DIAGNOSTIC_CMD_REQ,
+                                HCI_OCF_FM_ENABLE_SLIMBUS);
+
+    ALOGE("%s:val = %d, uint8 val = %d", __func__, val, (uint8_t)val);
+    return send_fm_cmd_pkt(opcode , sizeof(val), &val);
+}
diff --git a/jni/FmConst.h b/jni/FmConst.h
index 26eb616..e37160f 100644
--- a/jni/FmConst.h
+++ b/jni/FmConst.h
@@ -153,6 +153,8 @@
     V4L2_CID_PRV_IRIS_LOWER_BAND,
     V4L2_CID_PRV_IRIS_AUDIO_MODE,
     V4L2_CID_PRV_IRIS_RMSSI,
+
+    V4L2_CID_PRV_ENABLE_SLIMBUS = 0x00980940,
 };
 
 #endif
diff --git a/jni/android_hardware_fm.cpp b/jni/android_hardware_fm.cpp
index b5b0a5e..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;
     }
 
@@ -1498,6 +1539,17 @@
     return FM_JNI_SUCCESS;
 }
 
+static jint android_hardware_fmradio_FmReceiverJNI_enableSlimbusNative
+ (JNIEnv * env, jobject thiz, jint fd, jint val)
+{
+    ALOGD("%s: val = %d\n", __func__, val);
+    int err = JNI_ERR;
+#ifdef FM_SOC_TYPE_CHEROKEE
+    err = vendor_interface->set_fm_ctrl(V4L2_CID_PRV_ENABLE_SLIMBUS, val);
+#endif
+    return err;
+}
+
 static void classInitNative(JNIEnv* env, jclass clazz) {
 
     ALOGI("ClassInit native called \n");
@@ -1644,6 +1696,8 @@
             (void*)android_hardware_fmradio_FmReceiverJNI_setSpurDataNative},
         { "configurePerformanceParams", "(I)V",
              (void*)android_hardware_fmradio_FmReceiverJNI_configurePerformanceParams},
+        { "enableSlimbus", "(II)I",
+             (void*)android_hardware_fmradio_FmReceiverJNI_enableSlimbusNative},
 };
 
 int register_android_hardware_fm_fmradio(JNIEnv* env)
diff --git a/qcom/fmradio/FmReceiver.java b/qcom/fmradio/FmReceiver.java
index af7191a..b15d512 100644
--- a/qcom/fmradio/FmReceiver.java
+++ b/qcom/fmradio/FmReceiver.java
@@ -2974,7 +2974,7 @@
            case TelephonyManager.NETWORK_TYPE_UMTS:
                if ((mEnableLpfUmts  & RatConf) == mEnableLpfUmts ) {
                    Log.v (TAG, "set LPF for net_type: " + Integer.toString(net_type));
-				   Log.v (TAG,  "enable:" + enable);
+                   Log.v (TAG,  "enable:" + enable);
                    mControl.enableLPF(sFd, enable);
                }
                break;
@@ -3079,4 +3079,8 @@
                break;
        }
    }
+   public void EnableSlimbus(int enable) {
+       Log.d(TAG, "EnableSlimbus :enable =" + enable);
+       mControl.enableSlimbus(sFd, enable);
+   }
 }
diff --git a/qcom/fmradio/FmReceiverJNI.java b/qcom/fmradio/FmReceiverJNI.java
index c5835ff..d9fa79a 100644
--- a/qcom/fmradio/FmReceiverJNI.java
+++ b/qcom/fmradio/FmReceiverJNI.java
@@ -547,4 +547,5 @@
      */
     static native int setSpurDataNative(int fd, short  buff[], int len);
     static native void configurePerformanceParams(int fd);
+    static native int enableSlimbus(int fd, int val);
 }
diff --git a/qcom/fmradio/FmRxControls.java b/qcom/fmradio/FmRxControls.java
index 7b9fb7c..a3eba2a 100644
--- a/qcom/fmradio/FmRxControls.java
+++ b/qcom/fmradio/FmRxControls.java
@@ -786,4 +786,13 @@
          return true;
       }
    }
+   public boolean enableSlimbus(int fd, int enable) {
+       int ret;
+       Log.d(TAG, "enableSlimbus : enable = " + enable);
+       ret = FmReceiverJNI.enableSlimbus(fd, enable);
+       if (ret == 0)
+           return true;
+       else
+           return false;
+   }
 }