diff --git a/fm_hci/fm_hci.c b/fm_hci/fm_hci.c
index e0d437a..ff932b9 100644
--- a/fm_hci/fm_hci.c
+++ b/fm_hci/fm_hci.c
@@ -247,7 +247,7 @@
                         event_notification(hci, HC_EVENT_RX);
 
                         if (hci->cb && hci->cb->process_event)
-                            hci->cb->process_event(hci->private_data, (uint8_t *)pbuf);
+                            hci->cb->process_event((uint8_t *)pbuf);
                         else
                             ALOGE("%s: ASSERT $$$$$$ Callback function NULL $$$$$", __func__);
 
diff --git a/fm_hci/fm_hci.cpp b/fm_hci/fm_hci.cpp
index 6a9dba6..1686c5a 100644
--- a/fm_hci/fm_hci.cpp
+++ b/fm_hci/fm_hci.cpp
@@ -171,7 +171,7 @@
 
         if (hci.cb && hci.cb->process_event) {
             ALOGI("%s: processing the event", __func__);
-            hci.cb->process_event(NULL, (uint8_t *)evt_buf);
+            hci.cb->process_event((uint8_t *)evt_buf);
         }
 
         free(evt_buf);
@@ -364,8 +364,6 @@
 *******************************************************************************/
 static void stop_tx_thread()
 {
-    int ret;
-
     ALOGI("%s:stop_tx_thread ++", __func__);
     hci.tx_cond_mtx.lock();
     hci.tx_cond.notify_all();
diff --git a/fm_hci/fm_hci_api.h b/fm_hci/fm_hci_api.h
index 01298f0..4c41509 100644
--- a/fm_hci/fm_hci_api.h
+++ b/fm_hci/fm_hci_api.h
@@ -63,7 +63,7 @@
     FM_RADIO_ENABLING
 } fm_power_state_t;
 
-typedef int (*event_notification_cb_t)(void *hal, unsigned char *buf);
+typedef int (*event_notification_cb_t)(unsigned char *buf);
 typedef int (*hci_close_done_cb_t)();
 
 
diff --git a/fmapp2/Android.mk b/fmapp2/Android.mk
index e125be5..a98adb5 100644
--- a/fmapp2/Android.mk
+++ b/fmapp2/Android.mk
@@ -19,7 +19,6 @@
 LOCAL_SRC_FILES += src/com/caf/fmradio/StationListActivity.java
 LOCAL_SRC_FILES += src/com/caf/fmradio/IFMRadioService.aidl
 LOCAL_SRC_FILES += src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl
-LOCAL_SRC_FILES += src/com/caf/fmradio/IFMTransmitterService.aidl
 LOCAL_SRC_FILES += src/com/caf/fmradio/IFMTransmitterServiceCallbacks.aidl
 
 ifeq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) >= 11 ))" )))
diff --git a/fmapp2/AndroidManifest.xml b/fmapp2/AndroidManifest.xml
index 482a85e..8f373e8 100644
--- a/fmapp2/AndroidManifest.xml
+++ b/fmapp2/AndroidManifest.xml
@@ -44,7 +44,7 @@
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
-
+    <uses-sdk android:minSdkVersion="28"  android:targetSdkVersion="28"/>
     <application
         android:icon="@drawable/ic_launcher_fmradio"
         android:label="@string/app_name"
diff --git a/fmapp2/res/layout/layout_dialog_progress.xml b/fmapp2/res/layout/layout_dialog_progress.xml
new file mode 100644
index 0000000..7aadd11
--- /dev/null
+++ b/fmapp2/res/layout/layout_dialog_progress.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     * Copyright (c) 2019 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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+     >
+
+    <ProgressBar
+        android:id="@+id/progress"
+        style="?android:attr/progressBarStyleInverse"
+        android:layout_width="@dimen/progress_bar_width"
+        android:layout_height="@dimen/progress_bar_height"
+        android:padding="10dp"
+        android:layout_marginLeft="20dp"
+         />
+
+    <TextView
+        android:id="@+id/id_tv_message"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="Sample Text"
+        android:layout_centerInParent="true"
+        android:layout_toRightOf="@id/progress"
+        android:paddingLeft="10dp"
+        android:textSize="@dimen/tv_message_font_size" />
+
+</RelativeLayout>
diff --git a/fmapp2/res/values/dimen.xml b/fmapp2/res/values/dimen.xml
new file mode 100644
index 0000000..83c84f7
--- /dev/null
+++ b/fmapp2/res/values/dimen.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     * Copyright (c) 2019 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.
+-->
+<resources>
+    <dimen name="tv_title_font_size">20sp</dimen>
+    <dimen name="tv_message_font_size">15sp</dimen>
+    <dimen name="progress_bar_width">80dp</dimen>
+    <dimen name="progress_bar_height">80dp</dimen>
+</resources>
diff --git a/fmapp2/src/com/caf/fmradio/FMMediaButtonIntentReceiver.java b/fmapp2/src/com/caf/fmradio/FMMediaButtonIntentReceiver.java
index 5dd3eb7..ef8b1ee 100644
--- a/fmapp2/src/com/caf/fmradio/FMMediaButtonIntentReceiver.java
+++ b/fmapp2/src/com/caf/fmradio/FMMediaButtonIntentReceiver.java
@@ -29,18 +29,11 @@
 
 package com.caf.fmradio;
 
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.app.IntentService;
 import android.content.BroadcastReceiver;
-import android.content.pm.PackageManager;
 import android.content.Context;
-import android.content.ComponentName;
+import android.content.Intent;
 import android.media.AudioManager;
 import android.util.Log;
-import android.view.KeyEvent;
-import android.os.Bundle;
-import java.lang.Object;
 
 public class FMMediaButtonIntentReceiver extends BroadcastReceiver {
 
diff --git a/fmapp2/src/com/caf/fmradio/FMRadio.java b/fmapp2/src/com/caf/fmradio/FMRadio.java
index 9865f4a..54baa12 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadio.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadio.java
@@ -31,7 +31,6 @@
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.ProgressDialog;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothDevice;
 import android.content.ComponentName;
@@ -98,6 +97,7 @@
 
 import android.content.SharedPreferences;
 import android.graphics.Color;
+import android.graphics.Point;
 
 public class FMRadio extends Activity
 {
@@ -121,8 +121,6 @@
    /* Dialog Identifiers */
    private static final int DIALOG_SEARCH = 1;
    private static final int DIALOG_SLEEP = 2;
-   private static final int DIALOG_SELECT_PRESET_LIST = 3;
-   private static final int DIALOG_PRESETS_LIST = 4;
    private static final int DIALOG_PRESET_LIST_RENAME = 5;
    private static final int DIALOG_PRESET_LIST_DELETE = 6;
    private static final int DIALOG_PRESET_LIST_AUTO_SET = 7;
@@ -132,7 +130,6 @@
    private static final int DIALOG_PRESET_RENAME = 11;
    private static final int DIALOG_CMD_TIMEOUT = 12;
    private static final int DIALOG_CMD_FAILED = 13;
-   private static final int DIALOG_CMD_FAILED_HDMI_ON = 14;
    private static final int DIALOG_CMD_FAILED_CALL_ON = 15;
    private static final int DIALOG_TAGS = 16;
 
@@ -250,7 +247,15 @@
    /* Radio Vars */
    private Handler mHandler = new Handler();
    /* Search Progress Dialog */
-   private ProgressDialog mProgressDialog = null;
+   private AlertDialog mProgressDialog = null;
+   private Dialog mDlgResetOptions;
+   private Dialog mDlgSearch;
+   private Dialog mDlgSleep;
+   private Dialog mDlgPresetRename;
+   private Dialog mDlgCmdTout;
+   private Dialog mDlgCmdFailed;
+   private Dialog mDlgCmdFailedCallOn;
+   private Dialog mDlgPickFrequency;
 
    /* Asynchronous command active */
    private static int mCommandActive = 0;
@@ -283,14 +288,15 @@
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setVolumeControlStream(AudioManager.STREAM_MUSIC);
+      Log.d(LOGTAG, "onCreate");
       mPrefs = new FmSharedPreferences(this);
       mCommandActive = CMD_NONE;
       mCommandFailed = CMD_NONE;
 
-      Log.d(LOGTAG, "onCreate - Height : "+ getWindowManager().getDefaultDisplay().getHeight()
-            + " - Width  : "+ getWindowManager().getDefaultDisplay().getWidth());
-
-      mDisplayWidth = getWindowManager().getDefaultDisplay().getWidth();
+      Point p = new Point();
+      getWindowManager().getDefaultDisplay().getSize(p);
+      mDisplayWidth = p.x;
+      Log.d(LOGTAG, " Height : " + p.y + " - mDisplayWidth  : " + mDisplayWidth);
       DisplayMetrics outMetrics = new DisplayMetrics();
       getWindowManager().getDefaultDisplay().getMetrics(outMetrics );
 
@@ -593,13 +599,11 @@
       Log.d(LOGTAG, "FMRadio: onDestroy");
       mHandler.removeCallbacksAndMessages(null);
       cleanupTimeoutHandler();
-      if(mProgressDialog != null) {
-         mProgressDialog.dismiss();
-      }
+      closeDialog(DIALOG_PROGRESS_PROGRESS);
       if(mSearchProgressHandler != null) {
          mSearchProgressHandler.removeCallbacksAndMessages(null);
       }
-      removeDialog(DIALOG_PRESET_OPTIONS);
+      closeDialog(DIALOG_PRESET_OPTIONS);
       unRegisterReceiver(mFmSettingReceiver);
       if (mService != null) {
           try {
@@ -624,6 +628,7 @@
       boolean mSpeakerPhoneOn = isSpeakerEnabled();
       boolean sleepActive = isSleepTimerActive();
       boolean searchActive = isScanActive() || isSeekActive();
+      Log.d(LOGTAG, "onCreateOptionsmenu");
 
       item = menu.add(0, MENU_SCAN_START, 0, R.string.menu_scan_start).
                             setIcon(R.drawable.ic_btn_search);
@@ -677,6 +682,7 @@
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
       super.onPrepareOptionsMenu(menu);
+      Log.d(LOGTAG, "onPrepare optionsmenu");
       MenuItem item;
       boolean radioOn = isFmOn();
       boolean recording = isRecording();
@@ -722,6 +728,7 @@
 
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
+       Log.d(LOGTAG, "onOptionSelected");
       switch (item.getItemId()) {
       case MENU_SETTINGS:
          Intent launchPreferencesIntent = new Intent().setClass(this,
@@ -753,10 +760,10 @@
           }
 
          if (mBTsoc.equals("rome")) {
-               clearStationList();
-               initiateSearch(0); // 0 - All stations
-           } else {
-               showDialog(DIALOG_SEARCH);
+             clearStationList();
+             initiateSearch(0); // 0 - All stations
+         } else {
+             displayDialog(DIALOG_SEARCH);
          }
 
          return true;
@@ -770,7 +777,7 @@
          stopRecording();
          return true;
       case MENU_SLEEP:
-         showDialog(DIALOG_SLEEP);
+          displayDialog(DIALOG_SLEEP);
          return true;
       case MENU_SLEEP_CANCEL:
          DebugToasts("Sleep Cancelled", Toast.LENGTH_SHORT);
@@ -889,101 +896,6 @@
    }
 
    @Override
-   protected Dialog onCreateDialog(int id) {
-      AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(this);
-      dlgBuilder.setOnKeyListener(new OnKeyListener() {
-         public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
-             Log.d(LOGTAG, "OnKeyListener event received"+keyCode);
-             switch (keyCode) {
-                 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-                 case 126: //KeyEvent.KEYCODE_MEDIA_PLAY:
-                 case 127: //KeyEvent.KEYCODE_MEDIA_PAUSE:
-                 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
-                 case KeyEvent.KEYCODE_MEDIA_NEXT:
-                 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
-                 case KeyEvent.KEYCODE_MEDIA_REWIND:
-                 case KeyEvent.KEYCODE_MEDIA_STOP:
-                     return true;
-             }
-             return false;
-         }
-      });
-      switch (id) {
-      case DIALOG_SEARCH: {
-            return createSearchDlg(id, dlgBuilder);
-         }
-      case DIALOG_SLEEP: {
-            return createSleepDlg(id, dlgBuilder);
-         }
-      case DIALOG_PROGRESS_PROGRESS: {
-         return createProgressDialog(id);
-        }
-      case DIALOG_PRESET_OPTIONS: {
-         return createPresetOptionsDlg(id, dlgBuilder);
-       }
-      case DIALOG_PRESET_RENAME: {
-         return createPresetRenameDlg(id, dlgBuilder);
-       }
-      case DIALOG_CMD_TIMEOUT:{
-         return createCmdTimeoutDlg(id, dlgBuilder);
-      }
-      case DIALOG_CMD_FAILED:{
-         return createCmdFailedDlg(id, dlgBuilder);
-      }
-      case DIALOG_CMD_FAILED_HDMI_ON:{
-         return createCmdFailedDlgHdmiOn(id);
-      }
-      case DIALOG_CMD_FAILED_CALL_ON:{
-          return createCmdFailedDlgCallOn(id);
-      }
-      case DIALOG_PICK_FREQUENCY: {
-            FmConfig fmConfig = FmSharedPreferences.getFMConfiguration();
-            return new FrequencyPickerDialog(this, fmConfig, mTunedStation.getFrequency(), mFrequencyChangeListener);
-      }
-      default:
-          break;
-      }
-      return null;
-   }
-
-   @Override
-   protected void onPrepareDialog(int id, Dialog dialog) {
-      super.onPrepareDialog(id, dialog);
-      int curListIndex = FmSharedPreferences.getCurrentListIndex();
-      PresetList curList = FmSharedPreferences.getStationList(curListIndex);
-      switch (id) {
-      case DIALOG_PRESET_RENAME: {
-            EditText et = (EditText) dialog.findViewById(R.id.list_edit);
-            if ((et != null) && (mPresetButtonStation != null)) {
-                et.setText(mPresetButtonStation.getName());
-            }
-            break;
-         }
-      case DIALOG_PRESET_OPTIONS: {
-            AlertDialog alertDlg = ((AlertDialog) dialog);
-            if ((alertDlg != null) && (mPresetButtonStation != null)) {
-                alertDlg.setTitle(mPresetButtonStation.getName());
-            }
-            break;
-         }
-      case DIALOG_PICK_FREQUENCY:
-         {
-            if (dialog != null && mTunedStation != null)
-            {
-               FmConfig fmConfig = FmSharedPreferences.getFMConfiguration();
-              ((FrequencyPickerDialog) dialog).updateSteps(fmConfig.getChSpacing());
-              ((FrequencyPickerDialog) dialog).updateMinFreq(fmConfig.getLowerLimit());
-              ((FrequencyPickerDialog) dialog).updateMaxFreq(fmConfig.getUpperLimit());
-              ((FrequencyPickerDialog) dialog).UpdateFrequency(mTunedStation.getFrequency());
-            }
-            break;
-         }
-      default:
-            break;
-      }
-   }
-
-   @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       super.onActivityResult(requestCode, resultCode, data);
       Log.d(LOGTAG, "onActivityResult : requestCode -> " + requestCode);
@@ -993,7 +905,8 @@
              if (data != null) {
                 String action = data.getAction();
                 if (action != null) {
-                  if (action.equals(Settings.RESTORE_FACTORY_DEFAULT_ACTION)) {
+                  if ((action.equals(Settings.RESTORE_FACTORY_DEFAULT_ACTION))
+                                               && (true == isFmOn())) {
                       disableRadio();
                       RestoreDefaults();
                       FmSharedPreferences.setTunedFrequency(FmSharedPreferences.DEFAULT_NO_FREQUENCY);
@@ -1090,7 +1003,7 @@
                     initiateSearch(pty);
                  }
              }
-             removeDialog(DIALOG_SEARCH);
+             closeDialog(DIALOG_SEARCH);
           }
       });
       return dlgBuilder.create();
@@ -1118,7 +1031,7 @@
          dlgBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {
             public void onCancel(DialogInterface dialog) {
                mPresetButtonStation = null;
-               removeDialog(DIALOG_PRESET_OPTIONS);
+               closeDialog(DIALOG_PRESET_OPTIONS);
             }
          });
          String[] items = new String [arrayList.size ()];
@@ -1147,7 +1060,7 @@
                       }
                    case PRESETS_OPTIONS_RENAME: {
                          // Rename
-                         showDialog(DIALOG_PRESET_RENAME);
+                         displayDialog(DIALOG_PRESET_RENAME);
                          break;
                       }
                    case PRESETS_OPTIONS_DELETE: {
@@ -1180,7 +1093,7 @@
                       }
                    }//switch item
                 }//if(mPresetButtonStation != null)
-                removeDialog (DIALOG_PRESET_OPTIONS);
+                closeDialog(DIALOG_PRESET_OPTIONS);
              }//onClick
          });
          return dlgBuilder.create();
@@ -1200,13 +1113,13 @@
                  long seconds = (long) (900 * (item + 1));
                  initiateSleepTimer(seconds);
               }
-              removeDialog (DIALOG_SLEEP);
+              closeDialog(DIALOG_SLEEP);
           }
       });
       return dlgBuilder.create();
    }
 
-   private Dialog createProgressDialog(int id) {
+   private AlertDialog createProgressDialog() {
       String msgStr = "";
       String titleStr = "";
       String []items;
@@ -1240,13 +1153,16 @@
          titleStr = getString(R.string.msg_searching_title);
          bSearchActive = true;
       }
+      Log.v(LOGTAG," bSearchActive :"+bSearchActive);
       if (bSearchActive) {
-          mProgressDialog = new ProgressDialog(FMRadio.this);
-          if (mProgressDialog != null) {
-              mProgressDialog.setTitle(titleStr);
-              mProgressDialog.setMessage(msgStr);
-              mProgressDialog.setIcon(R.drawable.ic_launcher_fmradio);
-              mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
+          AlertDialog.Builder builder = new AlertDialog.Builder(this);
+          builder.setTitle(titleStr);
+          builder.setIcon(R.drawable.ic_launcher_fmradio);
+          View view = getLayoutInflater().inflate(R.layout.layout_dialog_progress,null);
+          builder.setView(view);
+          TextView tvMessage = (TextView)view.findViewById(R.id.id_tv_message);
+          tvMessage.setText(msgStr);
+          mProgressDialog = builder.create();
               mProgressDialog.setCanceledOnTouchOutside(false);
               mProgressDialog.setButton(DialogInterface.BUTTON_POSITIVE,
                                    getText(R.string.button_text_stop),
@@ -1277,7 +1193,6 @@
                     return false;
                 }
             });
-          }
           Message msg = new Message();
           msg.what = TIMEOUT_PROGRESS_DLG;
           mSearchProgressHandler.sendMessageDelayed(msg, SHOWBUSY_TIMEOUT);
@@ -1344,13 +1259,13 @@
                                          mPresetButtonStation=null;
                                          setupPresetLayout();
                                          mPrefs.Save();
-                                         removeDialog(DIALOG_PRESET_RENAME);
+                                         closeDialog(DIALOG_PRESET_RENAME);
                                       }
                                    });
       dlgBuilder.setNegativeButton(R.string.alert_dialog_cancel,
                                    new DialogInterface.OnClickListener() {
                                       public void onClick(DialogInterface dialog, int whichButton) {
-                                         removeDialog(DIALOG_PRESET_RENAME);
+                                         closeDialog(DIALOG_PRESET_RENAME);
                                       }
                                    });
       return(dlgBuilder.create());
@@ -1366,7 +1281,7 @@
                                          public void onClick(DialogInterface dialog,
                                                              int whichButton) {
                                             cleanupTimeoutHandler();
-                                            removeDialog(DIALOG_CMD_TIMEOUT);
+                                            closeDialog(DIALOG_CMD_TIMEOUT);
                                          }
                                       });
          return(dlgBuilder.create());
