Merge "FM: Update state after tune is complete when search is cancelled"
diff --git a/fmapp2/AndroidManifest.xml b/fmapp2/AndroidManifest.xml
index a0ed3ca..e80f68d 100644
--- a/fmapp2/AndroidManifest.xml
+++ b/fmapp2/AndroidManifest.xml
@@ -57,6 +57,7 @@
             android:clearTaskOnLaunch="true"
             android:allowTaskReparenting="true"
             android:launchMode="singleTask"
+            android:configChanges="orientation|keyboardHidden|screenSize"
             android:excludeFromRecents="false" >
 
             <intent-filter>
diff --git a/fmapp2/res/values/arrays.xml b/fmapp2/res/values/arrays.xml
index c505ec0..442ffc3 100644
--- a/fmapp2/res/values/arrays.xml
+++ b/fmapp2/res/values/arrays.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2009, 2011-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009, 2011-2014 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:
@@ -361,8 +361,12 @@
       <item> Get AfJmpRmssi Threshold</item>
       <item> Get GoodChRmssi Threshold</item>
       <item> Get AfJmpRmssi Samples count</item>
-      <item> RF Statistics</item>
       <item> Set RXREPEAT Count</item>
+      <item> Set Sig Blend SinrHi</item>
+      <item> Get Sig Blend SinrHi</item>
+      <item> Set Sig Blend RmssiHi</item>
+      <item> Get Sig Blend RmssiHi</item>
+      <item> RF Statistics</item>
   </string-array>
 
 
diff --git a/fmapp2/res/values/strings.xml b/fmapp2/res/values/strings.xml
index bff5bb8..55b2932 100644
--- a/fmapp2/res/values/strings.xml
+++ b/fmapp2/res/values/strings.xml
@@ -248,6 +248,10 @@
     <string name="rt_plus_tags">Tags</string>
     <string name="enter_RxRePeatCount">Enter RxRePeat count</string>
     <string name="set_RxRePeatCount">Config RxRePeat count</string>
+    <string name="enter_BlendSinrHi">Enter Sig Blend SinrHi value</string>
+    <string name="set_BlendSinrHi">Configure Sig Blend SinrHi value</string>
+    <string name="enter_BlendRmssiHi">Enter Sig Blend RmssiHi value</string>
+    <string name="set_BlendRmssiHi">Configure Sig Blend RmssiHi value</string>
     <string name="enter_RssiTh">Enter RSSI Threshold</string>
     <string name="set_RssiTh">Config RSSI Threshold</string>
     <string name="enter_AfJumpRssiTh">Enter AF jump RSSI Threshold</string>
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
index 2de50e7..9154c26 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadioService.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2014, 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:
@@ -177,6 +177,8 @@
    static final int RECORD_START = 1;
    static final int RECORD_STOP = 0;
    private Thread mRecordServiceCheckThread = null;
+   private boolean mUnMuteOnFocusLoss = false;
+   private boolean mSpeakerOnFocusLoss = false;
 
    public FMRadioService() {
    }
@@ -375,12 +377,10 @@
                             Log.d(LOGTAG, "FM Audio Path is Analog Mode: FM Over BT not allowed");
                             return ;
                         }
-                       //when playback is overA2Dp and A2dp disconnected
-                       //when playback is not overA2DP and A2DP Connected
+                       //when A2dp connected/disconnected
                        // In above two cases we need to Stop and Start FM which
                        // will take care of audio routing
                        if( (isFmOn()) &&
-                           (true == ((bA2dpConnected)^(mOverA2DP))) &&
                            (false == mStoppedOnFocusLoss)) {
                            Log.d(LOGTAG, "stopping and starting FM\n");
                            stopFM();
@@ -703,8 +703,10 @@
       cancelAlarmDealyedServiceStop();
       mServiceInUse = true;
       /* Application/UI is attached, so get out of lower power mode */
-      setLowPowerMode(false);
-      startFM();
+      if (isFmOn()) {
+          setLowPowerMode(false);
+          startFM();
+      }
       Log.d(LOGTAG, "onRebind");
    }
 
@@ -832,6 +834,8 @@
        }
        sendRecordServiceIntent(RECORD_START);
        mPlaybackInProgress = true;