@@ -1384,25 +1299,7 @@
                                    new DialogInterface.OnClickListener() {
                                       public void onClick(DialogInterface dialog,
                                                           int whichButton) {
-                                         removeDialog(DIALOG_CMD_TIMEOUT);
-                                         mCommandFailed = CMD_NONE;
-                                      }
-                                   });
-
-      return(dlgBuilder.create());
-   }
-
-   private Dialog createCmdFailedDlgHdmiOn(int id) {
-      AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(this);
-      dlgBuilder.setIcon(R.drawable.alert_dialog_icon)
-                .setTitle(R.string.fm_command_failed_title);
-      dlgBuilder.setMessage(R.string.fm_cmd_failed_msg_hdmi);
-
-      dlgBuilder.setPositiveButton(R.string.alert_dialog_ok,
-                                   new DialogInterface.OnClickListener() {
-                                      public void onClick(DialogInterface dialog,
-                                                          int whichButton) {
-                                         removeDialog(DIALOG_CMD_TIMEOUT);
+                                          closeDialog(DIALOG_CMD_FAILED);
                                          mCommandFailed = CMD_NONE;
                                       }
                                    });
@@ -1420,7 +1317,7 @@
                                     new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog,
                                                            int whichButton) {
-                                          removeDialog(DIALOG_CMD_TIMEOUT);
+                                           closeDialog(DIALOG_CMD_FAILED_CALL_ON);
                                           mCommandFailed = CMD_NONE;
                                           finish();
                                        }
@@ -1441,7 +1338,10 @@
    private View.OnLongClickListener mFrequencyViewClickListener =
       new View.OnLongClickListener() {
         public boolean onLongClick(View v) {
-          showDialog(DIALOG_PICK_FREQUENCY);
+          FmConfig fmConfig = FmSharedPreferences.getFMConfiguration();
+          mDlgPickFrequency = new FrequencyPickerDialog(FMRadio.this, fmConfig,
+                        mTunedStation.getFrequency(), mFrequencyChangeListener);
+          mDlgPickFrequency.show();
           return true;
         }
    };
@@ -1480,20 +1380,6 @@
         }
    };
 
-   private View.OnClickListener mPresetListClickListener =
-      new View.OnClickListener() {
-        public void onClick(View v) {
-          showDialog(DIALOG_SELECT_PRESET_LIST);
-        }
-   };
-   private View.OnLongClickListener mPresetListButtonOnLongClickListener =
-      new View.OnLongClickListener() {
-        public boolean onLongClick(View view) {
-          showDialog(DIALOG_PRESETS_LIST);
-          return true;
-        }
-   };
-
    private View.OnClickListener mPresetsPageClickListener =
       new View.OnClickListener() {
         public void onClick(View v) {
@@ -1521,7 +1407,9 @@
            PresetStation station = (PresetStation)view.getTag();
            mPresetButtonStation = station;
            if (station != null) {
-               showDialog(DIALOG_PRESET_OPTIONS);
+               Log.v(LOGTAG," onLongClick DIALOG_PRESET_OPTIONS :");
+               closeDialog(DIALOG_PRESET_OPTIONS);
+               displayDialog(DIALOG_PRESET_OPTIONS);
            }else {
                addToPresets();
                view.startAnimation(mAnimation);
@@ -1576,9 +1464,9 @@
                }else {
                    mCommandFailed = CMD_MUTE;
                    if(isCallActive()) {
-                      showDialog(DIALOG_CMD_FAILED_CALL_ON);
+                       displayDialog(DIALOG_CMD_FAILED_CALL_ON);
                    }else {
-                      showDialog(DIALOG_CMD_FAILED);
+                       displayDialog(DIALOG_CMD_FAILED);
                    }
                }
               }catch (RemoteException e) {
@@ -1692,9 +1580,10 @@
                    mCommandFailed = CMD_FMON;
                    if(isCallActive()) {
                       enableRadioOnOffUI();
-                      showDialog(DIALOG_CMD_FAILED_CALL_ON);
+                      mDlgCmdFailedCallOn = createCmdFailedDlgCallOn(DIALOG_CMD_FAILED_CALL_ON);
+                      mDlgCmdFailedCallOn.show();
                    }else {
-                      showDialog(DIALOG_CMD_FAILED);
+                      displayDialog(DIALOG_CMD_FAILED);
                    }
                 }
             }else {
@@ -2106,7 +1995,7 @@
       if (searchActive) {
          synchronized (this) {
             if(mProgressDialog == null) {
-               showDialog(DIALOG_PROGRESS_PROGRESS);
+                displayDialog(DIALOG_PROGRESS_PROGRESS);
             }else {
                Message msg = new Message();
                msg.what = UPDATE_PROGRESS_DLG;
@@ -2241,7 +2130,7 @@
                if (mIsSeeking == false) {
                   mCommandFailed = CMD_SEEK;
                   Log.e(LOGTAG, "mService.seek failed");
-                  showDialog(DIALOG_CMD_FAILED);
+                  displayDialog(DIALOG_CMD_FAILED);
                }
             }
          }catch (RemoteException e) {
@@ -2260,7 +2149,7 @@
                if (mIsSeeking == false) {
                   mCommandFailed = CMD_SEEK;
                   Log.e(LOGTAG, "mService.seek failed");
-                  showDialog(DIALOG_CMD_FAILED);
+                  displayDialog(DIALOG_CMD_FAILED);
                }
             }
          }catch (RemoteException e) {
@@ -2290,7 +2179,7 @@
                if (mIsScaning == false) {
                   mCommandFailed = CMD_SCAN;
                   Log.e(LOGTAG, "mService.scan failed");
-                  showDialog(DIALOG_CMD_FAILED);
+                  displayDialog(DIALOG_CMD_FAILED);
                }else {
                   mScanPty = pty;
                }
@@ -2312,7 +2201,7 @@
                if (mIsSeeking == false) {
                   mCommandFailed = CMD_SEEKPI;
                   Log.e(LOGTAG, "mService.seekPI failed");
-                  showDialog(DIALOG_CMD_FAILED);
+                  displayDialog(DIALOG_CMD_FAILED);
                }
             }
          }catch (RemoteException e) {
@@ -2360,7 +2249,7 @@
                if (mIsSearching == false) {
                   mCommandFailed = CMD_SEARCHLIST;
                   Log.e(LOGTAG, "mService.searchStrongStationList failed");
-                  showDialog(DIALOG_CMD_FAILED);
+                  displayDialog(DIALOG_CMD_FAILED);
                }
             }catch (RemoteException e) {
                e.printStackTrace();
@@ -2386,7 +2275,7 @@
               mSearchProgressHandler.removeMessages(END_PROGRESS_DLG);
               mSearchProgressHandler.removeMessages(UPDATE_PROGRESS_DLG);
               mSearchProgressHandler.removeMessages(TIMEOUT_PROGRESS_DLG);
-              removeDialog(DIALOG_PROGRESS_PROGRESS);
+              closeDialog(DIALOG_PROGRESS_PROGRESS);
               mProgressDialog = null;
            }else if (msg.what == TIMEOUT_PROGRESS_DLG) {
               cancelSearch();
@@ -2607,7 +2496,7 @@
                if (isFmOn()) {
                   mCommandFailed = CMD_TUNE;
                   Log.e(LOGTAG, "mService.tune failed");
-                  showDialog(DIALOG_CMD_FAILED);
+                  displayDialog(DIALOG_CMD_FAILED);
                }
              }
              mTunedStation.setName("");
@@ -2647,7 +2536,7 @@
                if (mCommandActive > 0) {
                   Log.d(LOGTAG, "mCommandTimeoutHandler: Cmd failed: " + mCommandActive);
                   mCommandTimeoutHandler.removeMessages(MSG_CMD_TIMEOUT);
-                  showDialog(DIALOG_CMD_TIMEOUT);
+                  displayDialog(DIALOG_CMD_TIMEOUT);
                   return;
                }
                break;
@@ -3317,4 +3206,117 @@
            myReceiver = null;
         }
     }
+
+    private void displayDialog(int id) {
+        Log.d(LOGTAG, " disaplyDialog " + id);
+        AlertDialog.Builder dlgBuilder = null;
+        if (id != DIALOG_PROGRESS_PROGRESS) {
+            dlgBuilder = new AlertDialog.Builder(this);
+            dlgBuilder.setOnKeyListener(new OnKeyListener() {
+                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
+                    Log.d(LOGTAG, "OnKeyListener event received" + keyCode);
+                    switch (keyCode) {
+                    case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                    case 126: // KeyEvent.KEYCODE_MEDIA_PLAY:
+                    case 127: // KeyEvent.KEYCODE_MEDIA_PAUSE:
+                    case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+                    case KeyEvent.KEYCODE_MEDIA_NEXT:
+                    case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+                    case KeyEvent.KEYCODE_MEDIA_REWIND:
+                    case KeyEvent.KEYCODE_MEDIA_STOP:
+                        return true;
+                    }
+                    return false;
+                }
+            });
+        }
+        switch (id) {
+        case DIALOG_PROGRESS_PROGRESS:
+            mProgressDialog = createProgressDialog();
+            mProgressDialog.show();
+            break;
+        case DIALOG_PRESET_OPTIONS:
+            mDlgResetOptions = createPresetOptionsDlg(DIALOG_PRESET_OPTIONS, dlgBuilder);
+            mDlgResetOptions.show();
+            break;
+        case DIALOG_SEARCH:
+            mDlgSearch = createSearchDlg(DIALOG_SEARCH, dlgBuilder);
+            mDlgSearch.show();
+            break;
+        case DIALOG_SLEEP:
+            mDlgSleep = createSleepDlg(DIALOG_SLEEP, dlgBuilder);
+            mDlgSleep.show();
+            break;
+        case DIALOG_PRESET_RENAME:
+            mDlgPresetRename = createPresetRenameDlg(DIALOG_PRESET_RENAME, dlgBuilder);
+            mDlgPresetRename.show();
+            break;
+        case DIALOG_CMD_TIMEOUT:
+            mDlgCmdTout = createCmdTimeoutDlg(DIALOG_CMD_TIMEOUT, dlgBuilder);
+            mDlgCmdTout.show();
+            break;
+        case DIALOG_CMD_FAILED:
+            mDlgCmdFailed = createCmdFailedDlg(DIALOG_CMD_FAILED, dlgBuilder);
+            mDlgCmdFailed.show();
+            break;
+        case DIALOG_CMD_FAILED_CALL_ON:
+            mDlgCmdFailedCallOn = createCmdFailedDlgCallOn(DIALOG_CMD_FAILED_CALL_ON);
+            mDlgCmdFailedCallOn.show();
+            break;
+        }
+    }
+
+    private void closeDialog(int id) {
+        Log.d(LOGTAG, " closeDialog " + id);
+        switch (id) {
+        case DIALOG_PROGRESS_PROGRESS:
+            if (mProgressDialog != null && mProgressDialog.isShowing()) {
+                mProgressDialog.dismiss();
+            }
+            break;
+        case DIALOG_PRESET_OPTIONS:
+            if (mDlgResetOptions != null && mDlgResetOptions.isShowing()) {
+                mDlgResetOptions.dismiss();
+            }
+            break;
+        case DIALOG_SEARCH:
+            if (mDlgSearch != null && mDlgSearch.isShowing()) {
+                mDlgSearch.dismiss();
+            }
+            mDlgSearch = null;
+            break;
+        case DIALOG_SLEEP:
+            if (mDlgSleep != null && mDlgSleep.isShowing()) {
+                mDlgSleep.dismiss();
+            }
+            mDlgSleep = null;
+        case DIALOG_PRESET_RENAME:
+            if (mDlgPresetRename != null && mDlgPresetRename.isShowing()) {
+                mDlgPresetRename.dismiss();
+            }
+            mDlgPresetRename = null;
+            break;
+        case DIALOG_CMD_TIMEOUT:
+            if (mDlgCmdTout != null && mDlgCmdTout.isShowing()) {
+                mDlgCmdTout.dismiss();
+            }
+            mDlgCmdTout = null;
+            break;
+        case DIALOG_CMD_FAILED:
+            if (mDlgCmdFailed != null && mDlgCmdFailed.isShowing()) {
+                mDlgCmdFailed.dismiss();
+            }
+            mDlgCmdFailed = null;
+            break;
+        case DIALOG_CMD_FAILED_CALL_ON:
+            if (mDlgCmdFailedCallOn != null && mDlgCmdFailedCallOn.isShowing()) {
+                mDlgCmdFailedCallOn.dismiss();
+            }
+            mDlgCmdFailedCallOn = null;
+            break;
+
+        default:
+            break;
+        }
+    }
 }
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
index 24be178..5a08422 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadioService.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -60,6 +60,8 @@
 import android.media.AudioRecord;
 import android.media.AudioTrack;
 import android.media.AudioDeviceInfo;
+import android.media.AudioAttributes;
+import android.media.AudioFocusRequest;
 
 import android.os.Environment;
 import android.os.Handler;
@@ -213,15 +215,7 @@
    private boolean mIsSSRInProgress = false;
    private boolean mIsSSRInProgressFromActivity = false;
    private int mKeyActionDownCount = 0;
-   private static final int AUDIO_SAMPLE_RATE = 44100;
-   private static final int AUDIO_CHANNEL_CONFIG =
-                                   AudioFormat.CHANNEL_CONFIGURATION_STEREO;
-   private static final int AUDIO_ENCODING_FORMAT =
-                                           AudioFormat.ENCODING_PCM_16BIT;
-   private static final int FM_RECORD_BUF_SIZE =
-                      AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE,
-                                   AUDIO_CHANNEL_CONFIG, AUDIO_ENCODING_FORMAT);
-   private AudioRecord mAudioRecord = null;
+
    private AudioTrack mAudioTrack = null;
    private static final int AUDIO_FRAMES_COUNT_TO_IGNORE = 3;
    private Object mEventWaitLock = new Object();
@@ -240,6 +234,7 @@
 
    private boolean mEventReceived = false;
    private boolean isfmOffFromApplication = false;
+   private AudioFocusRequest mGainFocusReq;
 
    public FMRadioService() {
    }
@@ -273,8 +268,7 @@
 
       mSession = new MediaSession(getApplicationContext(), this.getClass().getName());
       mSession.setCallback(mSessionCallback);
-      mSession.setFlags(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY |
-                             MediaSession.FLAG_HANDLES_MEDIA_BUTTONS);
+      mSession.setFlags(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY);
       if ( false == SystemProperties.getBoolean("ro.fm.mulinst.recording.support",true)) {
            mSingleRecordingInstanceSupported = true;
       }
@@ -293,6 +287,8 @@
 
       getA2dpStatusAtStart();
 
+      mGainFocusReq = requestAudioFocus();
+
    }
 
    @Override
@@ -308,7 +304,8 @@
       cancelAlarms();
       //release the audio focus listener
       AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-      audioManager.abandonAudioFocus(mAudioFocusListener);
+      audioManager.abandonAudioFocusRequest(mGainFocusReq);
+      mGainFocusReq = null;
       /* Remove the Screen On/off listener */
       if (mScreenOnOffReceiver != null) {
           unregisterReceiver(mScreenOnOffReceiver);
@@ -681,7 +678,7 @@
                         if (cmd != null && cmd.equals("pause")) {
                             if (isFmOn()) {
                                 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-                                audioManager.abandonAudioFocus(mAudioFocusListener);
+                                audioManager.abandonAudioFocusRequest(mGainFocusReq);
                                 mDelayedStopHandler.obtainMessage(FOCUSCHANGE, AudioManager.AUDIOFOCUS_LOSS, 0).sendToTarget();
 
                                 if (isOrderedBroadcast()) {
@@ -843,7 +840,7 @@
    }
 
    @Override
-   public void onStart(Intent intent, int startId) {
+   public int onStartCommand(Intent intent, int flags, int startId) {
       Log.d(LOGTAG, "onStart");
       mServiceStartId = startId;
       // make sure the service will shut down on its own if it was
@@ -851,6 +848,8 @@
       mDelayedStopHandler.removeCallbacksAndMessages(null);
       cancelAlarmDealyedServiceStop();
       setAlarmDelayedServiceStop();
+
+      return START_STICKY;
    }
 
    @Override
@@ -1000,6 +999,22 @@
         }
    };
 
+   private AudioFocusRequest requestAudioFocus() {
+       AudioAttributes playbackAttr = new AudioAttributes.Builder()
+       .setUsage(AudioAttributes.USAGE_MEDIA)
+       .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+       .build();
+       AudioFocusRequest focusRequest =
+           new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
+       .setAudioAttributes(playbackAttr)
+       .setAcceptsDelayedFocusGain(true)
+       .setWillPauseWhenDucked(true)
+       .setOnAudioFocusChangeListener(this::onAudioFocusChange)
+       .build();
+
+       return focusRequest;
+   }
+
    private void startFM() {
        Log.d(LOGTAG, "In startFM");
        if(true == mAppShutdown) { // not to send intent to AudioManager in Shutdown
@@ -1024,9 +1039,7 @@
            for(int i = 0; i < 4; i++)
            {
               AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-              int granted =
-                   audioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
-                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+              int granted = audioManager.requestAudioFocus(mGainFocusReq);
               if (granted == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                   Log.d(LOGTAG, "audio focuss granted");
                   break;
@@ -1045,11 +1058,15 @@
        }
        mSession.setActive(true);
 
-       Log.d(LOGTAG,"FM registering for registerMediaButtonEventReceiver");
+       Log.d(LOGTAG,"FM registering for MediaButtonReceiver");
        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        ComponentName fmRadio = new ComponentName(this.getPackageName(),
                                   FMMediaButtonIntentReceiver.class.getName());
-       mAudioManager.registerMediaButtonEventReceiver(fmRadio);
+       Intent mediaButtonIntent =
+               new Intent(Intent.ACTION_MEDIA_BUTTON).setComponent(fmRadio);
+       PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0,
+                          mediaButtonIntent, 0);
+       mSession.setMediaButtonReceiver(pi);
 
        mStoppedOnFocusLoss = false;
        mPlaybackInProgress = true;
@@ -1729,11 +1746,8 @@
       Log.d(LOGTAG,"in stop");
 
       if (!mServiceInUse) {
-          Log.d(LOGTAG,"calling unregisterMediaButtonEventReceiver in stop");
-          mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-          ComponentName fmRadio = new ComponentName(this.getPackageName(),
-                                  FMMediaButtonIntentReceiver.class.getName());
-          mAudioManager.unregisterMediaButtonEventReceiver(fmRadio);
+          Log.d(LOGTAG,"release media session");
+          mSession.release();
       }
       if (mSession.isActive()) {
           mSession.setActive(false);
@@ -2346,7 +2360,7 @@
                               // failure of enable can be because handle
                               // already open which gets effected if
                               // we disable
-            audioManager.abandonAudioFocus(mAudioFocusListener);
+            audioManager.abandonAudioFocusRequest(mGainFocusReq);
             stop();
        }
 
@@ -2417,7 +2431,7 @@
          // 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);
+             audioManager.abandonAudioFocusRequest(mGainFocusReq);
              mStoppedOnFocusLoss = true;
          }
          //audioManager.setParameters("FMRadioOn=false");
@@ -3158,7 +3172,7 @@
        try {
             File sampleDir = Environment.getExternalStorageDirectory();
             StatFs stat = new StatFs(sampleDir.getAbsolutePath());
-            return stat.getAvailableBlocks() * (long) stat.getBlockSize();
+            return stat.getAvailableBlocksLong() * stat.getBlockSizeLong();
        } catch (Exception e) {
             Log.i(LOGTAG, "Fail to access external storage", e);
        }
@@ -3995,8 +4009,7 @@
           (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);
+           audioManager.requestAudioFocus(mGainFocusReq);
            startFM();
            mStoppedOnFocusLoss = false;
        }
@@ -4010,8 +4023,7 @@
           (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);
+           audioManager.requestAudioFocus(mGainFocusReq);
            startFM();
            if (mReceiver.isCherokeeChip() && (mPref.getBoolean("SLIMBUS_SEQ", true))) {
               enableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
@@ -4030,11 +4042,11 @@
        Log.d(LOGTAG, "--requestFocus");
    }
 
-   private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() {
-       public void onAudioFocusChange(int focusChange) {
+
+   public void onAudioFocusChange(int focusChange) {
            mDelayedStopHandler.obtainMessage(FOCUSCHANGE, focusChange, 0).sendToTarget();
-       }
-   };
+   }
+
 
    class A2dpServiceListener implements BluetoothProfile.ServiceListener {
        private List<BluetoothDevice> mA2dpDeviceList = null;
diff --git a/fmapp2/src/com/caf/fmradio/FMStats.java b/fmapp2/src/com/caf/fmradio/FMStats.java
index 40cb4ec..fadeef2 100644
--- a/fmapp2/src/com/caf/fmradio/FMStats.java
+++ b/fmapp2/src/com/caf/fmradio/FMStats.java
@@ -71,6 +71,7 @@
 import android.view.MenuItem;
 import android.view.MenuInflater;
 import android.os.SystemClock;
+import android.graphics.Point;
 
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -293,6 +294,7 @@
     private BroadcastReceiver mBandSweepDwellExprdListener = null;
 
     private WakeLock mWakeLock;
+    private Dialog mDialgBandSweep;
 
     private GetNextFreqInterface mNextFreqInterface;
     private CommaSeparatedFreqFileReader mFreqFileReader;
@@ -543,7 +545,7 @@
         Log.d(LOGTAG, "onDestroy: unbindFromService completed");
         mReceiver = null;
         mService = null;
-        removeDialog(DIALOG_BAND_SWEEP_SETTING);
+        closeDialog(DIALOG_BAND_SWEEP_SETTING);
         mWakeLock.release();
         super.onDestroy();
     }
@@ -2920,9 +2922,11 @@
          /* Create a new row to be added. */
         mNewRowIds++;
         TableRow tr2 = new TableRow(getApplicationContext());
-        int width = getWindowManager().getDefaultDisplay().getWidth();
+        Point size = new Point();
+        getWindowManager().getDefaultDisplay().getSize(size);
+        int width = size.x;
         tr2.setLayoutParams(new LayoutParams(
-                     LayoutParams.FILL_PARENT,
+                     LayoutParams.MATCH_PARENT,
                      LayoutParams.WRAP_CONTENT));
         tr2.setId(mNewRowIds);
         /* Create a Button to be the row-content. */
@@ -2965,7 +2969,7 @@
           /* Add row to TableLayout. */
           /* Add row to TableLayout. */
         tl.addView(tr2,new TableLayout.LayoutParams(
-             LayoutParams.FILL_PARENT,
+             LayoutParams.MATCH_PARENT,
              LayoutParams.WRAP_CONTENT));
         if(null != mFileCursor)
         {
@@ -3712,17 +3716,6 @@
          }
      }
 
-     @Override
-     protected Dialog onCreateDialog(int id) {
-         AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(this);
-         switch(id)
-         {
-         case DIALOG_BAND_SWEEP_SETTING:
-              return createBandSweepDialog(id, dlgBuilder);
-         }
-         return null;
-     }
-
      private Dialog createBandSweepDialog(int id, AlertDialog.Builder dlgBuilder) {
          LayoutInflater inflater = LayoutInflater.from(this);
          final View listview = inflater.inflate(R.layout.band_sweep_setting, null);
@@ -3755,12 +3748,12 @@
                            String s = dwellBox.getText().toString();
                            prevDwellTime = Integer.parseInt(s);
                         }
-                        removeDialog(DIALOG_BAND_SWEEP_SETTING);
+                        closeDialog(DIALOG_BAND_SWEEP_SETTING);
                     }
                 })
                 .setNegativeButton(R.string.band_sweep_setting_cancel, new DialogInterface.OnClickListener() {
                     public void onClick(DialogInterface dialog, int id) {
-                        removeDialog(DIALOG_BAND_SWEEP_SETTING);
+                        closeDialog(DIALOG_BAND_SWEEP_SETTING);
                     }
                 });
          return dlgBuilder.create();
@@ -3768,7 +3761,9 @@
 
     private View.OnClickListener mClicktBandSweepSettingListener = new View.OnClickListener() {
          public void onClick(View v) {
-            showDialog(DIALOG_BAND_SWEEP_SETTING);
+            AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(FMStats.this);
+            mDialgBandSweep = createBandSweepDialog(DIALOG_BAND_SWEEP_SETTING, dlgBuilder);
+            mDialgBandSweep.show();
          }
     };
 
@@ -4081,4 +4076,15 @@
        stopCurTest();
        stopRecording();
     }
+
+    private void closeDialog(int id) {
+        Log.d(LOGTAG, " closeDialog " + id);
+        switch (id) {
+        case DIALOG_BAND_SWEEP_SETTING:
+            if (mDialgBandSweep != null && mDialgBandSweep.isShowing()) {
+                mDialgBandSweep.dismiss();
+            }
+            break;
+        }
+    }
 }
diff --git a/fmapp2/src/com/caf/fmradio/FMTransmitterActivity.java b/fmapp2/src/com/caf/fmradio/FMTransmitterActivity.java
deleted file mode 100644
index 7ae8762..0000000
--- a/fmapp2/src/com/caf/fmradio/FMTransmitterActivity.java
+++ /dev/null
@@ -1,1608 +0,0 @@
-/*
- * Copyright (c) 2009-2013, 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.
- */
-
-package com.caf.fmradio;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.BroadcastReceiver;
-import android.content.SharedPreferences;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.media.AudioManager;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.Window;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.ImageView; //import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-import android.text.TextUtils; //import android.app.ProgressDialog;
-import android.util.DisplayMetrics;
-
-import java.lang.ref.WeakReference; //import java.text.DecimalFormat;
-import java.util.HashMap;
-import java.util.ArrayList;
-
-import com.caf.utils.FrequencyPicker;
-import com.caf.utils.FrequencyPickerDialog;
-import android.content.ServiceConnection;
-
-import qcom.fmradio.FmConfig;
-import android.os.ServiceManager;
-
-import com.caf.fmradio.HorizontalNumberPicker.OnScrollFinishListener;
-import com.caf.fmradio.HorizontalNumberPicker.OnValueChangeListener;
-import com.caf.fmradio.HorizontalNumberPicker.Scale;
-
-public class FMTransmitterActivity extends Activity {
-   public static final String LOGTAG = "FMTransmitterActivity";
-
-   /* menu Identifiers */
-   private static final int MENU_SCAN_START = Menu.FIRST + 1;
-   private static final int MENU_SCAN_STOP = Menu.FIRST + 2;
-   private static final int MENU_SETTINGS = Menu.FIRST + 3;
-
-   /* Dialog Identifiers */
-   private static final int DIALOG_PRESET_LIST_AUTO_SET = 1;
-   private static final int DIALOG_PICK_FREQUENCY = 2;
-   private static final int DIALOG_PRESET_OPTIONS = 3;
-   private static final int DIALOG_PROGRESS_PROGRESS = 5;
-   private static final int DIALOG_CMD_FAILED_HDMI_ON = 14;
-   /* Activity Return ResultIdentifiers */
-   private static final int ACTIVITY_RESULT_SETTINGS = 1;
-
-   private static final int MAX_PRESETS = 7;
-   private IFMTransmitterService mService = null;
-   private FmSharedPreferences mPrefs;
-
-   /* Button Resources */
-   private ImageView mOnOffButton;
-   private  HorizontalNumberPicker mPicker;
-   /* 6 Preset Buttons */
-   private Button[] mPresetButtons = {null, null, null, null, null, null, null};
-   private int[] mPresetFrequencies = {0, 0, 0, 0, 0, 0, 0};
-   // private ImageButton mSearchButton;
-   private ImageView mForwardButton;
-   private ImageView mBackButton;
-
-   /* row in the station info layout */
-   private TextView mTransmitStaticMsgTV;
-   private TextView mTuneStationFrequencyTV;
-
-   /* Bottom row in the station info layout */
-   private TextView mRadioTextTV;
-
-   /* Current Status Indicators */
-   private static boolean mIsSearching = false;
-   private static boolean mSearchingResultStatus = false;
-
-   private boolean mInternalAntennaAvailable = false;
-
-   private Animation mAnimation = null;
-   private ScrollerText mRadioTextScroller = null;
-
-   private static int mTunedFrequency = 0;
-   private int mFrequency;
-   private int mPresetButtonIndex = -1;
-   private String mMetaData = null;
-   private String mPSData = null;
-
-   /* Radio Vars */
-   private Handler mHandler = new Handler();
-   private Handler enableRadioHandler = new Handler();
-   private Handler disableRadioHandler = new Handler();
-
-   /* Search Progress Dialog */
-   private ProgressDialog mProgressDialog = null;
-
-   private LoadedDataAndState SavedDataAndState = null;
-
-   private static int mDisplayWidth;
-   private static final int TEXTSIZE_PARAMETER_FOR_NUMBER_PICKER = 20;
-   private static final int FREQUENCY_STEP_SMALL = 50;
-   private static final int FREQUENCY_STEP_MEDIUM = 100;
-   private static final int FREQUENCY_STEP_LARGE = 200;
-   public static boolean mUpdatePickerValue = false;
-
-   private BroadcastReceiver mFmSettingReceiver = null;
-   /** Called when the activity is first created. */
-   @Override
-   public void onCreate(Bundle savedInstanceState) {
-
-      super.onCreate(savedInstanceState);
-      mPrefs = new FmSharedPreferences(this);
-      Log.d(LOGTAG, "onCreate - Height : "
-             + getWindowManager().getDefaultDisplay().getHeight()
-             + " - Width  : "
-             + getWindowManager().getDefaultDisplay().getWidth());
-
-      mDisplayWidth = getWindowManager().getDefaultDisplay().getWidth();
-      DisplayMetrics outMetrics = new DisplayMetrics();
-      getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
-
-      setContentView(R.layout.fmtransmitter);
-      SavedDataAndState = (LoadedDataAndState)getLastNonConfigurationInstance();
-      mAnimation = AnimationUtils.loadAnimation(this, R.anim.preset_select);
-
-      mPicker = (HorizontalNumberPicker)findViewById(R.id.fm_picker);
-      if(mPicker != null) {
-         mPicker.setTextSize(mDisplayWidth / TEXTSIZE_PARAMETER_FOR_NUMBER_PICKER);
-         mPicker.setDensity(outMetrics.densityDpi);
-         mPicker.setOnValueChangedListener(new OnValueChangeListener() {
-         @Override
-           public void onValueChange(HorizontalNumberPicker picker,
-             int oldVal, int newVal) {
-             // TODO Auto-generated method stub
-             valueToFrequency(newVal);
-             mHandler.post(mRadioChangeFrequency);
-           }
-         });
-       }
-       mOnOffButton = (ImageView)findViewById(R.id.btn_onoff);
-       if(mOnOffButton != null) {
-          mOnOffButton.setOnClickListener(mTurnOnOffClickListener);
-       }
-       mForwardButton = (ImageView)findViewById(R.id.btn_forward);
-       if(mForwardButton != null) {
-          mForwardButton.setOnClickListener(mForwardClickListener);
-       }
-       mBackButton = (ImageView)findViewById(R.id.btn_back);
-       if(mBackButton != null) {
-          mBackButton.setOnClickListener(mBackClickListener);
-       }
-
-       /* Preset Buttons */
-       mPresetButtons[0] = (Button)findViewById(R.id.presets_button_1);
-       mPresetButtons[1] = (Button)findViewById(R.id.presets_button_2);
-       mPresetButtons[2] = (Button)findViewById(R.id.presets_button_3);
-       mPresetButtons[3] = (Button)findViewById(R.id.presets_button_4);
-       mPresetButtons[4] = (Button)findViewById(R.id.presets_button_5);
-       mPresetButtons[5] = (Button)findViewById(R.id.presets_button_6);
-       mPresetButtons[6] = (Button)findViewById(R.id.presets_button_7);
-       for(int nButton = 0; nButton < MAX_PRESETS; nButton++) {
-          if (mPresetButtons[nButton] != null) {
-              mPresetButtons[nButton].setOnClickListener(
-                                        mPresetButtonClickListener);
-              mPresetButtons[nButton].setOnLongClickListener(
-                                            mPresetButtonOnLongClickListener);
-          }
-       }
-
-       mTransmitStaticMsgTV = (TextView)findViewById(R.id.transmit_msg_tv);
-       String str = getString(R.string.transmit_msg_string);
-       if(null != mPSData) {
-          str = mPSData.concat("\n").concat(str);
-       }
-       if(mTransmitStaticMsgTV != null) {
-          mTransmitStaticMsgTV.setText(str);
-       }
-
-       mTuneStationFrequencyTV = (TextView)findViewById(R.id.prog_frequency_tv);
-       if(mTuneStationFrequencyTV != null) {
-          mTuneStationFrequencyTV.setOnLongClickListener(
-                                       mFrequencyViewClickListener);
-       }
-       mRadioTextTV = (TextView)findViewById(R.id.radio_text_tv);
-
-       if((mRadioTextScroller == null) && (mRadioTextTV != null)) {
-          mRadioTextScroller = new ScrollerText(mRadioTextTV);
-       }
-
-       enableRadioOnOffUI(false);
-
-       if(false == bindToService(this, osc)) {
-          Log.d(LOGTAG, "onCreate: Failed to Start Service");
-       }else {
-          Log.d(LOGTAG, "onCreate: Start Service completed successfully");
-       }
-       registerFMSettingListner();
-   }
-
-   @Override
-   public void onRestart() {
-      Log.d(LOGTAG, "onRestart");
-      super.onRestart();
-   }
-
-   @Override
-   public void onStop() {
-      Log.d(LOGTAG, "onStop");
-      super.onStop();
-   }
-
-   @Override
-   public void onStart() {
-      super.onStart();
-      Log.d(LOGTAG, "onStart");
-      try {
-           if(mService != null) {
-              mService.registerCallbacks(mServiceCallbacks);
-           }
-      }catch(RemoteException e) {
-           e.printStackTrace();
-      }
-
-   }
-
-   @Override
-   protected void onPause() {
-      super.onPause();
-      mRadioTextScroller.stopScroll();
-      SavePreferences();
-   }
-
-   private static final String TX_PREF_LAST_TUNED_FREQUENCY = "last_tx_frequency";
-   private static final String TX_PRESET_FREQUENCY = "tx_preset_freq_";
-   private static final int DEFAULT_NO_FREQUENCY = 98100;
-
-   public void SavePreferences() {
-       Log.d(LOGTAG, "Save preferences");
-       SharedPreferences sp = getPreferences(Context.MODE_PRIVATE);
-       SharedPreferences.Editor ed = sp.edit();
-
-       ed.putInt(TX_PREF_LAST_TUNED_FREQUENCY, mTunedFrequency);
-
-       for(int presetIndex = 0; presetIndex < MAX_PRESETS; presetIndex++) {
-           ed.putInt(TX_PRESET_FREQUENCY + presetIndex,
-                                        mPresetFrequencies[presetIndex]);
-       }
-       ed.commit();
-   }
-
-   public void LoadPreferences() {
-      SharedPreferences sp = getPreferences(Context.MODE_PRIVATE);
-      mTunedFrequency = sp.getInt(
-                  TX_PREF_LAST_TUNED_FREQUENCY, DEFAULT_NO_FREQUENCY);
-      for(int presetIndex = 0; presetIndex < MAX_PRESETS; presetIndex++) {
-          mPresetFrequencies[presetIndex] = sp.getInt(
-                          TX_PRESET_FREQUENCY + presetIndex,
-                          DEFAULT_NO_FREQUENCY);
-      }
-   }
-
-   protected void setDisplayvalue() {
-      int max = mPrefs.getUpperLimit();
-      int min = mPrefs.getLowerLimit();
-      int step = mPrefs.getFrequencyStepSize();
-
-      if(mPicker == null)
-         return;
-
-      switch(step) {
-      case FREQUENCY_STEP_SMALL:
-           mPicker.setScale(Scale.SCALE_SMALL);
-           break;
-      case FREQUENCY_STEP_MEDIUM:
-           mPicker.setScale(Scale.SCALE_MEDIUM);
-           break;
-      case FREQUENCY_STEP_LARGE:
-           mPicker.setScale(Scale.SCALE_LARGE);
-           break;
-      }
-      int channels = (int)((max - min) / step);
-      String [] displayValues = new String[channels + 1];
-      for(int i = 0; i < displayValues.length; i++) {
-          displayValues[i] = String.valueOf((min + i * step) / 1000.0f);
-      }
-      if(mPicker != null) {
-         mPicker.setDisplayedValues(displayValues, true);
-         mPicker.setWrapSelectorWheel(true);
-         mPicker.invalidate();
-      }
-   }
-   @Override
-   public void onResume() {
-      super.onResume();
-      Log.d(LOGTAG, "Resuming");
-      LoadPreferences();
-      if(mPicker != null) {
-         setDisplayvalue();
-      }
-      mUpdatePickerValue = true;
-      mHandler.post(mUpdateRadioText);
-      updateStationInfoToUI();
-      enableRadioOnOffUI();
-   }
-
-   @Override
-   public void onDestroy() {
-      super.onDestroy();
-      mHandler.removeCallbacksAndMessages(null);
-      if(mProgressDialog != null) {
-         mProgressDialog.dismiss();
-         mProgressDialog = null;
-      }
-      if(mSearchProgressHandler != null) {
-         mSearchProgressHandler.removeCallbacksAndMessages(null);
-      }
-      removeDialog(DIALOG_PRESET_LIST_AUTO_SET);
-      unRegisterReceiver(mFmSettingReceiver);
-      unbindFromService(this);
-      mService = null;
-      Log.d(LOGTAG, "onDestroy: unbindFromService completed");
-   }
-
-   private static class LoadedDataAndState {
-      public LoadedDataAndState(){};
-      public boolean onOrOff;
-   }
-
-   @Override
-   public Object onRetainNonConfigurationInstance() {
-      LoadedDataAndState data = new LoadedDataAndState();
-      if(mService != null) {
-         try {
-              data.onOrOff = mService.isFmOn();
-         }catch(RemoteException e) {
-              data.onOrOff = false;
-              e.printStackTrace();
-         }
-       }else {
-         data.onOrOff = false;
-       }
-       return data;
-   }
-
-   @Override
-   public boolean onCreateOptionsMenu(Menu menu) {
-      super.onCreateOptionsMenu(menu);
-      MenuItem item;
-      boolean radioOn = isFmOn();
-      boolean searchActive = isSearchActive();
-
-      item = menu.add(0, MENU_SCAN_START, 0, R.string.menu_scan_for_preset)
-                            .setIcon(R.drawable.ic_btn_search);
-      if(item != null) {
-         item.setVisible(!searchActive && radioOn);
-      }
-      item = menu.add(0, MENU_SCAN_STOP, 0, R.string.menu_scan_stop).setIcon(
-                                R.drawable.ic_btn_search);
-      if(item != null) {
-        item.setVisible(searchActive && radioOn);
-      }
-
-      /* Settings can be active */
-      item = menu.add(0, MENU_SETTINGS, 0, R.string.menu_settings).setIcon(
-                           android.R.drawable.ic_menu_preferences);
-
-      return true;
-   }
-
-   @Override
-   public boolean onPrepareOptionsMenu(Menu menu) {
-      super.onPrepareOptionsMenu(menu);
-
-      MenuItem item;
-      boolean radioOn = isFmOn();
-      boolean searchActive = isSearchActive();
-
-      item = menu.findItem(MENU_SCAN_START);
-      if(item != null) {
-         item.setVisible(!searchActive && radioOn);
-      }
-      item = menu.findItem(MENU_SCAN_STOP);
-      if(item != null) {
-         item.setVisible(searchActive && radioOn);
-      }
-      return true;
-   }
-
-   @Override
-   public boolean onOptionsItemSelected(MenuItem item) {
-      switch(item.getItemId()) {
-      case MENU_SETTINGS:
-           Intent launchPreferencesIntent = new Intent().setClass(this,
-                                                  Settings.class);
-           launchPreferencesIntent.putExtra(Settings.RX_MODE,false);
-           startActivityForResult(launchPreferencesIntent,
-                                   ACTIVITY_RESULT_SETTINGS);
-
-           return true;
-
-      case MENU_SCAN_START:
-           showDialog(DIALOG_PRESET_LIST_AUTO_SET);
-           return true;
-
-      case MENU_SCAN_STOP:
-           cancelSearch();
-           return true;
-
-      default:
-           break;
-      }
-      return super.onOptionsItemSelected(item);
-   }
-
-   @Override
-   protected Dialog onCreateDialog(int id) {
-      switch (id) {
-      case DIALOG_PRESET_LIST_AUTO_SET: {
-           return createPresetListAutoSelectWarnDlg(id);
-      }
-      case DIALOG_PICK_FREQUENCY: {
-           FmConfig fmConfig = FmSharedPreferences.getFMConfiguration();
-           return new FrequencyPickerDialog(this, fmConfig, mTunedFrequency,
-                                        mFrequencyChangeListener);
-      }
-      case DIALOG_PROGRESS_PROGRESS: {
-           return createProgressDialog(id);
-      }
-      case DIALOG_PRESET_OPTIONS: {
-           return createPresetOptionsDlg(id);
-      }
-      default:
-           break;
-      }
-      return null;
-   }
-
-   @Override
-   protected void onPrepareDialog(int id, Dialog dialog) {
-      super.onPrepareDialog(id, dialog);
-      switch(id) {
-      case DIALOG_PICK_FREQUENCY: {
-           FmConfig fmConfig = FmSharedPreferences.getFMConfiguration();
-           ((FrequencyPickerDialog) dialog).updateSteps(fmConfig.getChSpacing());
-           ((FrequencyPickerDialog) dialog).updateMinFreq(fmConfig.getLowerLimit());
-           ((FrequencyPickerDialog) dialog).updateMaxFreq(fmConfig.getUpperLimit());
-           ((FrequencyPickerDialog) dialog).UpdateFrequency(mTunedFrequency);
-            break;
-      }
-      case DIALOG_PRESET_OPTIONS: {
-           AlertDialog alertDlg = ((AlertDialog) dialog);
-           if((alertDlg != null) && (mPresetButtonIndex >= 0)
-               && (mPresetButtonIndex <= MAX_PRESETS)) {
-               int frequency = mPresetFrequencies[mPresetButtonIndex];
-               alertDlg.setTitle(PresetStation.getFrequencyString(frequency));
-           }
-           break;
-      }
-      default:
-           break;
-      }
-   }
-
-   @Override
-   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-      super.onActivityResult(requestCode, resultCode, data);
-      Log.d(LOGTAG, "onActivityResult : requestCode -> " + requestCode);
-      Log.d(LOGTAG, "onActivityResult : resultCode -> " + resultCode);
-      if(requestCode == ACTIVITY_RESULT_SETTINGS) {
-         if(resultCode == RESULT_OK) {
-            if(data != null) {
-               String action = data.getAction();
-               if(action != null) {
-                  if(action.equals(Settings.RESTORE_FACTORY_DEFAULT_ACTION)) {
-                     RestoreDefaults();
-                     enableRadioOnOffUI();
-                     tuneRadio(mTunedFrequency);
-                  }
-               }
-            }
-         } //if ACTIVITY_RESULT_SETTINGS
-      }//if (resultCode == RESULT_OK)
-   }
-
-   /**
-     * @return true if a internal antenna is available.
-     *
-     */
-   boolean isInternalAntennaAvailable() {
-      return mInternalAntennaAvailable;
-   }
-
-   private Dialog createPresetOptionsDlg(int id) {
-      if((mPresetButtonIndex >= 0) && (mPresetButtonIndex <= MAX_PRESETS)) {
-         int frequency = mPresetFrequencies[mPresetButtonIndex];
-         AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(this);
-         dlgBuilder.setTitle(PresetStation.getFrequencyString(frequency));
-         ArrayList<String> arrayList = new ArrayList<String>();
-         arrayList.add(getResources().getString(R.string.preset_tune));
-         arrayList.add(getResources().getString(R.string.preset_replace));
-         arrayList.add(getResources().getString(R.string.preset_delete));
-         dlgBuilder.setCancelable(true);
-         dlgBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {
-             public void onCancel(DialogInterface dialog) {
-                mPresetButtonIndex = -1;
-                removeDialog(DIALOG_PRESET_OPTIONS);
-             }
-         });
-         String[] items = new String[arrayList.size()];
-         arrayList.toArray(items);
-         dlgBuilder.setItems(items, new DialogInterface.OnClickListener() {
-            public void onClick(DialogInterface dialog, int item) {
-               if((mPresetButtonIndex >= 0) &&
-                  (mPresetButtonIndex <= MAX_PRESETS)) {
-                  int frequency = mPresetFrequencies[mPresetButtonIndex];
-                  switch(item) {
-                  case 0: {
-                          // Tune to this station
-                          mPresetButtonIndex = -1;
-                          tuneRadio(frequency);
-                          break;
-                  }
-                  case 1: {
-                          // Replace preset Station with currently tuned
-                          // station
-                          Log.d(LOGTAG, "Replace station - " + frequency
-                                 + " with " + mTunedFrequency);
-                          if(!stationExists(mTunedFrequency)) {
-                             mPresetFrequencies[mPresetButtonIndex] = mTunedFrequency;
-                             mPresetButtonIndex = -1;
-                             setupPresetLayout();
-                             SavePreferences();
-                          }
-                          break;
-                  }
-                  case 2: {
-                          // Delete
-                          mPresetFrequencies[mPresetButtonIndex] = 0;
-                          mPresetButtonIndex = -1;
-                          setupPresetLayout();
-                          SavePreferences();
-                          break;
-                  }
-                  default: {
-                           // Should not happen
-                           mPresetButtonIndex = -1;
-                           break;
-                  }
-                 }// switch item
-               } // if(mPresetButtonStation != null)
-               removeDialog(DIALOG_PRESET_OPTIONS);
-            }// onClick
-        });
-        return dlgBuilder.create();
-      }
-      return null;
-   }
-
-   private Dialog createProgressDialog(int id) {
-      String msgStr = "";
-      String titleStr = "";
-      boolean bSearchActive = false;
-
-      if(isSearchActive()) {
-         msgStr = getString(R.string.msg_weak_searching);
-         titleStr = getString(R.string.msg_searching_title);
-         bSearchActive = true;
-      }
-
-      if(bSearchActive) {
-         mProgressDialog = new ProgressDialog(FMTransmitterActivity.this);
-         if(mProgressDialog != null) {
-            mProgressDialog.setTitle(titleStr);
-            mProgressDialog.setMessage(msgStr);
-            mProgressDialog.setIcon(R.drawable.ic_launcher_fm_tx);
-            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
-            mProgressDialog.setCanceledOnTouchOutside(false);
-            mProgressDialog.setButton(DialogInterface.BUTTON_POSITIVE,
-                   getText(R.string.button_text_stop),
-                            new DialogInterface.OnClickListener() {
-                                public void onClick(DialogInterface dialog,
-                                                      int whichButton) {
-                                   cancelSearch();
-                                }
-                             });
-            mProgressDialog.setOnCancelListener(
-                   new DialogInterface.OnCancelListener() {
-                       public void onCancel(DialogInterface dialog) {
-                          cancelSearch();
-                       }
-                    });
-          }
-
-          Message msg = new Message();
-          msg.what = TIMEOUT_PROGRESS_DLG;
-          mSearchProgressHandler.sendMessageDelayed(msg, SHOWBUSY_TIMEOUT);
-      }
-      return mProgressDialog;
-   }
-
-   private Dialog createPresetListAutoSelectWarnDlg(int id) {
-      AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(this);
-      dlgBuilder.setIcon(R.drawable.alert_dialog_icon).setTitle(
-                                R.string.presetlist_autoselect_title);
-      dlgBuilder.setMessage(getString(R.string.fmtx_autoselect_name));
-
-      dlgBuilder.setPositiveButton(R.string.alert_dialog_ok,
-                new DialogInterface.OnClickListener() {
-                   public void onClick(DialogInterface dialog, int whichButton) {
-                      /*
-                       * Since the presets will be changed, reset the page
-                       * number
-                       */
-                       initiateSearchList();
-                       setupPresetLayout();
-                       SavePreferences();
-                       removeDialog(DIALOG_PRESET_LIST_AUTO_SET);
-                   }
-                });
-
-                dlgBuilder.setNegativeButton(R.string.alert_dialog_cancel,
-                   new DialogInterface.OnClickListener() {
-                      public void onClick(DialogInterface dialog, int whichButton) {
-                         removeDialog(DIALOG_PRESET_LIST_AUTO_SET);
-                      }
-                   });
-      return (dlgBuilder.create());
-   }
-
-   private void RestoreDefaults() {
-      for(int index = 0; index < MAX_PRESETS; index++) {
-          mPresetFrequencies[index] = 0;
-      }
-      mTunedFrequency = FmSharedPreferences.getLowerLimit();
-      SavePreferences();
-   }
-
-   private View.OnLongClickListener mFrequencyViewClickListener = new View.OnLongClickListener() {
-      public boolean onLongClick(View v) {
-         showDialog(DIALOG_PICK_FREQUENCY);
-         return true;
-      }
-   };
-
-   private View.OnClickListener mForwardClickListener = new View.OnClickListener() {
-      public void onClick(View v) {
-         int frequency = FmSharedPreferences
-                                        .getNextTuneFrequency(mTunedFrequency);
-         Log.d(LOGTAG, "Tune Up: to " + frequency);
-         tuneRadio(frequency);
-      }
-   };
-
-   private View.OnClickListener mBackClickListener = new View.OnClickListener() {
-      public void onClick(View v) {
-         int frequency = FmSharedPreferences
-                                        .getPrevTuneFrequency(mTunedFrequency);
-         Log.d(LOGTAG, "Tune Down: to " + frequency);
-         tuneRadio(frequency);
-      }
-   };
-
-
-   private View.OnClickListener mPresetButtonClickListener = new View.OnClickListener() {
-      public void onClick(View view) {
-         Integer indexInteger = (Integer) view.getTag();
-         int index = indexInteger.intValue();
-         if((index >= 0) && (index <= MAX_PRESETS)) {
-            Log.d(LOGTAG, "station - " + index);
-            if(mPresetFrequencies[index] != 0) {
-               mTunedFrequency = mPresetFrequencies[index];
-               tuneRadio(mTunedFrequency);
-               view.startAnimation(mAnimation);
-            }
-         }
-      }
-   };
-
-   private boolean stationExists(int frequency) {
-      boolean exists = false;
-      for(int i = 0; i < MAX_PRESETS; i++) {
-          if(mPresetFrequencies[i] == frequency) {
-             exists = true;
-             break;
-          }
-      }
-      if(exists){
-         Toast t = Toast.makeText(this, getString(R.string.station_exists), Toast.LENGTH_SHORT);
-         t.show();
-      }
-      return exists;
-   }
-   private View.OnLongClickListener mPresetButtonOnLongClickListener = new View.OnLongClickListener() {
-      public boolean onLongClick(View view) {
-         Integer indexInteger = (Integer) view.getTag();
-         int index = indexInteger.intValue();
-         if((index >= 0) && (index <= MAX_PRESETS)) {
-            int frequency = mPresetFrequencies[index];
-            mPresetButtonIndex = index;
-            if(frequency > 0) {
-               showDialog(DIALOG_PRESET_OPTIONS);
-            }else if(!stationExists(mTunedFrequency)) {
-               mPresetFrequencies[index] = mTunedFrequency;
-               view.startAnimation(mAnimation);
-               setupPresetLayout();
-               SavePreferences();
-            }
-          }
-          return true;
-      }
-   };
-
-   private FrequencyPickerDialog.OnFrequencySetListener
-      mFrequencyChangeListener =
-         new FrequencyPickerDialog.OnFrequencySetListener() {
-            public void onFrequencySet
-            (
-              FrequencyPicker view, int frequency
-             ) {
-               Log.d(LOGTAG, "mFrequencyChangeListener:"
-                      + "onFrequencyChanged to : "
-                      + frequency);
-               tuneRadio(frequency);
-            }
-   };
-
-   private View.OnClickListener mTurnOnOffClickListener =
-      new View.OnClickListener() {
-         public void onClick(View v) {
-
-            if(isFmOn()) {
-               enableRadioHandler.removeCallbacks(enableRadioTask);
-               disableRadioHandler.removeCallbacks(disableRadioTask);
-               disableRadioHandler.postDelayed(disableRadioTask, 0);
-            }else {
-               enableRadioHandler.removeCallbacks(enableRadioTask);
-               disableRadioHandler.removeCallbacks(disableRadioTask);
-               enableRadioHandler.postDelayed(enableRadioTask, 0);
-            }
-            setTurnOnOffButtonImage();
-         }
-   };
-
-   private void setTurnOnOffButtonImage() {
-      if(isFmOn() == true) {
-         mOnOffButton.setImageResource(R.drawable.ic_btn_onoff);
-      }else {
-         /* Find a icon to indicate off */
-         mOnOffButton.setImageResource(R.drawable.ic_btn_onoff);
-      }
-   }
-
-   private void enableRadioOnOffButton() {
-      if(mOnOffButton != null) {
-         mOnOffButton.setEnabled(true);
-         mOnOffButton.setClickable(true);
-      }
-   }
-
-   private void disableRadioOnOffButton() {
-      if(mOnOffButton != null) {
-         mOnOffButton.setEnabled(false);
-         mOnOffButton.setClickable(false);
-      }
-   }
-
-   private void setHsPluggedInMsg() {
-      if(mRadioTextTV != null) {
-         mRadioTextTV.setVisibility(View.VISIBLE);
-         mRadioTextTV.setText(getString(R.string.msg_headsetpluggedin));
-      }
-   }
-
-   private Runnable enableRadioTask = new Runnable() {
-      public void run() {
-         enableRadio();
-      }
-   };
-
-   private Runnable disableRadioTask = new Runnable() {
-      public void run() {
-         disableRadio();
-      }
-   };
-
-   private void enableRadio() {
-      mIsSearching = false;
-      disableRadioOnOffButton();
-      if(mService != null) {
-         try {
-              if(mService.isHeadsetPlugged()) {
-                 setHsPluggedInMsg();
-                 enableRadioOnOffButton();
-              }else if(mService.isCallActive()) {
-                 enableRadioOnOffButton();
-              }else if(!mService.fmOn()) {
-                 enableRadioOnOffButton();
-              }
-         }catch(RemoteException e) {
-              enableRadioOnOffButton();
-              e.printStackTrace();
-         }
-      }
-   }
-
-   private void disableRadio() {
-      enableRadioOnOffUI(false);
-      cancelSearch();
-      if(mService != null) {
-         try {
-              if(!mService.fmOff()) {
-                 enableRadioOnOffButton();
-              }
-         }catch(RemoteException e) {
-              enableRadioOnOffButton();
-              e.printStackTrace();
-         }
-      }
-   }
-
-   public void fmConfigure() {
-      if(mService != null) {
-         try {
-              mService.fmReconfigure();
-         }catch(RemoteException e) {
-              e.printStackTrace();
-         }
-      }
-   }
-
-   private void enableRadioOnOffUI() {
-      boolean bEnable = true;
-      //decide enable or disable UI based on
-      //Tx Service status.This is valid only
-      // when search is not in progress. When
-      // search is in progress UI should be active
-      if(false == isSearchActive()) {
-         bEnable = isFmOn();
-      }
-      /* Disable if no antenna/headset is available */
-      if(!readInternalAntennaAvailable()) {
-         Log.d(LOGTAG,"finding internal antenna avialable as false");
-         bEnable = false;
-      }
-      enableRadioOnOffUI(bEnable);
-   }
-
-   private void enableRadioOnOffUI(boolean bEnable) {
-      if(bEnable) {
-         if(mTuneStationFrequencyTV != null) {
-            mTuneStationFrequencyTV.setOnLongClickListener(
-                                            mFrequencyViewClickListener);
-         }
-         if(mRadioTextScroller != null) {
-            mRadioTextScroller.startScroll();
-         }
-         for (int nButton = 0; nButton < MAX_PRESETS; nButton++) {
-             if (mPresetButtons[nButton] != null) {
-                 mPresetButtons[nButton].setTextColor(Color.WHITE);
-             }
-         }
-      }else {
-         if(mTuneStationFrequencyTV != null) {
-            mTuneStationFrequencyTV.setOnLongClickListener(null);
-         }
-         if(mRadioTextScroller != null) {
-            mRadioTextScroller.stopScroll();
-         }
-         for (int nButton = 0; nButton < MAX_PRESETS; nButton++) {
-             if (mPresetButtons[nButton] != null) {
-                 mPresetButtons[nButton].setTextColor(Color.BLACK);
-             }
-         }
-      }
-
-      if(mForwardButton != null) {
-         mForwardButton.setVisibility(((bEnable == true) ? View.VISIBLE
-                                : View.INVISIBLE));
-      }
-      if(mBackButton != null) {
-         mBackButton.setVisibility(((bEnable == true) ? View.VISIBLE
-                                : View.INVISIBLE));
-      }
-      if(mTransmitStaticMsgTV != null) {
-         mTransmitStaticMsgTV.setVisibility(((bEnable == true) ? View.VISIBLE
-                                : View.INVISIBLE));
-      }
-      if(mTuneStationFrequencyTV != null) {
-         mTuneStationFrequencyTV.setVisibility(((bEnable == true) ? View.VISIBLE
-                                : View.INVISIBLE));
-      }
-      if(mRadioTextTV != null) {
-         mRadioTextTV.setVisibility(((bEnable == true) ? View.VISIBLE
-                                : View.INVISIBLE));
-      }
-      if(mPicker != null) {
-         mPicker.setVisibility(
-         bEnable ? View.VISIBLE : View.INVISIBLE );
-      }
-      try {
-           if(null != mService) {
-              if(mService.isHeadsetPlugged()) {
-                 Log.d(LOGTAG,"headset plugged in");
-                 if(mRadioTextTV != null) {
-                    mRadioTextTV.setVisibility(View.VISIBLE);
-                     mRadioTextTV.setText(getString(R.string.msg_headsetpluggedin));
-                 }
-                 if(mOnOffButton != null) {
-                    mOnOffButton.setEnabled(false);
-                 }
-              }else if(mService.isCallActive()) {
-                 Log.d(LOGTAG,"call active");
-                 if(mRadioTextTV != null) {
-                    mRadioTextTV.setVisibility(View.VISIBLE);
-                    mRadioTextTV.setText(getString(R.string.msg_callactive));
-                 }
-                 if(mOnOffButton != null) {
-                    mOnOffButton.setEnabled(false);
-                 }
-              }else {
-                 if(mRadioTextTV != null) {
-                    mRadioTextTV.setText("");
-                 }
-                 if(mOnOffButton != null) {
-                    mOnOffButton.setEnabled(true);
-                 }
-              }
-           }else {
-              Log.d(LOGTAG,"Service null");
-              if(mRadioTextTV != null) {
-                 mRadioTextTV.setText("");
-              }
-              if(mOnOffButton != null) {
-                 mOnOffButton.setEnabled(true);
-              }
-           }
-      }catch(RemoteException e) {
-           e.printStackTrace();
-      }
-
-      for(int nButton = 0; nButton < MAX_PRESETS; nButton++) {
-          if(mPresetButtons[nButton] != null) {
-             mPresetButtons[nButton].setEnabled(bEnable);
-          }
-      }
-   }
-
-   private void updateSearchProgress() {
-      boolean searchActive = isSearchActive();
-      if(searchActive) {
-         synchronized (this) {
-            if(mProgressDialog == null) {
-               showDialog(DIALOG_PROGRESS_PROGRESS);
-            }else {
-               Message msg = new Message();
-               msg.what = UPDATE_PROGRESS_DLG;
-               mSearchProgressHandler.sendMessage(msg);
-            }
-         }
-      }else {
-         Message msg = new Message();
-         msg.what = END_PROGRESS_DLG;
-         mSearchProgressHandler.sendMessage(msg);
-      }
-   }
-
-   private void resetSearchProgress() {
-      Message msg = new Message();
-      msg.what = END_PROGRESS_DLG;
-      mSearchProgressHandler.sendMessage(msg);
-   }
-
-   private void setupPresetLayout() {
-      for(int buttonIndex = 0; (buttonIndex < MAX_PRESETS); buttonIndex++) {
-          if(mPresetButtons[buttonIndex] != null) {
-             String display = "";
-             int frequency = mPresetFrequencies[buttonIndex];
-             if(frequency != 0) {
-                display = PresetStation.getFrequencyString(frequency);
-             }else {
-                display = this.getString(R.string.add_station);
-             }
-             mPresetButtons[buttonIndex].setText(display);
-             mPresetButtons[buttonIndex].setTag(new Integer(buttonIndex));
-          }
-      }
-   }
-
-   private void updateStationInfoToUI() {
-      mTuneStationFrequencyTV.setText(PresetStation.getFrequencyString(mTunedFrequency));
-      if((mPicker != null) && mUpdatePickerValue) {
-          mPicker.setValue(((mTunedFrequency - mPrefs.getLowerLimit())
-                              / mPrefs.getFrequencyStepSize()));
-      }
-      mRadioTextTV.setText("");
-      setupPresetLayout();
-   }
-
-   private boolean isFmOn() {
-      boolean bOn = false;
-      if(mService != null) {
-         try {
-              bOn = mService.isFmOn();
-         }catch (RemoteException e) {
-              e.printStackTrace();
-         }
-      }
-      return (bOn);
-   }
-
-   private boolean isSearchActive() {
-      return (mIsSearching);
-   }
-
-   public int getCurrentTunedFrequency() {
-      return mTunedFrequency;
-   }
-
-   private void cancelSearch() {
-      synchronized (this) {
-         if(mService != null) {
-            try {
-                 if(mIsSearching == true) {
-                    if(true == mService.cancelSearch()) {
-                    }
-                 }
-            }catch (RemoteException e) {
-                 e.printStackTrace();
-            }
-         }
-      }
-      updateSearchProgress();
-   }
-
-   /** get Weakest Stations */
-   private void initiateSearchList() {
-      synchronized (this) {
-         mIsSearching = true;
-         if(mService != null) {
-            try {
-                 mSearchingResultStatus = false;
-                 mIsSearching = mService.searchWeakStationList(MAX_PRESETS);
-            }catch (RemoteException e) {
-                 e.printStackTrace();
-            }
-            updateSearchProgress();
-         }
-      }
-   }
-
-   /** get Internal Antenna Available mode Stations */
-   private boolean readInternalAntennaAvailable() {
-      mInternalAntennaAvailable = false;
-      if(mService != null) {
-         try {
-              mInternalAntennaAvailable = mService
-                                               .isInternalAntennaAvailable();
-         }catch (RemoteException e) {
-              e.printStackTrace();
-         }
-      }
-      Log.e(LOGTAG, "readInternalAntennaAvailable: internalAntenna : "
-                                + mInternalAntennaAvailable);
-      return mInternalAntennaAvailable;
-   }
-
-   private static final int UPDATE_PROGRESS_DLG = 1;
-   private static final int END_PROGRESS_DLG = 2;
-   private static final int TIMEOUT_PROGRESS_DLG = 3;
-   private static final int SHOWBUSY_TIMEOUT = 300000;
-   private Handler mSearchProgressHandler = new Handler() {
-      public void handleMessage(Message msg) {
-         if(msg.what == UPDATE_PROGRESS_DLG) {
-            if(mProgressDialog != null) {
-               mTuneStationFrequencyTV.setText(PresetStation.getFrequencyString(mTunedFrequency));
-               String titleStr = getString( R.string.msg_search_title,
-                                            PresetStation.getFrequencyString(mTunedFrequency));
-
-               mProgressDialog.setTitle(titleStr);
-            }
-         }else if (msg.what == END_PROGRESS_DLG) {
-            mSearchProgressHandler.removeMessages(END_PROGRESS_DLG);
-            mSearchProgressHandler.removeMessages(UPDATE_PROGRESS_DLG);
-            mSearchProgressHandler.removeMessages(TIMEOUT_PROGRESS_DLG);
-            removeDialog(DIALOG_PROGRESS_PROGRESS);
-            mProgressDialog = null;
-         }else if (msg.what == TIMEOUT_PROGRESS_DLG) {
-            cancelSearch();
-         }
-      }
-  };
-
-  private void tuneRadio(int frequency) {
-     if(mService != null) {
-        try {
-             mService.tune(frequency);
-             updateStationInfoToUI();
-        }catch (RemoteException e) {
-             e.printStackTrace();
-        }
-     }
-  }
-
-  private void resetFMStationInfoUI() {
-     mRadioTextTV.setText("");
-     mRadioTextScroller.stopScroll();
-     mUpdatePickerValue = true;
-     updateStationInfoToUI();
-  }
-
-
-  private Runnable mUpdateStationInfo = new Runnable() {
-     public void run() {
-        updateSearchProgress();
-        resetFMStationInfoUI();
-     }
-  };
-
-  private Runnable mSearchListComplete = new Runnable() {
-     public void run() {
-        Log.d(LOGTAG, "mSearchListComplete: ");
-        mIsSearching = false;
-
-        if(mService != null) {
-           try {
-                if(mSearchingResultStatus) {
-                   int[] searchList = mService.getSearchList();
-                   if(searchList != null) {
-                      for(int station = 0; (station < searchList.length)
-                            && (station < MAX_PRESETS); station++) {
-                           Log.d(LOGTAG, "mSearchListComplete: [" + station
-                                  + "] = " + searchList[station]);
-                           mPresetFrequencies[station] = searchList[station];
-                      }
-                   }
-           }
-           if(!mService.isHeadsetPlugged()) {
-              mService.fmRestart();
-              /* Tune to last tuned frequency */
-              tuneRadio(mTunedFrequency);
-              updateSearchProgress();
-              resetFMStationInfoUI();
-              setupPresetLayout();
-              SavePreferences();
-           }else {
-              updateSearchProgress();
-              enableRadioHandler.removeCallbacks(enableRadioTask);
-              disableRadioHandler.removeCallbacks(disableRadioTask);
-              disableRadioHandler.postDelayed(disableRadioTask, 0);
-           }
-        }catch (RemoteException e) {
-           e.printStackTrace();
-        }
-     }
-   }
-  };
-
-
-
-  private Runnable mUpdateRadioText = new Runnable() {
-     public void run() {
-        String str = "";
-        if((mService != null) && isFmOn()) {
-            try {
-                 /* Get Radio Text and update the display */
-                 str = mService.getRadioText();
-                 if(null != mMetaData) {
-                    Log.d(LOGTAG,"meta data is "+mMetaData);
-                    str = str.concat(mMetaData);
-                 }else {
-                    str = str.concat("...");
-                 }
-                 /* Update only if all the characters are printable */
-                 if(TextUtils.isGraphic(str)) {
-                    Log.d(LOGTAG, "mUpdateRadioText: Updatable string: ["
-                              + str + "]");
-                    mRadioTextTV.setText(str);
-                 }else if (TextUtils.isEmpty(str)) {
-                    mRadioTextTV.setText("");
-                 }else {
-                    Log.d(LOGTAG, "RDS has non printable stuff");
-                    mRadioTextTV.setText("");
-                 }
-
-                 mRadioTextScroller.startScroll();
-                 String szRTStr = getString(R.string.transmit_msg_string);
-                 mPSData = mService.getPSData();
-                 if(null != mPSData ) {
-                    szRTStr = mPSData.concat("\n").concat(szRTStr);
-                 }else {
-                    Log.d(LOGTAG, "mPSData is NULL");
-                 }
-                 mTransmitStaticMsgTV.setText(szRTStr);
-            }catch (RemoteException e) {
-                 e.printStackTrace();
-            }
-        }
-     }
-  };
-
-  private Runnable mRadioChangeFrequency = new Runnable(){
-     public void run() {
-        mUpdatePickerValue = false;
-        tuneRadio(mFrequency);
-     }
-  };
-
-  protected int valueToFrequency(int value) {
-     mFrequency = mPrefs.getLowerLimit() + value *
-                             mPrefs.getFrequencyStepSize();
-     return mFrequency;
-  }
-
-  private void DebugToasts(String str, int duration) {
-     Toast.makeText(this, str, duration).show();
-  }
-
-  /**
-    * This Handler will scroll the text view. On startScroll, the scrolling
-    * starts after SCROLLER_START_DELAY_MS The Text View is scrolled left one
-    * character after every SCROLLER_UPDATE_DELAY_MS When the entire text is
-    * scrolled, the scrolling will restart after SCROLLER_RESTART_DELAY_MS
-    */
-  private final class ScrollerText extends Handler {
-
-     private static final byte SCROLLER_STOPPED = 0x51;
-     private static final byte SCROLLER_STARTING = 0x52;
-     private static final byte SCROLLER_RUNNING = 0x53;
-
-     private static final int SCROLLER_MSG_START = 0xF1;
-     private static final int SCROLLER_MSG_TICK = 0xF2;
-     private static final int SCROLLER_MSG_RESTART = 0xF3;
-
-     private static final int SCROLLER_START_DELAY_MS = 1000;
-     private static final int SCROLLER_RESTART_DELAY_MS = 3000;
-     private static final int SCROLLER_UPDATE_DELAY_MS = 200;
-
-     private final WeakReference<TextView> mView;
-
-     private byte mStatus = SCROLLER_STOPPED;
-     String mOriginalString;
-     int mStringlength = 0;
-     int mIteration = 0;
-
-     ScrollerText(TextView v) {
-        mView = new WeakReference<TextView>(v);
-     }
-
-     /**
-      * Scrolling Message Handler
-      */
-     @Override
-     public void handleMessage(Message msg) {
-        switch (msg.what) {
-        case SCROLLER_MSG_START:
-             mStatus = SCROLLER_RUNNING;
-             updateText();
-             break;
-        case SCROLLER_MSG_TICK:
-             updateText();
-             break;
-        case SCROLLER_MSG_RESTART:
-             if(mStatus == SCROLLER_RUNNING) {
-                startScroll();
-             }
-             break;
-        }
-     }
-
-     /**
-      * Moves the text left by one character and posts a delayed message for
-      * next update after SCROLLER_UPDATE_DELAY_MS. If the entire string is
-      * scrolled, then it displays the entire string and waits for
-      * SCROLLER_RESTART_DELAY_MS for scrolling restart
-      */
-     void updateText() {
-        if(mStatus != SCROLLER_RUNNING) {
-           return;
-        }
-
-        removeMessages(SCROLLER_MSG_TICK);
-
-        final TextView textView = mView.get();
-        if(textView != null) {
-           String szStr2 = "";
-           if(mStringlength > 0) {
-              mIteration++;
-              if(mIteration >= mStringlength) {
-                 mIteration = 0;
-                 sendEmptyMessageDelayed(SCROLLER_MSG_RESTART,
-                                            SCROLLER_RESTART_DELAY_MS);
-              }else {
-                 sendEmptyMessageDelayed(SCROLLER_MSG_TICK,
-                                            SCROLLER_UPDATE_DELAY_MS);
-              }
-              szStr2 = mOriginalString.substring(mIteration);
-           }
-           textView.setText(szStr2);
-        }
-     }
-
-     /**
-      * Stops the scrolling The textView will be set to the original string.
-      */
-     void stopScroll() {
-        mStatus = SCROLLER_STOPPED;
-        removeMessages(SCROLLER_MSG_TICK);
-        removeMessages(SCROLLER_MSG_RESTART);
-        removeMessages(SCROLLER_MSG_START);
-        resetScroll();
-     }
-
-     /**
-      * Resets the scroll to display the original string.
-      */
-
-     private void resetScroll() {
-        mIteration = 0;
-        final TextView textView = mView.get();
-        if(textView != null) {
-           textView.setText(mOriginalString);
-        }
-     }
-
-     /**
-       * Starts the Scrolling of the TextView after a delay of
-       * SCROLLER_START_DELAY_MS Starts only if Length > 0
-       */
-     void startScroll() {
-        final TextView textView = mView.get();
-           if(textView != null) {
-              mOriginalString = (String) textView.getText().toString();
-              mStringlength = mOriginalString.length();
-              if(mStringlength > 0) {
-                 mStatus = SCROLLER_STARTING;
-                 sendEmptyMessageDelayed(SCROLLER_MSG_START,
-                                           SCROLLER_START_DELAY_MS);
-              }
-           }
-     }
-  }
-
-  public IFMTransmitterService sService = null;
-  private HashMap<Context, ServiceBinder> sConnectionMap = new HashMap<Context, ServiceBinder>();
-
-  public boolean bindToService(Context context) {
-     Log.e(LOGTAG, "bindToService: Context");
-     return bindToService(context, null);
-  }
-
-  public boolean bindToService(Context context,
-                        ServiceConnection callback) {
-     Log.e(LOGTAG, "bindToService: Context with serviceconnection callback");
-     context.startService(new Intent(context, FMTransmitterService.class));
-     ServiceBinder sb = new ServiceBinder(callback);
-     sConnectionMap.put(context, sb);
-     return context.bindService((new Intent()).setClass(context,
-                                FMTransmitterService.class), sb, 0);
-  }
-
-  public void unbindFromService(Context context) {
-     ServiceBinder sb = (ServiceBinder) sConnectionMap.remove(context);
-     Log.e(LOGTAG, "unbindFromService: Context");
-     if(sb == null) {
-        Log.e(LOGTAG, "Trying to unbind for unknown Context");
-        return;
-     }
-     context.unbindService(sb);
-     if(sConnectionMap.isEmpty()) {
-        // presumably there is nobody interested in the service at this
-        // point,
-        // so don't hang on to the ServiceConnection
-        sService = null;
-     }
-  }
-
-  private class ServiceBinder implements ServiceConnection {
-     ServiceConnection mCallback;
-
-     ServiceBinder(ServiceConnection callback) {
-        mCallback = callback;
-     }
-
-     public void onServiceConnected(ComponentName className,
-                                android.os.IBinder service) {
-        sService = IFMTransmitterService.Stub.asInterface(service);
-        if(mCallback != null) {
-           Log.e(LOGTAG, "onServiceConnected: mCallback");
-           mCallback.onServiceConnected(className, service);
-        }
-     }
-
-     public void onServiceDisconnected(ComponentName className) {
-        if(mCallback != null) {
-           mCallback.onServiceDisconnected(className);
-        }
-        sService = null;
-     }
-  }
-
-  private ServiceConnection osc = new ServiceConnection() {
-     public void onServiceConnected(ComponentName classname, IBinder obj) {
-        mService = IFMTransmitterService.Stub.asInterface(obj);
-        Log.e(LOGTAG, "ServiceConnection: onServiceConnected: ");
-        if(mService != null) {
-           try {
-                mService.registerCallbacks(mServiceCallbacks);
-                if(false == mService.isHeadsetPlugged()) {
-                   Log.e(LOGTAG, "return for isHeadsetPlugged is false");
-                   if(SavedDataAndState == null) {
-                      enableRadioHandler.removeCallbacks(enableRadioTask);
-                      disableRadioHandler.removeCallbacks(disableRadioTask);
-                      enableRadioHandler.postDelayed(enableRadioTask, 0);
-                   }else if (SavedDataAndState.onOrOff) {
-                      enableRadioOnOffUI(true);
-                   }else {
-                      enableRadioOnOffUI(false);
-                   }
-                }else {
-                   enableRadioOnOffUI(false);
-                }
-           }catch (RemoteException e) {
-                e.printStackTrace();
-           }
-           return;
-        }else {
-           Log.e(LOGTAG, "IFMTransmitterService onServiceConnected failed");
-        }
-        // Service is dead or not playing anything. If we got here as part
-        // of a "play this file" Intent, exit. Otherwise go to the Music
-        // app start screen.
-        if(getIntent().getData() == null) {
-            Intent intent = new Intent(Intent.ACTION_MAIN);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            intent.setClass(FMTransmitterActivity.this,
-                                 FMTransmitterActivity.class);
-            startActivity(intent);
-        }
-        finish();
-     }
-
-     public void onServiceDisconnected(ComponentName classname) {
-     }
-  };
-
-  private IFMTransmitterServiceCallbacks.Stub mServiceCallbacks = new IFMTransmitterServiceCallbacks.Stub() {
-
-     public void onDisabled() throws RemoteException {
-        mHandler.post(mRadioStateUpdated);
-     }
-
-     public void onRadioReset() throws RemoteException {
-        mHandler.post(mRadioReset);
-     }
-
-     public void onEnabled(boolean status) throws RemoteException {
-        mHandler.post(mRadioStateUpdated);
-     }
-
-     public void onRadioTextChanged() throws RemoteException {
-     }
-
-     public void onSearchListComplete(boolean status) throws RemoteException {
-        mIsSearching = false;
-        mSearchingResultStatus = status;
-        mHandler.post(mSearchListComplete);
-     }
-
-     public void onTuneStatusChanged(int frequency) throws RemoteException {
-        mTunedFrequency = frequency;
-        Log.d(LOGTAG, "onTuneStatusChanged: Frequency : " + mTunedFrequency);
-        FmSharedPreferences.setTunedFrequency(mTunedFrequency);
-        SavePreferences();
-        mHandler.post(mUpdateStationInfo);
-     }
-
-     public void onReconfigured() throws RemoteException {
-        RestoreDefaults();
-     }
-
-     public void onMetaDataChanged(String metaStr)  throws RemoteException {
-        Log.d(LOGTAG,"meta data is "+metaStr);
-        mMetaData = new String (metaStr);
-        mHandler.post(mUpdateRadioText);
-     }
-
-     public void onPSInfoSent(String psStr ) throws RemoteException {
-                    Log.d(LOGTAG,"PS String data is "+psStr);
-                    mPSData = new String (psStr);
-                    mHandler.post(mUpdateRadioText);
-     }
-  };
-
-  private Runnable mRadioStateUpdated = new Runnable() {
-     public void run() {
-        enableRadioOnOffButton();
-        /* Update UI to FM On State */
-        if(isFmOn()) {
-           enableRadioOnOffUI(true);
-           /* Tune to the last tuned frequency */
-           mUpdatePickerValue = true;
-           LoadPreferences();
-           tuneRadio(mTunedFrequency);
-         }else {
-           /* Save the existing frequency */
-           FmSharedPreferences.setTunedFrequency(mTunedFrequency);
-           SavePreferences();
-           removeDialog(DIALOG_PRESET_LIST_AUTO_SET);
-           enableRadioOnOffUI(false);
-         }
-
-     }
-  };
-
-  private Runnable mRadioReset = new Runnable() {
-     public void run() {
-        /* Save the existing frequency */
-        resetSearchProgress();
-        FmSharedPreferences.setTunedFrequency(mTunedFrequency);
-        SavePreferences();
-        enableRadioOnOffUI(false);
-     }
-  };
-
-  private void registerFMSettingListner() {
-       if(mFmSettingReceiver == null) {
-           mFmSettingReceiver = new BroadcastReceiver() {
-               @Override
-               public void onReceive(Context context, Intent intent) {
-                    Log.d(LOGTAG, "Received intent " + intent);
-                    String action = intent.getAction();
-                    Log.d(LOGTAG, " action = " + action);
-                    if (action.equals(Settings.ACTION_FM_SETTING)) {
-                        int state = intent.getIntExtra("state", 0);
-                        Log.d(LOGTAG, "ACTION_FM_SETTING Intent received" + state);
-                        switch(state) {
-                        case Settings.FM_BAND_CHANGED:
-                             fmConfigure();
-                             break;
-                        case Settings.FM_CHAN_SPACING_CHANGED:
-                             fmConfigure();
-                             break;
-                        }
-                    }
-                }
-           };
-           IntentFilter iFilter = new IntentFilter();
-           iFilter.addAction(Settings.ACTION_FM_SETTING);
-           registerReceiver(mFmSettingReceiver, iFilter);
-       }
-  }
-
-  private void unRegisterReceiver(BroadcastReceiver myReceiver) {
-      if(myReceiver != null) {
-         unregisterReceiver(myReceiver);
-         myReceiver = null;
-      }
-  }
-
-}
diff --git a/fmapp2/src/com/caf/fmradio/FMTransmitterService.java b/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
deleted file mode 100644
index 5e11943..0000000
--- a/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
+++ /dev/null
@@ -1,1234 +0,0 @@
-/*
- * Copyright (c) 2009-2013, 2015, 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.
- */
-
-package com.caf.fmradio;
-
-import java.lang.ref.WeakReference;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.media.AudioManager;
-import android.media.AudioSystem;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemProperties;
-import android.os.PowerManager.WakeLock;
-import android.os.RemoteException;
-import android.telephony.PhoneStateListener;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-import android.widget.RemoteViews;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.BroadcastReceiver;
-import qcom.fmradio.FmReceiver;
-import qcom.fmradio.FmTransmitter;
-import qcom.fmradio.FmRxEvCallbacksAdaptor;
-import qcom.fmradio.FmTransmitterCallbacksAdaptor;
-import qcom.fmradio.FmRxRdsData;
-import qcom.fmradio.FmConfig;
-import com.caf.utils.A2dpDeviceStatus;
-import android.media.IRemoteControlDisplay;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.graphics.Bitmap;
-import android.media.IAudioService;
-import android.media.MediaMetadataRetriever;
-
-
-/**
- * Provides "background" FM Radio (that uses the hardware) capabilities,
- * allowing the user to switch between activities without stopping playback.
- */
-public class FMTransmitterService extends Service
-{
-   private static final int FMTRANSMITTERSERVICE_STATUS = 102;
-   private static final int FM_TX_PROGRAM_TYPE = 0;
-   private static final int FM_TX_PROGRAM_ID = 0x1234;
-   private static final int FM_TX_PS_REPEAT_COUNT = 1;
-
-   private static final String FMRADIO_DEVICE_FD_STRING = "/dev/radio0";
-   private static final String LOGTAG = "FMTxService";//FMRadio.LOGTAG;
-   private static final String QFM_STRING ="QFMRADIO";
-
-   private static FmReceiver mReceiver;
-   private static FmTransmitter mTransmitter;
-   private int mTunedFrequency = 0;
-
-   private static FmSharedPreferences mPrefs;
-   private IFMTransmitterServiceCallbacks mCallbacks;
-   private WakeLock mWakeLock;
-   private int mServiceStartId = -1;
-   private boolean mServiceInUse = false;
-   private boolean mMuted = false;
-   private boolean mResumeAfterCall = false;
-
-   private boolean mFMOn = false;
-   private int mFMSearchStations = 0;
-
-   private FmRxRdsData mFMRxRDSData=null;
-   final Handler mHandler = new Handler();
-   private BroadcastReceiver mHeadsetReceiver = null;
-   boolean mHeadsetPlugged = false;
-   // Track A2dp Device status changes
-   private A2dpDeviceStatus mA2dpDeviceState = null;
-   // interval after which we stop the service when idle
-   private static final int IDLE_DELAY = 60000;
-
-   private static String RText = " ";
-   private IAudioService mAudioService;
-   private AudioManager mAudioManager;
-   private Metadata mMetadata;
-   RdsDisplay mRds;
-
-   public FMTransmitterService() {
-   }
-
-   @Override
-   public void onCreate() {
-      super.onCreate();
-
-      mCallbacks = null;
-      mPrefs = new FmSharedPreferences(this);
-
-      PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
-      mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getName());
-      mWakeLock.setReferenceCounted(false);
-
-      // If the service was idle, but got killed before it stopped itself, the
-      // system will relaunch it. Make sure it gets stopped again in that case.
-
-      TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
-      tmgr.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
-
-      //register for A2DP utility interface
-      mA2dpDeviceState = new A2dpDeviceStatus(getApplicationContext());
-      Message msg = mDelayedStopHandler.obtainMessage();
-      mDelayedStopHandler.sendMessageDelayed(msg, IDLE_DELAY);
-      mAudioManager = new AudioManager(getApplicationContext());
-      mMetadata = new Metadata();
-      registerHeadsetListener();
-      mRds = new RdsDisplay();
-      mAudioManager.registerRemoteControlDisplay(mRds);
-   }
-
-   @Override
-   public void onDestroy() {
-      Log.d(LOGTAG, "onDestroy");
-      if (isFmOn())
-      {
-         Log.e(LOGTAG, "Service being destroyed while still playing.");
-      }
-
-      // make sure there aren't any other messages coming
-      mDelayedStopHandler.removeCallbacksAndMessages(null);
-      mAudioManager.unregisterRemoteControlDisplay(mRds);
-
-      /* Unregister the headset Broadcase receiver */
-      if (mHeadsetReceiver != null) {
-          unregisterReceiver(mHeadsetReceiver);
-          mHeadsetReceiver = null;
-      }
-      /* Since the service is closing, disable the receiver */
-      fmOff();
-
-      TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
-      tmgr.listen(mPhoneStateListener, 0);
-
-      mWakeLock.release();
-      super.onDestroy();
-   }
-
-   @Override
-   public IBinder onBind(Intent intent) {
-      mDelayedStopHandler.removeCallbacksAndMessages(null);
-      mServiceInUse = true;
-      /* Application/UI is attached, so get out of lower power mode */
-      setLowPowerMode(false);
-      Log.d(LOGTAG, "onBind");
-      return mBinder;
-   }
-
-   @Override
-   public void onRebind(Intent intent) {
-      mDelayedStopHandler.removeCallbacksAndMessages(null);
-      mServiceInUse = true;
-      /* Application/UI is attached, so get out of lower power mode */
-      setLowPowerMode(false);
-      Log.d(LOGTAG, "onRebind");
-   }
-
-   @Override
-   public void onStart(Intent intent, int startId) {
-      Log.d(LOGTAG, "onStart");
-      mServiceStartId = startId;
-      mDelayedStopHandler.removeCallbacksAndMessages(null);
-
-      // make sure the service will shut down on its own if it was
-      // just started but not bound to and nothing is playing
-      mDelayedStopHandler.removeCallbacksAndMessages(null);
-      Message msg = mDelayedStopHandler.obtainMessage();
-      mDelayedStopHandler.sendMessageDelayed(msg, IDLE_DELAY);
-   }
-
-   @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);
-      if (isFmOn())
-      {
-         // something is currently playing, or will be playing once
-         // an in-progress call ends, so don't stop the service now.
-         return true;
-      }
-
-      stopSelf(mServiceStartId);
-      return true;
-   }
-
-   /* Handle Phone Call + FM Concurrency */
-   private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
-      @Override
-      public void onCallStateChanged(int state, String incomingNumber) {
-          Log.d(LOGTAG, "onCallStateChanged: State - " + state );
-          Log.d(LOGTAG, "onCallStateChanged: incomingNumber - " + incomingNumber );
-          fmActionOnCallState(state );
-      }
-
-      // NEED TO CHECK ACTION TO BE TAKEN ON DATA ACTIVITY
-   };
-   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.
-           AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-           if((TelephonyManager.CALL_STATE_OFFHOOK == state)||
-              (TelephonyManager.CALL_STATE_RINGING == state)) {
-               if (state == TelephonyManager.CALL_STATE_RINGING) {
-                   int ringvolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
-                   if (ringvolume == 0) {
-                       return;
-                   }
-               }
-               if( mFMOn == true) {
-                   Log.d(LOGTAG, "posting for call state change");
-                   mHandler.post(mChangeFMTxState);
-                   mResumeAfterCall = true;
-               }
-           }
-           else if (state == TelephonyManager.CALL_STATE_IDLE) {
-              // start playing again
-              if (mResumeAfterCall)
-              {
-                  Log.d(LOGTAG, "posting for call state change");
-                  mHandler.post(mChangeFMTxState);
-                  mResumeAfterCall = false;
-              }
-           }//idle
-       }
-
-   private Handler mDelayedStopHandler = new Handler() {
-      @Override
-      public void handleMessage(Message msg) {
-         // Check again to make sure nothing is playing right now
-         if (isFmOn() || mServiceInUse)
-         {
-            return;
-         }
-         Log.d(LOGTAG, "mDelayedStopHandler: stopSelf");
-         stopSelf(mServiceStartId);
-      }
-   };
-
-   /* Show the FM Notification */
-   public void startNotification() {
-      RemoteViews views = new RemoteViews(getPackageName(), R.layout.statusbar);
-      views.setImageViewResource(R.id.icon, R.drawable.ic_status_fm_tx);
-      if (isFmOn())
-      {
-         views.setTextViewText(R.id.frequency, getTunedFrequencyString());
-      } else
-      {
-         views.setTextViewText(R.id.frequency, "");
-      }
-
-      Notification status = new Notification();
-      status.contentView = views;
-      status.flags |= Notification.FLAG_ONGOING_EVENT;
-      status.icon = R.drawable.ic_status_fm_tx;
-      status.contentIntent = PendingIntent.getActivity(this, 0,
-                                                       new Intent("com.caf.fmradio.FMTRANSMITTER_ACTIVITY"), 0);
-      startForeground(FMTRANSMITTERSERVICE_STATUS, status);
-      //NotificationManager nm = (NotificationManager)
-      //                         getSystemService(Context.NOTIFICATION_SERVICE);
-      //nm.notify(FMTRANSMITTERSERVICE_STATUS, status);
-      //setForeground(true);
-      mFMOn = true;
-   }
-
-   private void stop() {
-      gotoIdleState();
-      mFMOn = false;
-   }
-
-   private void gotoIdleState() {
-      mDelayedStopHandler.removeCallbacksAndMessages(null);
-      Message msg = mDelayedStopHandler.obtainMessage();
-      mDelayedStopHandler.sendMessageDelayed(msg, IDLE_DELAY);
-      //NotificationManager nm =
-      //(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-      //nm.cancel(FMTRANSMITTERSERVICE_STATUS);
-      //setForeground(false);
-      stopForeground(true);
-   }
-
-   /*
-    * By making this a static class with a WeakReference to the Service, we
-    * ensure that the Service can be GCd even when the system process still
-    * has a remote reference to the stub.
-    */
-   static class ServiceStub extends IFMTransmitterService.Stub
-   {
-      WeakReference<FMTransmitterService> mService;
-
-      ServiceStub(FMTransmitterService service)
-      {
-         mService = new WeakReference<FMTransmitterService>(service);
-      }
-
-      public boolean fmOn() throws RemoteException
-      {
-         return(mService.get().fmOn());
-      }
-
-      public boolean fmOff() throws RemoteException
-      {
-         return(mService.get().fmOff());
-      }
-      public boolean fmRadioReset() throws RemoteException
-      {
-         return(mService.get().fmRadioReset());
-      }
-      public boolean fmRestart() throws RemoteException
-      {
-         return(mService.get().fmRestart());
-      }
-
-      public boolean isFmOn()
-      {
-         return(mService.get().isFmOn());
-      }
-      public boolean fmReconfigure()
-      {
-         return(mService.get().fmReconfigure());
-      }
-
-      public void registerCallbacks(IFMTransmitterServiceCallbacks cb)
-      throws RemoteException {
-         mService.get().registerCallbacks(cb);
-      }
-
-      public boolean searchWeakStationList(int numStations)
-      throws RemoteException {
-         return(mService.get().searchWeakStationList(numStations));
-      }
-
-      public void unregisterCallbacks() throws RemoteException
-      {
-         mService.get().unregisterCallbacks();
-      }
-
-      public boolean tune(int frequency)
-      {
-         return(mService.get().tune(frequency));
-      }
-
-      public boolean cancelSearch()
-      {
-         return(mService.get().cancelSearch());
-      }
-
-      public String getRadioText()
-      {
-         return(mService.get().getRadioText());
-      }
-
-      public int[] getSearchList()
-      {
-         return(mService.get().getSearchList());
-      }
-
-      public boolean isInternalAntennaAvailable()
-      {
-         return(mService.get().isInternalAntennaAvailable());
-      }
-      public boolean isHeadsetPlugged()
-      {
-         return(mService.get().isHeadsetPlugged());
-      }
-      public boolean isCallActive()
-      {
-          return(mService.get().isCallActive());
-      }
-      public String getPSData()
-      {
-          return(mService.get().getPSData());
-      }
-   }
-
-   private final IBinder mBinder = new ServiceStub(this);
-   /*
-    * 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;
-
-      Log.d(LOGTAG, "fmOn");
-      mWakeLock.acquire(10*1000);
-      if (mTransmitter == null) {
-          try {
-               mTransmitter = new FmTransmitter(FMRADIO_DEVICE_FD_STRING, transmitCallbacks);
-               Log.d(LOGTAG, "new transmitter created");
-          } catch (InstantiationException e) {
-               throw new RuntimeException("FmTx service not available!");
-          }
-      }
-      if (mTransmitter != null)
-      {
-         if (isFmOn())
-         {
-            /* FM Is already on,*/
-            bStatus = true;
-            try {
-                 if(mCallbacks != null) {
-                    mCallbacks.onEnabled(true);
-                 }
-            } catch(RemoteException e) {
-                 e.printStackTrace();
-            }
-            Log.d(LOGTAG, "mTransmitter is 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());
-
-             boolean bFmRxEnabled = false;
-
-             if (!mA2dpDeviceState.isDeviceAvailable()) {
-                 bStatus = mTransmitter.enable(config);
-             }
-             if( false == bStatus ) {
-                Log.e(LOGTAG,"FM Enable failed");
-                return bStatus;
-             }
-             bStatus = mTransmitter.setTxPowerLevel(FmTransmitter.FM_TX_PWR_LEVEL_7);
-
-             if( false == bStatus ) {
-                Log.e(LOGTAG,"FM setPowerLevel failed");
-                return bStatus;
-             }
-
-             Log.e(LOGTAG, "FMTx is on: Requesting to start FM TX");
-//             AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_TX,
-//                                  AudioSystem.DEVICE_STATE_AVAILABLE, "");
-         }
-
-         if(true == bStatus )
-         {
-                bStatus = mTransmitter.setRdsOn();
-                if( true != bStatus ) {
-                    Log.d(LOGTAG, "FMTx setRdsOn failed");
-                } else {
-                    if(false == mTransmitter.getInternalAntenna()) {
-                        Log.d(LOGTAG, "Setting internal antenna explicitly");
-                        mTransmitter.setInternalAntenna(true);
-                    }
-                    startNotification();
-                }
-         }
-         else
-         {
-             stop();
-         }
-      }
-      return(bStatus);
-   }
-
-  /*
-   * Turn OFF FM Operations: This disables all the current FM operations             .
-   */
-   private void fmOperationsOff() {
-
-      Log.d(LOGTAG, "fmOperationsOff" );
-
-      Log.e(LOGTAG, "FMTx is off: Requesting to stop FM Tx");
-//      AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_TX,
-//                           AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
-   }
-   /*
-    * 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() {
-      boolean bStatus=false;
-      Log.d(LOGTAG, "fmOff");
-
-      fmOperationsOff();
-
-      // This will disable the FM radio device
-      if (mTransmitter != null)
-      {
-         bStatus = mTransmitter.disable();
-         mTransmitter = null;
-      }
-      /* Disable Receiver */
-      if (mReceiver != null)
-      {
-         bStatus = mReceiver.disable(this);
-         mReceiver = null;
-      }
-      RText = " ";
-      stop();
-      return(bStatus);
-   }
-  /*
-   * Turn OFF FM: Disable the FM Host when hardware resets asynchronously            .
-   *                                                                                 .
-   * @return true if fm Reset api was invoked successfully, false if the api failed  .
-   */
-   private boolean fmRadioReset() {
-      boolean bStatus=false;
-      Log.d(LOGTAG, "fmRadioReset");
-      fmOperationsOff();
-
-      // This will disable the FM radio device
-      if (mTransmitter != null)
-      {
-         bStatus = mTransmitter.reset();
-         mTransmitter = null;
-      }
-      /* Disable Receiver */
-      if (mReceiver != null)
-      {
-         bStatus = mReceiver.reset();
-         mReceiver = null;
-      }
-      stop();
-      return(bStatus);
-   }
-
-   /*
-    * Restart FM Transmitter: Disables FM receiver mode or transmitter is already active
-    * and 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 fmRestart() {
-      boolean bStatus=false;
-      Log.d(LOGTAG, "fmRestart");
-
-      /* First Disable Transmitter, if enabled */
-      if (mTransmitter != null)
-      {
-         bStatus = mTransmitter.disable();
-         mTransmitter = null;
-         mFMOn = false;
-      }
-
-      /* Disable Receiver */
-      if (mReceiver != null)
-      {
-         bStatus = mReceiver.disable(this);
-         mReceiver = null;
-      }
-      try {
-          Thread.sleep(100);//sleep needed for SoC to switch mode
-      }
-      catch ( Exception ex ) {
-          Log.d( LOGTAG,  "RunningThread InterruptedException");
-      }
-      bStatus = fmOn();
-      return(bStatus);
-   }
-
-   /* Returns whether FM hardware is ON.
-    *
-    * @return true if FM was tuned, searching. (at the end of
-    * the search FM goes back to tuned).
-    *
-    */
-   public boolean isFmOn() {
-      return mFMOn;
-   }
-
-   /*
-    *  ReConfigure the FM Setup parameters
-    *  - Band
-    *  - Channel Spacing (50/100/200 KHz)
-    *  - Emphasis (50/75)
-    *  - Frequency limits
-    *  - RDS/RBDS standard
-    *
-    * @return true if configure api was invoked successfully, false if the api failed.
-    */
-   public boolean fmReconfigure() {
-      boolean bStatus=false;
-      Log.d(LOGTAG, "fmReconfigure");
-      if (mTransmitter != null)
-      {
-         // This sets up the FM radio device
-         FmConfig config = FmSharedPreferences.getFMConfiguration();
-         Log.d(LOGTAG, "RadioBand   :"+ config.getRadioBand());
-         Log.d(LOGTAG, "Emphasis    :"+ config.getEmphasis());
-         Log.d(LOGTAG, "ChSpacing   :"+ config.getChSpacing());
-         Log.d(LOGTAG, "RdsStd      :"+ config.getRdsStd());
-         Log.d(LOGTAG, "LowerLimit  :"+ config.getLowerLimit());
-         Log.d(LOGTAG, "UpperLimit  :"+ config.getUpperLimit());
-         bStatus = mTransmitter.configure(config);
-      }
-      if (mCallbacks != null)
-      {
-         try
-         {
-            mCallbacks.onReconfigured();
-         } catch (RemoteException e)
-         {
-            e.printStackTrace();
-         }
-      }
-      return(bStatus);
-   }
-
-   /*
-    * Register UI/Activity Callbacks
-    */
-   public void registerCallbacks(IFMTransmitterServiceCallbacks cb)
-   {
-      mCallbacks = cb;
-   }
-
-   /*
-    *  unRegister UI/Activity Callbacks
-    */
-   public void unregisterCallbacks()
-   {
-      mCallbacks=null;
-   }
-
-   /* Tunes to the specified frequency
-    *
-    * @return true if Tune command was invoked successfully, false if not muted.
-    *  Note: Callback FmRxEvRadioTuneStatus will be called when the tune
-    *        is complete
-    */
-   public boolean tune(int frequency) {
-      boolean bCommandSent=false;
-      double doubleFrequency = frequency/1000.00;
-
-      Log.d(LOGTAG, "tune:  " + doubleFrequency);
-      if (mTransmitter != null)
-      {
-         mTransmitter.setStation(frequency);
-         mTunedFrequency = frequency;
-         bCommandSent = true;
-      }
-      return bCommandSent;
-   }
-
-   /* Search for the weakest 12 FM Stations in the current band.
-    *
-    * It searches in the forward direction relative to the current tuned station.
-    * int numStations: maximum number of stations to search.
-    *
-    * @return true if Search command was invoked successfully, false if not muted.
-    *  Note: 1. Callback FmRxEvSearchListComplete will be called when the Search
-    *        is complete
-    *        2. Callback FmRxEvRadioTuneStatus will also be called when tuned to
-    *        the previously tuned station.
-    */
-   public boolean searchWeakStationList(int numStations)
-   {
-
-       boolean bStatus=false;
-       FmConfig config = FmSharedPreferences.getFMConfiguration();
-
-       if(null != mTransmitter) {
-           mTransmitter.disable();
-           mTransmitter = null;
-           mFMOn = false;
-       }
-       if(null != mReceiver) {
-           mReceiver.disable(this);
-           mReceiver = null;
-       }
-       try {
-           Thread.sleep(100);//SoC needs a delay to switch mode
-       } catch (Exception ex) {
-           Log.d( LOGTAG,  "RunningThread InterruptedException");
-       }
-
-
-       if(null == mReceiver) {
-           try {
-               mReceiver = new FmReceiver(FMRADIO_DEVICE_FD_STRING, fmCallbacks);
-           }
-           catch (InstantiationException e){
-            throw new RuntimeException("FmTx service not available!");
-           }
-           if (mReceiver.getFMState() == mReceiver.FMState_Turned_Off) {
-               bStatus = mReceiver.enable(config, this);
-           } else {
-               try {
-                   Thread.sleep(100);
-               } catch (Exception ex) {
-                   Log.d( LOGTAG,  "RunningThread InterruptedException");
-               }
-               bStatus = mReceiver.enable(config, this);
-           }
-           if (!bStatus) {
-               Log.e( LOGTAG,  "Search for weak station failed");
-               return false;
-           }
-       }
-
-       bStatus = mReceiver.setStation(config.getLowerLimit());
-
-       Log.d(LOGTAG, "mReceiver.setStation:  bStatus: " + bStatus);
-       bStatus = mReceiver.searchStationList( FmReceiver.FM_RX_SRCHLIST_MODE_WEAKEST,
-                                              FmReceiver.FM_RX_SEARCHDIR_UP,
-                                              numStations,
-                                              0);
-
-        mFMSearchStations = 0;//numStations;
-        if(bStatus == false)
-        {
-           try
-           {
-              if (mCallbacks != null)
-              {
-                 mCallbacks.onSearchListComplete(false);
-              }
-           } catch (RemoteException e)
-           {
-              e.printStackTrace();
-           }
-        }
-      return bStatus;
-   }
-
-   /* Cancel any ongoing Search (Seek/Scan/SearchStationList).
-    *
-    * @return true if Search command was invoked successfully, false if not muted.
-    *  Note: 1. Callback FmRxEvSearchComplete will be called when the Search
-    *        is complete/cancelled.
-    *        2. Callback FmRxEvRadioTuneStatus will also be called when tuned to a station
-    *        at the end of the Search or if the seach was cancelled.
-    */
-   public boolean cancelSearch()
-   {
-      boolean bStatus=false;
-      if (mReceiver != null)
-      {
-         bStatus = mReceiver.cancelSearch();
-         Log.d(LOGTAG, "mReceiver.cancelSearch: bStatus: " + bStatus);
-         try
-         {
-            if (mCallbacks != null)
-            {
-               mCallbacks.onSearchListComplete(false);
-            }
-         } catch (RemoteException e)
-         {
-            e.printStackTrace();
-         }
-
-      }
-      return bStatus;
-   }
-
-   /* Retrieves the basic String to be displayed on UI
-    * Other than this static string the RDS String will be
-    * queried by Tx Activity to update on UI
-    */
-   public String getRadioText() {
-      String str = "Radio Text: Transmitting ";
-      Log.d(LOGTAG, "Radio Text: [" + str + "]");
-      return str;
-   }
-
-   /* Retrieves the station list from the SearchStationlist.
-    *
-    * @return Array of integers that represents the station frequencies.
-    * Note: 1. This is a synchronous call that should typically called when
-    *           Callback onSearchListComplete.
-    */
-   public int[] getSearchList()
-   {
-      int[] frequencyList = null;
-      if (mReceiver != null)
-      {
-         Log.d(LOGTAG, "getSearchList: ");
-         frequencyList = mReceiver.getStationList();
-      }
-      return frequencyList;
-   }
-   /* Set the FM Power Mode on the FM hardware SoC.
-    * Typically used when UI/Activity is in the background, so the Host is interrupted less often.
-    *
-    * boolean bLowPower: true: Enable Low Power mode on FM hardware.
-    *                    false: Disable Low Power mode on FM hardware. (Put into normal power mode)
-    * @return true if set power mode api was invoked successfully, false if the api failed.
-    */
-   public boolean setLowPowerMode(boolean bLowPower)
-   {
-      boolean bCommandSent=false;
-      if (mTransmitter != null)
-      {
-         Log.d(LOGTAG, "setLowPowerMode: " + bLowPower);
-         if(bLowPower)
-         {
-            bCommandSent = mTransmitter.setPowerMode(FmTransmitter.FM_TX_LOW_POWER_MODE);
-         }
-         else
-         {
-            bCommandSent = mTransmitter.setPowerMode(FmTransmitter.FM_TX_NORMAL_POWER_MODE);
-         }
-      }
-      return bCommandSent;
-   }
-   /** Determines if an internal Antenna is available.
-    *
-    * @return true if internal antenna is available, false if
-    *         internal antenna is not available.
-    */
-   public boolean isInternalAntennaAvailable()
-   {
-      boolean bAvailable  = false;
-      /* Update this when the API is available */
-
-      if(null != mTransmitter ) {
-          bAvailable = mTransmitter.getInternalAntenna();
-          Log.d(LOGTAG, "internalAntennaAvailable: " + bAvailable);
-      } else if( null != mReceiver ) {
-          bAvailable = mReceiver.getInternalAntenna();
-          Log.d(LOGTAG, "internalAntennaAvailable: " + bAvailable);
-      }
-      return bAvailable;
-   }
-
-
-   private FmTransmitterCallbacksAdaptor transmitCallbacks = new  FmTransmitterCallbacksAdaptor() {
-      public void FmTxEvRDSGroupsAvailable() {
-         // Do nothing
-      }
-
-      public void FmTxEvRDSGroupsComplete() {
-         // Do nothing
-      }
-      public void FmTxEvContRDSGroupsComplete() {
-      }
-
-      public void FmTxEvTuneStatusChange(int freq) {
-
-        Log.d(LOGTAG, "onTuneStatusChange\n");
-        if (mCallbacks != null)
-        {
-           try
-           {
-              mCallbacks.onTuneStatusChanged(freq);
-           } catch (RemoteException e)
-           {
-              e.printStackTrace();
-           }
-        }
-        /* Update the frequency in the StatusBar's Notification */
-        startNotification();
-
-        String s = getPSData();
-        if( true == mTransmitter.startPSInfo(
-            s, FM_TX_PROGRAM_TYPE, FM_TX_PROGRAM_ID, FM_TX_PS_REPEAT_COUNT ) ) {
-            if (mCallbacks != null)
-            {
-               try
-               {
-                  mCallbacks.onPSInfoSent(s);
-               } catch (RemoteException e)
-               {
-                  e.printStackTrace();
-               }
-            }
-        }
-
-        if (mTransmitter != null ){
-            mTransmitter.startRTInfo(RText, FM_TX_PROGRAM_TYPE, FM_TX_PROGRAM_ID );
-        }
-
-        try {
-             if (mCallbacks != null ) {
-                 mCallbacks.onMetaDataChanged(RText);
-             } else {
-                 Log.d(LOGTAG, "callback is not there");
-             }
-        } catch (RemoteException ex){
-             ex.printStackTrace();
-        }
-
-      }
-
-      public void FmTxEvRadioDisabled() {
-         Log.d(LOGTAG, "onRadioDisabled");
-         mFMOn = false;
-         if((mServiceInUse) && (mCallbacks != null) ) {
-            try {
-                  mCallbacks.onDisabled();
-            } catch(RemoteException e) {
-                  e.printStackTrace();
-            }
-         }
-      }
-      public void FmTxEvRadioEnabled() {
-         mFMOn = true;
-         if((mServiceInUse) && (mCallbacks != null) ) {
-            try {
-                  mCallbacks.onEnabled(true);
-            } catch(RemoteException e) {
-                  e.printStackTrace();
-            }
-         }
-      }
-      public void FmTxEvRadioReset() {
-         if(isFmOn()) {
-            // Received Radio Disable event unexpectedly
-            Log.d(LOGTAG, "FM is ON, reset FM");
-            fmRadioReset();
-            try {
-                /* Notify the UI/Activity, only if the service is "bound"
-                   by an activity and if Callbacks are registered
-                */
-                if((mServiceInUse) && (mCallbacks != null)) {
-                    mCallbacks.onRadioReset();
-                }
-             }
-             catch (RemoteException e) {
-                e.printStackTrace();
-             }
-         }
-      }
-   };
-
-   /* Receiver callbacks back from the FM Stack */
-   FmRxEvCallbacksAdaptor fmCallbacks = new FmRxEvCallbacksAdaptor()
-   {
-      public void FmRxEvEnableReceiver()
-      {
-         Log.d(LOGTAG, "FmRxEvEnableReceiver");
-      }
-      public void FmRxEvDisableReceiver()
-      {
-         Log.d(LOGTAG, "FmRxEvDisableReceiver");
-      }
-      public void FmRxEvRadioReset()
-      {
-         Log.d(LOGTAG, "FmRxEvRadioReset");
-         if(isFmOn()) {
-             // Received Radio Reset event
-             Log.d(LOGTAG, "FM is ON, reset FM");
-             fmRadioReset();
-             try
-             {
-                /* Notify the UI/Activity, only if the service is "bound"
-                   by an activity and if Callbacks are registered
-                */
-                if((mServiceInUse) && (mCallbacks != null) )
-                {
-                    mCallbacks.onRadioReset();
-                }
-             }
-             catch (RemoteException e)
-             {
-                e.printStackTrace();
-             }
-         }
-      }
-
-      public void FmRxEvRadioTuneStatus(int frequency)
-      {
-         Log.d(LOGTAG, "FmRxEvRadioTuneStatus: Tuned Frequency: " +frequency);
-      }
-
-      public void FmRxEvSearchListComplete()
-      {
-         Log.d(LOGTAG, "FmRxEvSearchListComplete");
-         try
-         {
-            if (mCallbacks != null) {
-                mCallbacks.onSearchListComplete(true);
-            } else if(mReceiver != null) {
-                mReceiver.disable();
-            }
-         } catch (RemoteException e)
-         {
-            e.printStackTrace();
-         }
-      }
-
-      public void FmRxEvEnableSlimbus(int status)
-      {
-         Log.d(LOGTAG, "FmRxEvEnableReceiver status = " + status);
-      }
-	  public void FmRxEvEnableSoftMute(int status)
-      {
-         Log.d(LOGTAG, "FmRxEvEnableReceiver status = " + status);
-      }
-   };
-
-
-   /*
-    *  Read the Tuned Frequency from the FM module.
-    */
-   private String getTunedFrequencyString() {
-      double frequency = mTunedFrequency / 1000.0;
-      String frequencyString = getString(R.string.stat_notif_tx_frequency, (""+frequency));
-      return frequencyString;
-   }
-   /**
-    * Registers an intent to listen for ACTION_HEADSET_PLUG
-    * notifications. This intent is called to know if the headset
-    * was plugged in/out
-    */
-   public void registerHeadsetListener() {
-       if (mHeadsetReceiver == null) {
-           mHeadsetReceiver = new BroadcastReceiver() {
-               @Override
-               public void onReceive(Context context, Intent intent) {
-                   String action = intent.getAction();
-                   if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
-                      Log.d(LOGTAG, "ACTION_HEADSET_PLUG Intent received");
-                      // Listen for ACTION_HEADSET_PLUG broadcasts.
-                      Log.d(LOGTAG, "mTransmitter: ACTION_HEADSET_PLUG");
-                      Log.d(LOGTAG, "==> intent: " + intent);
-                      Log.d(LOGTAG, "    state: " + intent.getIntExtra("state", 0));
-                      Log.d(LOGTAG, "    name: " + intent.getStringExtra("name"));
-                      mHeadsetPlugged = (intent.getIntExtra("state", 0) == 1);
-                      mHandler.post(mChangeFMTxState);
-
-                   } else if (mA2dpDeviceState.isA2dpStateChange(action)) {
-                       if (mA2dpDeviceState.isConnected(intent)){
-                           Log.d(LOGTAG, " A2DP connected");
-                           mHeadsetPlugged = true;
-                           if( mFMOn == true)
-                           {
-                               mHandler.post(mChangeFMTxState);
-                           }
-                       } else if( !mA2dpDeviceState.isConnected(intent)) {
-                           Log.d(LOGTAG, "A2DP disconnected");
-                           mHeadsetPlugged = false;
-                           if( mFMOn == false) // when FM Tx App open, DISC BT
-                           {
-                               Log.d(LOGTAG, "posting for a2dp state change");
-                               mHandler.post(mChangeFMTxState);
-                           }
-                       }
-                   } else if (action.equals("HDMI_CONNECTED")) {
-                       if( mFMOn == true) {
-                           Log.d(LOGTAG, "posting for hdmi state change");
-                           mHandler.post(mChangeFMTxState);
-                       }
-                   }
-               }
-           };
-           IntentFilter iFilter = new IntentFilter();
-           iFilter.addAction(Intent.ACTION_HEADSET_PLUG);
-           iFilter.addAction(mA2dpDeviceState.getActionSinkStateChangedString());
-           iFilter.addAction(mA2dpDeviceState.getActionPlayStateChangedString());
-           iFilter.addAction("HDMI_CONNECTED");
-           iFilter.addCategory(Intent.CATEGORY_DEFAULT);
-           registerReceiver(mHeadsetReceiver, iFilter);
-       }
-   }
-   final Runnable    mChangeFMTxState = new Runnable() {
-       public void run() {
-           boolean bStatus = false;
-
-           Log.d(LOGTAG, "Enter change FM Tx State");
-           /* Update the UI based on the state change of the headset/antenna*/
-           if(mHeadsetPlugged) {
-              bStatus =  cancelSearch();
-              if(bStatus == false)
-                 Log.e(LOGTAG, "Error in cancelling the search");
-              if(isFmOn()) {
-                 Log.d(LOGTAG, "disable called from headset handler");
-                 bStatus = fmOff();
-                 if(mServiceInUse && (mCallbacks != null) && (bStatus == true)) {
-                    try {
-                        mCallbacks.onDisabled();
-                    } catch(RemoteException e) {
-                        e.printStackTrace();
-                    }
-                 } else if(bStatus == false) {
-                    Log.e(LOGTAG, "Error in turning off the FM TX ");
-                 }
-              } else if(mReceiver != null) {
-                 bStatus = mReceiver.disable();
-                 if(bStatus == true)
-                    mReceiver = null;
-                 else
-                    Log.e(LOGTAG, "Error in disabling the FM RX");
-              }
-           }else {
-              if(!isFmOn()) {
-                 bStatus = fmOn();
-                 if(mServiceInUse && (mCallbacks != null) && (bStatus == true)) {
-                    try {
-                        mCallbacks.onEnabled(true);
-                    } catch(RemoteException e) {
-                        e.printStackTrace();
-                    }
-                 } else if(bStatus == false) {
-                    Log.e(LOGTAG, "Error in enabling the FM TX");
-                 }
-              }
-           }
-       }
-   };
-   private class RdsDisplay extends IRemoteControlDisplay.Stub {
-        RdsDisplay() {
-        }
-
-        @Override
-        public void setPlaybackState(int generationId, int state, long stateChangeTimeMs,
-                  long currentPosMs, float speed) {
-        }
-
-        @Override
-        public void setMetadata(int generationId, Bundle metadata) {
-            updateMetadata(metadata);
-        }
-
-        @Override
-        public void setTransportControlInfo(int generationId, int flags, int posCapabilities) {
-        }
-
-        @Override
-        public void setArtwork(int generationId, Bitmap bitmap) {
-        }
-
-        @Override
-        public void setAllMetadata(int generationId, Bundle metadata, Bitmap bitmap) {
-         }
-
-        @Override
-        public void setCurrentClientId(int clientGeneration, PendingIntent clientMediaIntent,
-                boolean clearing) {
-        }
-
-        @Override
-        public void setEnabled(boolean enabled) {
-        }
-   }
-
-   class Metadata {
-        private String artist;
-        private String trackTitle;
-        private String albumTitle;
-
-        public Metadata() {
-            artist = null;
-            trackTitle = null;
-            albumTitle = null;
-        }
-
-        public String toString() {
-            return "Metadata[artist=" + artist + " trackTitle=" + trackTitle + " albumTitle=" +
-                   albumTitle + "]";
-        }
-   }
-
-   private String getMdString(Bundle data, int id) {
-        return data.getString(Integer.toString(id));
-   }
-
-   private void updateMetadata(Bundle data) {
-        String oldMetadata = mMetadata.toString();
-        mMetadata.artist = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST);
-        mMetadata.trackTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_TITLE);
-        mMetadata.albumTitle = getMdString(data, MediaMetadataRetriever.METADATA_KEY_ALBUM);
-        Log.v(LOGTAG, "mMetadata=" + mMetadata.toString());
-        if (mTransmitter != null ){
-            RText = mMetadata.albumTitle  +":" + mMetadata.trackTitle +":"+ mMetadata.artist;
-            Log.d(LOGTAG,"RT string size is "+RText.length());
-            mTransmitter.startRTInfo(RText, FM_TX_PROGRAM_TYPE, FM_TX_PROGRAM_ID );
-        }
-
-        try {
-             if (mCallbacks != null ) {
-                 mCallbacks.onMetaDataChanged(RText);
-             } else {
-                 Log.d(LOGTAG, "callback is not there");
-             }
-        } catch (RemoteException ex){
-             ex.printStackTrace();
-        }
-   }
-   public boolean isHeadsetPlugged() {
-       if (mA2dpDeviceState.isDeviceAvailable())
-          mHeadsetPlugged = true;
-       return mHeadsetPlugged;
-   }
-   public boolean isCallActive() {
-       TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
-       if( TelephonyManager.CALL_STATE_IDLE !=tmgr.getCallState() )
-           return true;
-       return false;
-   }
-   public String getPSData(){
-       return QFM_STRING;
-   }
-}
diff --git a/fmapp2/src/com/caf/fmradio/IFMTransmitterService.aidl b/fmapp2/src/com/caf/fmradio/IFMTransmitterService.aidl
deleted file mode 100644
index 79e01de..0000000
--- a/fmapp2/src/com/caf/fmradio/IFMTransmitterService.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.caf.fmradio;
-
-import com.caf.fmradio.IFMTransmitterServiceCallbacks;
-interface IFMTransmitterService
-{
-    boolean fmOn();
-    boolean fmOff();
-    boolean fmRestart();
-    boolean isFmOn();
-    boolean fmReconfigure();
-    void registerCallbacks(IFMTransmitterServiceCallbacks cb);
-    void unregisterCallbacks();
-    boolean tune(int frequency);
-    boolean searchWeakStationList(int numStations);
-    int[]   getSearchList();
-    boolean cancelSearch();
-    String getRadioText();
-    boolean isInternalAntennaAvailable();
-    boolean isHeadsetPlugged();
-    boolean isCallActive();
-    String  getPSData();
-}
-
diff --git a/fmapp2/src/com/caf/fmradio/Settings.java b/fmapp2/src/com/caf/fmradio/Settings.java
index de19f01..6ad98e6 100644
--- a/fmapp2/src/com/caf/fmradio/Settings.java
+++ b/fmapp2/src/com/caf/fmradio/Settings.java
@@ -81,6 +81,7 @@
 
         private FmSharedPreferences mPrefs = null;
         private boolean mRxMode = false;