+       mUnMuteOnFocusLoss = false;
+       mSpeakerOnFocusLoss = false;
    }
 
    private void stopFM(){
@@ -1057,7 +1061,14 @@
 
        if((TelephonyManager.CALL_STATE_OFFHOOK == state)||
           (TelephonyManager.CALL_STATE_RINGING == state)) {
-           boolean bTempSpeaker = mSpeakerPhoneOn; //need to restore SpeakerPhone
+           boolean bTempSpeaker = (mSpeakerPhoneOn | mSpeakerOnFocusLoss) ; //need to restore SpeakerPhone
+           if (mUnMuteOnFocusLoss) {
+               if (audioManager != null) {
+                   Log.d(LOGTAG, "Mute");
+                   mMuted = true;
+                   audioManager.setStreamMute(AudioManager.STREAM_MUSIC,true);
+               }
+           }
            boolean bTempMute = mMuted;// need to restore Mute status
            int bTempCall = mCallStatus;//need to restore call status
            if (isFmOn() && fmOff()) {
@@ -1185,10 +1196,13 @@
                       if (mSpeakerPhoneOn) {
                          mSpeakerDisableHandler.removeCallbacks(mSpeakerDisableTask);
                          mSpeakerDisableHandler.postDelayed(mSpeakerDisableTask, 0);
+                         mSpeakerOnFocusLoss = true;
                       }
                       if (true == mPlaybackInProgress) {
-                          if(mMuted)
+                          if(mMuted) {
                              unMute();
+                             mUnMuteOnFocusLoss = true;
+                          }
                           stopFM();
                       }
                       if (mSpeakerPhoneOn) {
diff --git a/fmapp2/src/com/caf/fmradio/FMStats.java b/fmapp2/src/com/caf/fmradio/FMStats.java
index 1c20c7a..a380781 100644
--- a/fmapp2/src/com/caf/fmradio/FMStats.java
+++ b/fmapp2/src/com/caf/fmradio/FMStats.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2014, 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:
@@ -235,6 +235,10 @@
     private static final int MAX_RSSI_TH_SILABS = 127;
     private static final int MIN_RDS_FIFO_CNT_SILABS = 0;
     private static final int MAX_RDS_FIFO_CNT_SILABS = 25;
+    private static final int MIN_BLEND_SINRHI = -128;
+    private static final int MAX_BLEND_SINRHI = 127;
+    private static final int MIN_BLEND_RMSSIHI = -128;
+    private static final int MAX_BLEND_RMSSIHI = 127;
 
     private static final int DIALOG_BAND_SWEEP_SETTING = 1;
 
@@ -578,6 +582,46 @@
         }
     };
 
+    private View.OnClickListener mOnSetBlendSinrHiListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            String a;
+            a =  txtbox1.getText().toString();
+            try {
+                 byte count = (byte) Integer.parseInt(a);
+                 Log.d(LOGTAG, "Value entered for mOnSetBlendSinrHiListener: " + count);
+                 if((count < MIN_BLEND_SINRHI ) ||
+                     (count > MAX_BLEND_SINRHI))
+                     return;
+                 if(mReceiver != null) {
+                         mReceiver.setBlendSinr(count);
+                 }
+            } catch (NumberFormatException e) {
+                 Log.e(LOGTAG, "Value entered is not in correct format : " + a);
+                 txtbox1.setText("");
+            }
+        }
+    };
+
+    private View.OnClickListener mOnSetBlendRmssiHiListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            String a;
+            a =  txtbox1.getText().toString();
+            try {
+                 byte count = (byte)Integer.parseInt(a);
+                 Log.d(LOGTAG, "Value entered for mOnSetBlendRmssiHiListener: " + count);
+                 if((count < MIN_BLEND_RMSSIHI) ||
+                     (count > MAX_BLEND_RMSSIHI))
+                     return;
+                 if(mReceiver != null) {
+                         mReceiver.setBlendRmssi(count);
+                 }
+            } catch (NumberFormatException e) {
+                 Log.e(LOGTAG, "Value entered is not in correct format : " + a);
+                 txtbox1.setText("");
+            }
+        }
+    };
+
     private View.OnClickListener mOnSetSigThListener =
      new View.OnClickListener() {
        public void onClick(View v) {
@@ -1025,6 +1069,7 @@
                                     View view, int pos, long id) {
             Log.d("Table","onItemSelected is hit with " + pos);
             int ret = Integer.MAX_VALUE;
+            byte retval = Byte.MAX_VALUE;
             txtbox1 = (EditText) findViewById(R.id.txtbox1);
             tv1 = (TextView) findViewById(R.id.label);
             button1 = (Button)findViewById(R.id.SearchMpxDcc);
@@ -1524,6 +1569,119 @@
                     }
                     break;
                 case 20:
+                    if (txtbox1 != null) {
+                        txtbox1.setText(R.string.type_rd);
+                        txtbox1.setVisibility(View.VISIBLE);
+                    }
+                    if (tv1 != null) {
+                        tv1.setText(R.string.enter_RxRePeatCount);
+                        tv1.setVisibility(View.VISIBLE);
+                    }
+                    if (SetButton != null) {
+                        SetButton.setText(R.string.set_RxRePeatCount);
+                        SetButton.setVisibility(View.VISIBLE);
+                        SetButton.setOnClickListener(mOnSetRxRePeatCount);
+                    }
+                    if(button1 != null) {
+                       button1.setVisibility(View.INVISIBLE);
+                    }
+                    if(button2 != null) {
+                       button2.setVisibility(View.INVISIBLE);
+                    }
+                    break;
+                case 21:
+                    if (txtbox1 != null) {
+                       txtbox1.setText(R.string.type_rd);
+                       txtbox1.setVisibility(View.VISIBLE);
+                    }
+                    if (tv1 != null) {
+                       tv1.setText(R.string.enter_BlendSinrHi);
+                       tv1.setVisibility(View.VISIBLE);
+                    }
+                    if(button1 != null) {
+                       button1.setVisibility(View.INVISIBLE);
+                    }
+                    if(button2 != null) {
+                       button2.setVisibility(View.INVISIBLE);
+                    }
+                    if (SetButton != null) {
+                       SetButton.setText(R.string.set_BlendSinrHi);
+                       SetButton.setVisibility(View.VISIBLE);
+                       SetButton.setOnClickListener(mOnSetBlendSinrHiListener);
+                    }
+                    break;
+                case 22:
+                    if (txtbox1 != null) {
+                        txtbox1.setVisibility(View.INVISIBLE);
+                    }
+                    if (tv1 != null) {
+                        tv1.setText("");
+                        tv1.setVisibility(View.VISIBLE);
+                    }
+                    if(button1 != null) {
+                       button1.setVisibility(View.INVISIBLE);
+                    }
+                    if(button2 != null) {
+                       button2.setVisibility(View.INVISIBLE);
+                    }
+                    if (SetButton != null) {
+                        SetButton.setVisibility(View.INVISIBLE);
+                    }
+                    if (mReceiver != null) {
+                        retval = mReceiver.getBlendSinr();
+                        Log.d(LOGTAG, "Get BlendSinrHi: " + retval);
+                        if((retval >= MIN_BLEND_RMSSIHI) &&
+                           (retval <= MAX_BLEND_RMSSIHI))
+                            tv1.setText(" " + String.valueOf(retval));
+                    }
+                    break;
+                case 23:
+                    if (txtbox1 != null) {
+                       txtbox1.setText(R.string.type_rd);
+                       txtbox1.setVisibility(View.VISIBLE);
+                    }
+                    if (tv1 != null) {
+                       tv1.setText(R.string.enter_BlendRmssiHi);
+                       tv1.setVisibility(View.VISIBLE);
+                    }
+                    if(button1 != null) {
+                       button1.setVisibility(View.INVISIBLE);
+                    }
+                    if(button2 != null) {
+                       button2.setVisibility(View.INVISIBLE);
+                    }
+                    if (SetButton != null) {
+                       SetButton.setText(R.string.set_BlendRmssiHi);
+                       SetButton.setVisibility(View.VISIBLE);
+                       SetButton.setOnClickListener(mOnSetBlendRmssiHiListener);
+                    }
+                    break;
+                case 24:
+                    if (txtbox1 != null) {
+                        txtbox1.setVisibility(View.INVISIBLE);
+                    }
+                    if (tv1 != null) {
+                        tv1.setText("");
+                        tv1.setVisibility(View.VISIBLE);
+                    }
+                    if(button1 != null) {
+                       button1.setVisibility(View.INVISIBLE);
+                    }
+                    if(button2 != null) {
+                       button2.setVisibility(View.INVISIBLE);
+                    }
+                    if (SetButton != null) {
+                        SetButton.setVisibility(View.INVISIBLE);
+                    }
+                    if (mReceiver != null) {
+                        retval = mReceiver.getBlendRmssi();
+                        Log.d(LOGTAG, "Get BlendRmssiHi: " + retval);
+                        if((retval >= MIN_BLEND_RMSSIHI) &&
+                           (retval <= MAX_BLEND_RMSSIHI))
+                            tv1.setText(" " + String.valueOf(retval));
+                    }
+                    break;
+                case 25:
                     tLayout.removeAllViewsInLayout();
                     mNewRowIds = NEW_ROW_ID;
                     tLayout.setVisibility(View.VISIBLE);
@@ -1547,27 +1705,6 @@
                     spinOptionFmRf.setAdapter(adaptRfCfg);
                     spinOptionFmRf.setOnItemSelectedListener(mSpinRfCfgListener);
                     break;
-                case 21:
-                    if (txtbox1 != null) {
-                        txtbox1.setText(R.string.type_rd);
-                        txtbox1.setVisibility(View.VISIBLE);
-                    }
-                    if (tv1 != null) {
-                        tv1.setText(R.string.enter_RxRePeatCount);
-                        tv1.setVisibility(View.VISIBLE);
-                    }
-                    if (SetButton != null) {
-                        SetButton.setText(R.string.set_RxRePeatCount);
-                        SetButton.setVisibility(View.VISIBLE);
-                        SetButton.setOnClickListener(mOnSetRxRePeatCount);
-                    }
-                    if(button1 != null) {
-                       button1.setVisibility(View.INVISIBLE);
-                    }
-                    if(button2 != null) {
-                       button2.setVisibility(View.INVISIBLE);
-                    }
-                    break;
             }
         }
         public void onNothingSelected(AdapterView<?> parent) {
diff --git a/qcom/fmradio/FmReceiver.java b/qcom/fmradio/FmReceiver.java
index 486dc33..732c0b2 100644
--- a/qcom/fmradio/FmReceiver.java
+++ b/qcom/fmradio/FmReceiver.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009,2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009,2012-2014, 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:
@@ -1951,6 +1951,42 @@
       return mControl.setPSRxRepeatCount(sFd, count);
    }
 
+   public byte getBlendSinr() {
+      int state = getFMState();
+      if ((state == FMState_Turned_Off) || (state == FMState_Srch_InProg)) {
+          Log.d(TAG, "getBlendSinr: Device currently busy in executing another command.");
+          return Byte.MAX_VALUE;
+      }
+      return mControl.getBlendSinr(sFd);
+   }
+
+   public boolean setBlendSinr(byte sinrHi) {
+      int state = getFMState();
+      if ((state == FMState_Turned_Off) || (state == FMState_Srch_InProg)) {
+          Log.d(TAG, "setBlendSinr: Device currently busy in executing another command.");
+          return false;
+      }
+      return mControl.setBlendSinr(sFd, sinrHi);
+   }
+
+   public byte getBlendRmssi() {
+      int state = getFMState();
+      if ((state == FMState_Turned_Off) || (state == FMState_Srch_InProg)) {
+          Log.d(TAG, "getBlendRmssi: Device currently busy in executing another command.");
+          return Byte.MAX_VALUE;
+      }
+      return mControl.getBlendRmssi(sFd);
+   }
+
+   public boolean setBlendRmssi(byte rmssiHi) {
+      int state = getFMState();
+      if ((state == FMState_Turned_Off) || (state == FMState_Srch_InProg)) {
+          Log.d(TAG, "setBlendRmssi: Device currently busy in executing another command.");
+          return false;
+      }
+      return mControl.setBlendRmssi(sFd, rmssiHi);
+   }
+
    /*==============================================================
    FUNCTION:  setRdsGroupOptions
    ==============================================================*/