+        private Dialog mDlgRestoreFactory;
 
         private int min_freq;
         private int max_freq;
@@ -455,15 +456,13 @@
         public boolean onPreferenceClick(Preference preference) {
           boolean handled = false;
           if (preference == mRestoreDefaultPreference) {
-              showDialog(RESTORE_FACTORY_DEFAULT_INT);
+             mDlgRestoreFactory = createDlgRestoreFactory();
+             mDlgRestoreFactory.show();
           }
           return handled;
         }
 
-        @Override
-        protected Dialog onCreateDialog(int id) {
-          switch (id) {
-          case RESTORE_FACTORY_DEFAULT_INT:
+        private Dialog createDlgRestoreFactory() {
                return new AlertDialog.Builder(this).setIcon(
                       R.drawable.alert_dialog_icon).setTitle(
                       R.string.settings_revert_confirm_title).setMessage(
@@ -484,10 +483,6 @@
                                                        int whichButton) {
                                 }
                               }).create();
-                default:
-                        break;
-                }
-                return null;
         }
 
         private void restoreSettingsDefault() {
diff --git a/fmapp2/src/com/caf/fmradio/StationListActivity.java b/fmapp2/src/com/caf/fmradio/StationListActivity.java
index 46b59ad..643fd57 100644
--- a/fmapp2/src/com/caf/fmradio/StationListActivity.java
+++ b/fmapp2/src/com/caf/fmradio/StationListActivity.java
@@ -139,10 +139,17 @@
         AdapterContextMenuInfo mi = (AdapterContextMenuInfo) item.getMenuInfo();
         switch (item.getItemId()) {
         case CONTEXT_MENU_RENAME:
-            showDialog(DIALOG_RENAME_ID);
+            mRenameDialog = new Dialog(this);
+            mRenameDialog.setContentView(R.layout.rename_dialog);
+            createRenameDeleteDialog(DIALOG_RENAME_ID, mRenameDialog);
+            mRenameDialog.show();
             break;
+
         case CONTEXT_MENU_DELETE:
-            showDialog(DIALOG_DELETE_ID);
+            mDeleteDialog = new Dialog(this);
+            mDeleteDialog.setContentView(R.layout.delete_dialog);
+            createRenameDeleteDialog(DIALOG_DELETE_ID, mDeleteDialog);
+            mDeleteDialog.show();
             break;
 
         }
@@ -177,8 +184,7 @@
         return false;
     }
 
-    @Override
-    protected void onPrepareDialog(int id, Dialog dialog, Bundle b) {
+    private void createRenameDeleteDialog(int id, Dialog dialog) {
         // TODO Auto-generated method stub
         // super.onPrepareDialog(id, dialog);
         // After change system language, current function will be executed before
@@ -248,25 +254,6 @@
         }
     }
 
-    @Override
-    protected Dialog onCreateDialog(int id, Bundle b) {
-        // TODO Auto-generated method stub
-        //should return different dialog
-        switch (id) {
-        case DIALOG_RENAME_ID:
-            mRenameDialog = new Dialog(this);
-            mRenameDialog.setContentView(R.layout.rename_dialog);
-            return mRenameDialog;
-        case DIALOG_DELETE_ID:
-            mDeleteDialog = new Dialog(this);
-            mDeleteDialog.setContentView(R.layout.delete_dialog);
-            return mDeleteDialog;
-        default:
-            ;
-        }
-        return null;
-    }
-
     private void saveStationName(int id, String name) {
         Integer stationIndex = mIndex.get(new Integer(id));
         SharedPreferences sp = getSharedPreferences(
diff --git a/fmapp2/src/com/caf/utils/FrequencyPickerDialog.java b/fmapp2/src/com/caf/utils/FrequencyPickerDialog.java
index be1c8b0..2b0b7b0 100644
--- a/fmapp2/src/com/caf/utils/FrequencyPickerDialog.java
+++ b/fmapp2/src/com/caf/utils/FrequencyPickerDialog.java
@@ -99,8 +99,8 @@
         }
         mCallBack = callback;
 
-        setButton(context.getString(R.string.set), this);
-        setButton2(context.getString(R.string.cancel),  (OnClickListener) null);
+        setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.set), this);
+        setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel),  (OnClickListener) null);
         setIcon(R.drawable.alert_dialog_icon);
 
         LayoutInflater inflater =