diff --git a/qcom/fmradio/FmRxControls.java b/qcom/fmradio/FmRxControls.java
index b959b70..864e289 100644
--- a/qcom/fmradio/FmRxControls.java
+++ b/qcom/fmradio/FmRxControls.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2014, 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:
@@ -98,6 +98,8 @@
    private static final int V4L2_CID_PRIVATE_RXREPEATCOUNT                 = V4L2_CID_PRIVATE_BASE + 0x3D;
    private static final int V4L2_CID_PRIVATE_RSSI_TH                       = V4L2_CID_PRIVATE_BASE + 0x3E;
    private static final int V4L2_CID_PRIVATE_AF_JUMP_RSSI_TH               = V4L2_CID_PRIVATE_BASE + 0x3F;
+   private static final int V4L2_CID_PRIVATE_BLEND_SINRHI                  = V4L2_CID_PRIVATE_BASE + 0x40;
+   private static final int V4L2_CID_PRIVATE_BLEND_RMSSIHI                 = V4L2_CID_PRIVATE_BASE + 0x41;
 
    private static final int V4L2_CTRL_CLASS_USER = 0x980000;
    private static final int V4L2_CID_BASE        = V4L2_CTRL_CLASS_USER | 0x900;
@@ -731,4 +733,33 @@
       }
    }
 
+   public byte getBlendSinr(int fd) {
+      return (byte)FmReceiverJNI.getControlNative(fd, V4L2_CID_PRIVATE_BLEND_SINRHI);
+   }
+
+   public boolean setBlendSinr(int fd, byte sinrHi) {
+      int ret;
+      ret = FmReceiverJNI.setControlNative(fd, V4L2_CID_PRIVATE_BLEND_SINRHI, sinrHi);
+      if(ret < 0) {
+         Log.e(TAG, "Error in setting sinrHi ");
+         return false;
+      }else {
+         return true;
+      }
+   }
+
+   public byte getBlendRmssi(int fd) {
+      return (byte)FmReceiverJNI.getControlNative(fd, V4L2_CID_PRIVATE_BLEND_RMSSIHI);
+   }
+
+   public boolean setBlendRmssi(int fd, byte rmssiHi) {
+      int ret;
+      ret = FmReceiverJNI.setControlNative(fd, V4L2_CID_PRIVATE_BLEND_RMSSIHI, rmssiHi);
+      if(ret < 0) {
+         Log.e(TAG, "Error in setting RmssiHi ");
+         return false;
+      }else {
+         return true;
+      }
+   }
 }