diff --git a/helium/radio-helium.h b/helium/radio-helium.h
index 7c7221b..2111eda 100644
--- a/helium/radio-helium.h
+++ b/helium/radio-helium.h
@@ -919,12 +919,6 @@
 #define AUDIO_CTRL_INTR (1 << 2)
 #define AF_JUMP_ENABLE  (1 << 4)
 
-int hci_def_data_read(struct hci_fm_def_data_rd_req *arg,
-       struct radio_hci_dev *hdev);
-int hci_def_data_write(struct hci_fm_def_data_wr_req *arg,
-       struct radio_hci_dev *hdev);
-int hci_fm_do_calibration(char *arg, struct radio_hci_dev *hdev);
-
 static inline int is_valid_tone(int tone)
 {
     if ((tone >= MIN_TX_TONE_VAL) &&
@@ -1250,7 +1244,7 @@
 
 struct fm_hal_t {
     struct radio_helium_device *radio;
-    fm_hal_callbacks_t *jni_cb;
+    const fm_hal_callbacks_t *jni_cb;
     void *private_data;
     pthread_mutex_t cmd_lock;
     pthread_cond_t cmd_cond;
@@ -1260,7 +1254,7 @@
 struct fm_interface_t {
     int (*init)(const fm_hal_callbacks_t *p_cb);
     int (*set_fm_ctrl)(int opcode, int val);
-    void (*get_fm_ctrl) (int opcode, int *val);
+    int (*get_fm_ctrl) (int opcode, int *val);
 };
 
 #endif /* __UAPI_RADIO_HCI_CORE_H */
diff --git a/helium/radio_helium_hal.c b/helium/radio_helium_hal.c
index 947402f..42be704 100644
--- a/helium/radio_helium_hal.c
+++ b/helium/radio_helium_hal.c
@@ -61,19 +61,19 @@
 struct fm_hal_t *hal = NULL;
 static pthread_mutex_t hal_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_cond_t hal_cond = PTHREAD_COND_INITIALIZER;
-
+#undef LOG_TAG
 #define LOG_TAG "radio_helium"
 #define WAIT_TIMEOUT 20000 /* 20*1000us */
 #define HAL_TIMEOUT  3
 
 static void radio_hci_req_complete(char result)
 {
-  ALOGD("%s:enetred %s", LOG_TAG, __func__);
+  ALOGD("%s:enetred %s result %d", LOG_TAG, __func__, result);
 }
 
 static void radio_hci_status_complete(int result)
 {
-   ALOGD("%s:enetred %s", LOG_TAG, __func__);
+   ALOGD("%s:enetred %s result %d", LOG_TAG, __func__, result);
 }
 
 static void hci_cc_fm_enable_rsp(char *ev_rsp)
@@ -111,7 +111,6 @@
 static void hci_cc_fm_disable_rsp(char *ev_buff)
 {
     char status;
-    int ret;
 
     if (ev_buff == NULL) {
         ALOGE("%s:%s, buffer is null\n", LOG_TAG, __func__);
@@ -157,7 +156,6 @@
 static void hci_cc_rds_grp_cntrs_ext_rsp(char *ev_buff)
 {
     char status;
-    int i;
     if (ev_buff == NULL) {
         ALOGE("%s:%s, buffer is null\n", LOG_TAG, __func__);
         return;
@@ -457,10 +455,10 @@
     hal->jni_cb->enable_softmute_cb(ev_buff[0]);
 }
 
-static inline void hci_cmd_complete_event(char *buff)
+static inline void hci_cmd_complete_event(uint8_t buff[])
 {
     uint16_t opcode;
-    uint8_t *pbuf;
+    char *pbuf;
 
     if (buff == NULL) {
         ALOGE("%s:%s, buffer is null\n", LOG_TAG, __func__);
@@ -469,7 +467,7 @@
     ALOGV("%s:buff[1] = 0x%x buff[2] = 0x%x", LOG_TAG, buff[1], buff[2]);
     opcode = ((buff[2] << 8) | buff[1]);
     ALOGV("%s: Received HCI CMD COMPLETE EVENT for the opcode: 0x%x", __func__, opcode);
-    pbuf = &buff[3];
+    pbuf = (char *)&buff[3];
 
     switch (opcode) {
     case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_ENABLE_RECV_REQ):
@@ -515,10 +513,10 @@
             hci_cc_rds_grp_cntrs_ext_rsp(pbuf);
             break;
     case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_PEEK_DATA):
-            hci_cc_riva_peek_rsp(buff);
+            hci_cc_riva_peek_rsp((char *)buff);
             break;
     case hci_diagnostic_cmd_op_pack(HCI_OCF_FM_SSBI_PEEK_REG):
-            hci_cc_ssbi_peek_rsp(buff);
+            hci_cc_ssbi_peek_rsp((char *)buff);
             break;
     case hci_diagnostic_cmd_op_pack(HCI_FM_SET_GET_RESET_AGC):
             hci_cc_agc_rsp(pbuf);
@@ -592,7 +590,7 @@
     }
 }
 
-static inline void hci_cmd_status_event(char *st_rsp)
+static inline void hci_cmd_status_event(uint8_t st_rsp[])
 {
     struct hci_ev_cmd_status *ev = (void *) st_rsp;
     uint16_t opcode;
@@ -608,12 +606,11 @@
     radio_hci_status_complete(ev->status);
 }
 
-static inline void hci_ev_tune_status(char *buff)
+static inline void hci_ev_tune_status(uint8_t buff[])
 {
 
     memcpy(&hal->radio->fm_st_rsp.station_rsp, &buff[0],
                                sizeof(struct hci_ev_tune_status));
-    char *freq = &hal->radio->fm_st_rsp.station_rsp.station_freq;
     ALOGD("freq = %d", hal->radio->fm_st_rsp.station_rsp.station_freq);
     hal->jni_cb->tune_cb(hal->radio->fm_st_rsp.station_rsp.station_freq);
 
@@ -631,12 +628,12 @@
         hal->jni_cb->rds_avail_status_cb(false);
 }
 
-static inline void hci_ev_search_next(char *buff)
+static inline void hci_ev_search_next()
 {
     hal->jni_cb->scan_next_cb();
 }
 
-static inline void hci_ev_stereo_status(char *buff)
+static inline void hci_ev_stereo_status(uint8_t buff[])
 {
     char st_status;
 
@@ -651,7 +648,7 @@
         hal->jni_cb->stereo_status_cb(false);
 }
 
-static void hci_ev_rds_lock_status(char *buff)
+static void hci_ev_rds_lock_status(uint8_t buff[])
 {
     char rds_status;
 
@@ -668,7 +665,7 @@
         hal->jni_cb->rds_avail_status_cb(false);
 }
 
-static inline void hci_ev_program_service(char *buff)
+static inline void hci_ev_program_service(uint8_t buff[])
 {
     int len;
     char *data;
@@ -694,7 +691,7 @@
     free(data);
 }
 
-static inline void hci_ev_radio_text(char *buff)
+static inline void hci_ev_radio_text(uint8_t buff[])
 {
     int len = 0;
     char *data;
@@ -729,7 +726,7 @@
     free(data);
 }
 
-static void hci_ev_af_list(char *buff)
+static void hci_ev_af_list(uint8_t buff[])
 {
     struct hci_ev_af_list ev;
 
@@ -746,10 +743,10 @@
     }
     memcpy(&ev.af_list[0], &buff[AF_LIST_OFFSET],
                                         ev.af_size * sizeof(int));
-    hal->jni_cb->af_list_update_cb(&ev);
+    hal->jni_cb->af_list_update_cb((uint16_t *)&ev);
 }
 
-static inline void hci_ev_search_compl(char *buff)
+static inline void hci_ev_search_compl(uint8_t buff[])
 {
     if (buff == NULL) {
         ALOGE("%s:%s,buffer is null\n", LOG_TAG, __func__);
@@ -759,7 +756,7 @@
     hal->jni_cb->seek_cmpl_cb(hal->radio->fm_st_rsp.station_rsp.station_freq);
 }
 
-static inline void hci_ev_srch_st_list_compl(char *buff)
+static inline void hci_ev_srch_st_list_compl(uint8_t buff[])
 {
     struct hci_ev_srch_list_compl *ev ;
     int cnt;
@@ -795,15 +792,14 @@
     }
 
     len = ev->num_stations_found * 2 + sizeof(ev->num_stations_found);
-    hal->jni_cb->srch_list_cb((char*)ev);
+    hal->jni_cb->srch_list_cb((uint16_t *)ev);
     free(ev);
 }
 
-static inline void hci_ev_rt_plus_id(char *buff)
+static inline void hci_ev_rt_plus_id(uint8_t buff[])
 {
     char *data = NULL;
     int len = 15;
-    unsigned short int agt;
 
     ALOGD("%s:%s: start", LOG_TAG, __func__);
     data = malloc(len);
@@ -815,18 +811,17 @@
        data[4] = buff[3];
 
       memcpy(&data[RDS_OFFSET], &buff[4], len-RDS_OFFSET);
-      ALOGD("%s:%s: RT+ ID grouptype=0x%x%x\n", LOG_TAG, __func__,data[4]);
+      ALOGD("%s:%s: RT+ ID grouptype=0x%x\n", LOG_TAG, __func__,data[4]);
       free(data);
     } else {
         ALOGE("%s:memory allocation failed\n", LOG_TAG);
     }
 }
 
-static void hci_ev_rt_plus_tag(char *buff)
+static void hci_ev_rt_plus_tag(uint8_t buff[])
 {
     char *data = NULL;
     int len = 15;
-    unsigned short int agt;
 
     ALOGD("%s:%s: start", LOG_TAG, __func__);
     data = malloc(len);
@@ -846,7 +841,7 @@
      }
 }
 
-static void  hci_ev_ext_country_code(char *buff)
+static void  hci_ev_ext_country_code(uint8_t buff[])
 {
     char *data = NULL;
     int len = ECC_EVENT_BUFSIZE;
@@ -884,7 +879,7 @@
     }
 }
 
-static void hci_ev_hw_error(char *buff)
+static void hci_ev_hw_error()
 {
    ALOGE("%s:%s: start", LOG_TAG, __func__);
    fm_hci_close(hal->private_data);
@@ -939,7 +934,7 @@
     }
 }
 
-static void hci_ev_raw_rds_group_data(char *buff)
+static void hci_ev_raw_rds_group_data(uint8_t buff[])
 {
     unsigned char blocknum, index;
     struct rds_grp_data temp;
@@ -1008,7 +1003,7 @@
         }
     } else {
         carrier = gtc;
-        if ((carrier == rt_plus_carrier)) {
+        if (carrier == rt_plus_carrier) {
          //    hci_ev_rt_plus(temp);
         }
         else if (carrier == ert_carrier) {
@@ -1034,7 +1029,7 @@
     case HCI_EV_SEARCH_PROGRESS:
     case HCI_EV_SEARCH_RDS_PROGRESS:
     case HCI_EV_SEARCH_LIST_PROGRESS:
-        hci_ev_search_next(((struct fm_event_header_t *)evt_buf)->params);
+        hci_ev_search_next();
         break;
     case HCI_EV_STEREO_STATUS:
         hci_ev_stereo_status(((struct fm_event_header_t *)evt_buf)->params);
@@ -1081,7 +1076,7 @@
         hci_ev_ext_country_code(((struct fm_event_header_t *)evt_buf)->params);
         break;
     case HCI_EV_HW_ERR_EVENT:
-        hci_ev_hw_error(((struct fm_event_header_t *)evt_buf)->params);
+        hci_ev_hw_error();
         break;
     default:
         break;
@@ -1089,18 +1084,18 @@
 }
 
 /* 'evt_buf' contains the event received from Controller */
-int process_event(void *hal, unsigned char *evt_buf)
+int process_event(unsigned char *evt_buf)
 {
     ALOGI("%s: %s: Received event notification from FM-HCI thread. EVT CODE: %d ",
                             LOG_TAG,  __func__, ((struct fm_event_header_t *)evt_buf)->evt_code);
-    radio_hci_event_packet(evt_buf);
+    radio_hci_event_packet((char*)evt_buf);
     return 0;
 }
 
 int fm_hci_close_done()
 {
     ALOGI("fm_hci_close_done");
-    fm_hal_callbacks_t *ptr = NULL;
+    const fm_hal_callbacks_t *ptr = NULL;
 
     pthread_mutex_lock(&hal_lock);
     if(hal != NULL){
@@ -1222,7 +1217,7 @@
 {
     int ret = FM_HC_STATUS_FAIL;
     struct timespec ts;
-    struct hci_fm_default_data_read_req *rd;
+    struct hci_fm_def_data_rd_req *rd;
 
     pthread_mutex_lock(&(hal->cmd_lock));
     hal->set_cmd_sent = true;
@@ -1244,7 +1239,7 @@
         case HCI_FM_HELIUM_AF_ALGO:
         case HCI_FM_HELIUM_AF_SINR_GD_CH_TH:
         case HCI_FM_HELIUM_AF_SINR_TH:
-            rd = (struct hci_fm_default_data_read_req *) cmd_param;
+            rd = (struct hci_fm_def_data_rd_req *) cmd_param;
             ret = hci_fm_default_data_read_req(rd);
             break;
         case HCI_FM_HELIUM_BLEND_SINRHI:
@@ -1278,9 +1273,9 @@
     fm_hci_close_done
 };
 
-int hal_init(fm_hal_callbacks_t *cb)
+int hal_init(const fm_hal_callbacks_t *cb)
 {
-    int ret = -FM_HC_STATUS_FAIL, i;
+    int ret = -FM_HC_STATUS_FAIL;
     fm_hci_hal_t hci_hal;
     struct timespec ts;
 
@@ -1365,7 +1360,6 @@
     int saved_val;
     char temp_val = 0;
     unsigned int rds_grps_proc = 0;
-    char *data;
     struct hci_fm_def_data_wr_req def_data_wrt;
     struct hci_fm_def_data_rd_req def_data_rd;
 
diff --git a/helium/radio_helium_hal_cmds.c b/helium/radio_helium_hal_cmds.c
index a8fc305..e4f3606 100644
--- a/helium/radio_helium_hal_cmds.c
+++ b/helium/radio_helium_hal_cmds.c
@@ -36,6 +36,7 @@
 #include "radio-helium.h"
 #include "fm_hci_api.h"
 #include <dlfcn.h>
+#undef LOG_TAG
 #define LOG_TAG "radio_helium"
 extern struct fm_hal_t *hal;
 
@@ -204,10 +205,6 @@
 {
     uint16_t opcode = 0;
 
-    if (th == NULL) {
-        ALOGE("%s:Threshold value NULL", LOG_TAG);
-        return -EINVAL;
-    }
     opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ,
                                HCI_OCF_FM_SET_SIGNAL_THRESHOLD);
     return send_fm_cmd_pkt(opcode, sizeof(th), &th);
