Merge "FM: Fix band sweep test not working"
diff --git a/Android.mk b/Android.mk
index 53064ac..7ba73d6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -15,4 +15,6 @@
 include $(LOCAL_PATH)/jni/Android.mk
 LOCAL_PATH := $(LOCAL_DIR_PATH)
 include $(LOCAL_PATH)/fmapp/Android.mk
+LOCAL_PATH := $(LOCAL_DIR_PATH)
+include $(LOCAL_PATH)/fmapp2/Android.mk
 endif # is-vendor-board-platform
diff --git a/fmapp/res/layout-land-finger-800x480/fmradio.xml b/fmapp/res/layout-normal-land-finger/fmradio.xml
similarity index 70%
rename from fmapp/res/layout-land-finger-800x480/fmradio.xml
rename to fmapp/res/layout-normal-land-finger/fmradio.xml
index f2289fd..939dcc5 100644
--- a/fmapp/res/layout-land-finger-800x480/fmradio.xml
+++ b/fmapp/res/layout-normal-land-finger/fmradio.xml
@@ -26,28 +26,35 @@
  * 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"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
-    android:layout_height="wrap_content">
+    android:orientation="horizontal"
+    android:layout_height="fill_parent">
 
     <!-- This LinearLayout contains Station Information display and the function buttons -->
-    <RelativeLayout android:id="@+id/station_info_wrapper_layout"
+    <LinearLayout android:id="@+id/station_info_wrapper_layout"
         android:background="@drawable/station_border"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content">
+        android:orientation="vertical"
+        android:layout_weight="0.6"
+        android:layout_width="0dp"
+        android:layout_height="fill_parent">
 
         <include layout="@layout/station_info" />
 
-     </RelativeLayout>
+     </LinearLayout>
 
-     <RelativeLayout android:id="@+id/navigate_wrapper_layout"
-         android:layout_width="fill_parent"
-         android:layout_height="wrap_content"
-         android:layout_below="@id/station_info_wrapper_layout">
+     <LinearLayout android:id="@+id/navigate_wrapper_layout"
+         android:layout_height="fill_parent"
+         android:layout_weight="0.4"
+         android:layout_width="0dp"
+         android:orientation="vertical"
+         android:layout_alignTop="@id/station_info_wrapper_layout"
+         android:layout_alignBottom="@id/station_info_wrapper_layout"
+         android:layout_toRightOf="@id/station_info_wrapper_layout">
 
          <!-- Layout contains the Next/Previous Presets and Tune buttons and status msg text-->
          <include layout="@layout/navigate"/>
 
-     </RelativeLayout>
+     </LinearLayout>
 
-</RelativeLayout>
+</LinearLayout>
diff --git a/fmapp/res/layout-land-finger-800x480/fmtransmitter.xml b/fmapp/res/layout-normal-land-finger/fmtransmitter.xml
similarity index 100%
rename from fmapp/res/layout-land-finger-800x480/fmtransmitter.xml
rename to fmapp/res/layout-normal-land-finger/fmtransmitter.xml
diff --git a/fmapp/res/layout-land-finger-800x480/navigate.xml b/fmapp/res/layout-normal-land-finger/navigate.xml
similarity index 75%
rename from fmapp/res/layout-land-finger-800x480/navigate.xml
rename to fmapp/res/layout-normal-land-finger/navigate.xml
index fab276a..ddc650b 100644
--- a/fmapp/res/layout-land-finger-800x480/navigate.xml
+++ b/fmapp/res/layout-normal-land-finger/navigate.xml
@@ -37,37 +37,25 @@
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentLeft="true"
-             android:textSize="16dip"
+             android:textSize="16dp"
              android:textStyle="bold"
              android:text="@string/default_record"/>
 
-         <ImageButton android:id="@+id/btn_silent"
-             android:src="@drawable/ic_silent_mode_off"
-             android:layout_width="wrap_content"
-             android:layout_height="wrap_content"
-             android:layout_toLeftOf="@id/btn_presets_list"/>
-
          <Button android:id="@+id/btn_presets_list"
              android:text= "@string/default_preset_list_name"
-             android:textSize="24dip"
+             android:textSize="24dp"
              android:singleLine="true"
              android:textStyle="bold"
              android:layout_centerHorizontal="true"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" />
 
-         <ImageButton android:id="@+id/btn_onoff"
-             android:layout_width="wrap_content"
-             android:layout_height="wrap_content"
-             android:layout_toRightOf="@id/btn_presets_list"
-             android:src="@drawable/ic_btn_onoff"/>
-
          <TextView android:id="@+id/sleep_msg_tv"
              android:textAppearance="?android:attr/textAppearanceMedium"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentRight="true"
-             android:textSize="16dip"
+             android:textSize="16dp"
              android:textStyle="bold"
              androidtext="@string/default_sleep"/>
 
@@ -77,76 +65,97 @@
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_below="@id/message_row"
-         android:layout_marginTop="1dip"
-         android:layout_marginBottom="5dip">
+         android:layout_marginTop="1dp"
+         android:layout_marginBottom="5dp">
 
          <RelativeLayout android:id="@+id/presets_upper_layout1"
              android:layout_width="wrap_content"
-             android:layout_centerInParent="true"
              android:layout_height="wrap_content">
 
              <Button android:id="@+id/presets_button_1"
                  android:text="@string/default_station"
-                 android:layout_marginLeft="10dip"
-                 android:layout_marginRight="25dip"
-                 android:textSize="24dip"
+                 android:textSize="24dp"
+                 android:layout_marginRight="10dp"
                  android:singleLine="true"
-                 android:layout_width="wrap_content"
+                 android:layout_width="75dp"
                  android:layout_height="wrap_content" />
 
              <Button android:id="@+id/presets_button_2"
                  android:text="@string/default_station"
-                 android:layout_marginRight="25dip"
-                 android:textSize="24dip"
+                 android:layout_marginRight="10dp"
+                 android:textSize="24dp"
                  android:singleLine="true"
                  android:layout_alignTop="@id/presets_button_1"
                  android:layout_alignBottom="@id/presets_button_1"
                  android:layout_toRightOf="@id/presets_button_1"
-                 android:layout_width="wrap_content"
+                 android:layout_width="75dp"
                  android:layout_height="wrap_content" />
 
              <Button android:id="@+id/presets_button_3"
                  android:text="@string/default_station"
-                 android:layout_marginRight="25dip"
-                 android:textSize="24dip"
+                 android:textSize="24dp"
                  android:singleLine="true"
                  android:layout_alignTop="@id/presets_button_2"
                  android:layout_alignBottom="@id/presets_button_2"
                  android:layout_toRightOf="@id/presets_button_2"
-                 android:layout_width="wrap_content"
+                 android:layout_width="75dp"
                  android:layout_height="wrap_content" />
 
+          </RelativeLayout>
+
+          <RelativeLayout android:id="@+id/presets_upper_layout2"
+            android:layout_width="wrap_content"
+            android:layout_below="@id/presets_upper_layout1"
+            android:layout_height="wrap_content">
+
              <Button android:id="@+id/presets_button_4"
                  android:text="@string/default_blank"
-                 android:layout_marginRight="25dip"
-                 android:textSize="24dip"
+                 android:layout_marginRight="10dp"
+                 android:textSize="24dp"
                  android:singleLine="true"
-                 android:layout_alignTop="@id/presets_button_3"
-                 android:layout_alignBottom="@id/presets_button_3"
-                 android:layout_toRightOf="@id/presets_button_3"
-                 android:layout_width="wrap_content"
+                 android:layout_width="75dp"
                  android:layout_height="wrap_content"/>
 
              <Button android:id="@+id/presets_button_5"
                  android:text="@string/default_blank"
-                 android:layout_marginRight="25dip"
-                 android:textSize="24dip"
+                 android:layout_marginRight="10dp"
+                 android:textSize="24dp"
                  android:singleLine="true"
                  android:layout_alignTop="@id/presets_button_4"
                  android:layout_alignBottom="@id/presets_button_4"
                  android:layout_toRightOf="@id/presets_button_4"
-                 android:layout_width="wrap_content"
+                 android:layout_width="75dp"
                  android:layout_height="wrap_content" />
 
              <ImageButton android:id="@+id/btn_preset_page"
                  android:src="@drawable/ic_btn_forward"
-                 android:layout_marginRight="10dip"
                  android:layout_alignTop="@id/presets_button_5"
                  android:layout_alignBottom="@id/presets_button_5"
                  android:layout_toRightOf="@id/presets_button_5"
-                 android:layout_width="wrap_content"
+                 android:layout_width="75dp"
                  android:layout_height="wrap_content"/>
 
          </RelativeLayout>
+
+         <RelativeLayout android:id="@+id/silent_on_off_layout"
+             android:layout_width="wrap_content"
+             android:layout_centerHorizontal="true"
+             android:layout_below="@id/presets_upper_layout2"
+             android:layout_height="wrap_content">
+
+             <ImageButton android:id="@+id/btn_silent"
+                 android:src="@drawable/ic_silent_mode_off"
+                 android:layout_width="wrap_content"
+                 android:layout_height="wrap_content"/>
+
+             <ImageButton android:id="@+id/btn_onoff"
+                 android:layout_width="wrap_content"
+                 android:layout_height="wrap_content"
+                 android:layout_toRightOf="@id/btn_silent"
+                 android:src="@drawable/ic_btn_onoff"/>
+
+         </RelativeLayout>
+
      </RelativeLayout>
+
 </merge>
diff --git a/fmapp/res/layout-land-finger-800x480/station_info.xml b/fmapp/res/layout-normal-land-finger/station_info.xml
similarity index 100%
rename from fmapp/res/layout-land-finger-800x480/station_info.xml
rename to fmapp/res/layout-normal-land-finger/station_info.xml
diff --git a/fmapp/res/layout-800x480/fmradio.xml b/fmapp/res/layout-normal/fmradio.xml
similarity index 97%
rename from fmapp/res/layout-800x480/fmradio.xml
rename to fmapp/res/layout-normal/fmradio.xml
index b3dbccb..5b9197c 100644
--- a/fmapp/res/layout-800x480/fmradio.xml
+++ b/fmapp/res/layout-normal/fmradio.xml
@@ -30,7 +30,7 @@
     android:id="@+id/fmradio"
     android:background="@drawable/application_border"
     android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
+    android:layout_height="wrap_content">
 
     <!-- This LinearLayout contains Station Information display and the function buttons -->
 
@@ -72,7 +72,7 @@
     <RelativeLayout android:id="@+id/layout_on_off"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginTop="5dp"
+        android:layout_marginTop="1dp"
         android:layout_centerInParent="true"
         android:layout_below="@id/on_off_separator_layout">
 
diff --git a/fmapp/res/layout-800x480/fmtags.xml b/fmapp/res/layout-normal/fmtags.xml
similarity index 100%
copy from fmapp/res/layout-800x480/fmtags.xml
copy to fmapp/res/layout-normal/fmtags.xml
diff --git a/fmapp/res/layout-800x480/fmtransmitter.xml b/fmapp/res/layout-normal/fmtransmitter.xml
similarity index 100%
rename from fmapp/res/layout-800x480/fmtransmitter.xml
rename to fmapp/res/layout-normal/fmtransmitter.xml
diff --git a/fmapp/res/layout-normal/navigate.xml b/fmapp/res/layout-normal/navigate.xml
new file mode 100644
index 0000000..bd8cdea
--- /dev/null
+++ b/fmapp/res/layout-normal/navigate.xml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+  <RelativeLayout android:id="@+id/message_row"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="1dp"
+        android:paddingTop="1dp"
+        android:paddingBottom="1dp">
+
+     <TextView android:id="@+id/record_msg_tv"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:textSize="15dp"
+        android:textStyle="bold"
+        android:gravity="fill"
+        android:text="@string/default_record" />
+
+     <Button android:id="@+id/btn_presets_list"
+        android:text="@string/default_preset_list_name"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:textSize="24dp"
+        android:textStyle="bold"
+        android:singleLine="true"
+        android:layout_centerHorizontal="true"
+        android:layout_alignParentTop="true"
+        android:layout_gravity="center"
+        android:layout_marginLeft="10dp"
+        android:layout_marginRight="10dp"
+        android:layout_marginBottom="10dp"
+        android:gravity="fill"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+     <TextView android:id="@+id/sleep_msg_tv"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentRight="true"
+        android:layout_alignBaseline="@+id/btn_presets_list"
+        android:textSize="15dp"
+        android:textStyle="bold"
+        android:gravity="fill"
+        android:text="@string/default_sleep" />
+  </RelativeLayout>
+
+  <RelativeLayout android:id="@+id/presets_layout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/message_row"
+        android:layout_centerInParent="true">
+
+   <!--  Upper Presets -->
+   <RelativeLayout android:id="@+id/presets_upper_layout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="top">
+
+     <Button android:id="@+id/presets_button_1"
+        android:text="@string/default_blank"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="24dp"
+        android:singleLine="true"
+        android:gravity="fill"
+        android:layout_width="85dp"
+        android:layout_height="wrap_content" />
+
+     <Button android:id="@+id/presets_button_2"
+        android:text="@string/default_blank"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="24dp"
+        android:singleLine="true"
+        android:layout_toRightOf="@id/presets_button_1"
+        android:layout_alignTop="@id/presets_button_1"
+        android:layout_alignBottom="@id/presets_button_1"
+        android:gravity="fill"
+        android:layout_width="85dp"
+        android:layout_height="wrap_content" />
+
+     <Button android:id="@+id/presets_button_3"
+        android:text="@string/default_blank"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="24dp"
+        android:singleLine="true"
+        android:layout_toRightOf="@id/presets_button_2"
+        android:layout_alignTop="@id/presets_button_2"
+        android:layout_alignBottom="@id/presets_button_2"
+        android:layout_width="85dp"
+        android:gravity="fill"
+        android:layout_height="wrap_content" />
+  </RelativeLayout>
+
+<!--  Lower Presets -->
+  <RelativeLayout android:id="@+id/presets_lower_layout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/presets_upper_layout"
+        android:layout_alignLeft="@id/presets_upper_layout"
+        android:layout_alignRight="@id/presets_upper_layout">
+
+     <Button android:id="@+id/presets_button_4"
+        android:text="@string/default_blank"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="24dp"
+        android:singleLine="true"
+        android:layout_width="85dp"
+        android:gravity="fill"
+        android:layout_alignLeft="@id/presets_button_1"
+        android:layout_alignRight="@id/presets_button_1"
+        android:layout_height="wrap_content" />
+
+     <Button android:id="@+id/presets_button_5"
+        android:text="@string/default_blank"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="24dp"
+        android:singleLine="true"
+        android:layout_toRightOf="@id/presets_button_4"
+        android:layout_alignTop="@id/presets_button_4"
+        android:layout_alignBottom="@id/presets_button_4"
+        android:layout_alignLeft="@id/presets_button_2"
+        android:layout_alignRight="@id/presets_button_2"
+        android:gravity="fill"
+        android:layout_width="85dp"
+        android:layout_height="wrap_content" />
+
+     <ImageButton android:id="@+id/btn_preset_page"
+        android:src="@drawable/ic_btn_forward"
+        android:layout_toRightOf="@id/presets_button_5"
+        android:layout_alignTop="@id/presets_button_5"
+        android:layout_alignBottom="@id/presets_button_5"
+        android:layout_alignLeft="@id/presets_button_3"
+        android:layout_alignRight="@id/presets_button_3"
+        android:gravity="fill"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+   </RelativeLayout>
+ </RelativeLayout>
+
+ <RelativeLayout android:id="@+id/scanning_stoplayout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        android:gravity="center">
+
+    <Button android:id="@+id/btn_scanning_stop"
+        android:clickable="true"
+        android:text="@string/stop_scanning"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="32dp"
+        android:singleLine="true"
+        android:padding="20dp"
+        android:gravity="fill"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+ </RelativeLayout>
+
+</merge>
diff --git a/fmapp/res/layout-800x480/station_info.xml b/fmapp/res/layout-normal/station_info.xml
similarity index 90%
rename from fmapp/res/layout-800x480/station_info.xml
rename to fmapp/res/layout-normal/station_info.xml
index 475d42a..e47f823 100644
--- a/fmapp/res/layout-800x480/station_info.xml
+++ b/fmapp/res/layout-normal/station_info.xml
@@ -44,7 +44,7 @@
           android:src="@drawable/ic_signal_2"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
-          android:paddingLeft="5dip"
+          android:paddingLeft="5dp"
           android:layout_alignParentTop="true"
           android:layout_alignParentLeft="true"/>
 
@@ -55,7 +55,7 @@
           android:layout_alignParentTop="true"
           android:layout_centerHorizontal="true"
           android:layout_alignBaseline="@id/signal_level"
-          android:textSize="16dip"
+          android:textSize="16dp"
           android:singleLine="true"
           android:textStyle="bold"
           android:text="@string/prog_service_string" />
@@ -64,11 +64,11 @@
          android:textAppearance="?android:attr/textAppearanceMedium"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
-         android:paddingRight="5dip"
+         android:paddingRight="5dp"
          android:layout_alignParentTop="true"
          android:layout_alignParentRight="true"
          android:layout_alignBaseline="@id/signal_level"
-         android:textSize="16dip"
+         android:textSize="16dp"
          android:text="@string/default_audio" />
 
     </RelativeLayout>
@@ -82,7 +82,7 @@
          android:textAppearance="?android:attr/textAppearanceMedium"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
-         android:textSize="16dip"
+         android:textSize="16dp"
          android:layout_centerInParent="true"
          android:text="@string/station_id_string" />
 
@@ -98,7 +98,7 @@
         android:textAppearance="?android:attr/textAppearanceLarge"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textSize="50dip"
+        android:textSize="50dp"
         android:layout_centerHorizontal="true"
         android:layout_centerVertical="true"
         android:text="@string/frequency_string"/>
@@ -107,8 +107,8 @@
         android:clickable="true"
         android:focusable="true"
         android:layout_width="wrap_content"
-        android:layout_height="100dip"
-        android:paddingLeft="2dip"
+        android:layout_height="100dp"
+        android:paddingLeft="2dp"
         android:layout_alignParentLeft="true"
         android:visibility="visible"
         android:layout_alignWithParentIfMissing="true"
@@ -118,8 +118,8 @@
         android:clickable="true"
         android:focusable="true"
         android:layout_width="wrap_content"
-        android:layout_height="100dip"
-        android:paddingRight="2dip"
+        android:layout_height="100dp"
+        android:paddingRight="2dp"
         android:layout_alignParentRight="true"
         android:visibility="visible"
         android:layout_alignWithParentIfMissing="true"
@@ -137,7 +137,7 @@
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textSize="16dip"
+        android:textSize="16dp"
         android:layout_centerInParent="true"
         android:text="@string/pty_string" />
     </RelativeLayout>
@@ -154,12 +154,12 @@
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textSize="16dip"
+        android:textSize="16dp"
         android:singleLine="true"
         android:textStyle="bold"
-        android:paddingLeft="2dip"
-        android:paddingRight="2dip"
-        android:paddingBottom="5dip"
+        android:paddingLeft="2dp"
+        android:paddingRight="2dp"
+        android:paddingBottom="5dp"
         android:gravity="center"
         android:text="@string/radio_text_string" />
 
@@ -167,12 +167,12 @@
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:textAppearance="?android:attr/textAppearanceMedium"
-         android:textSize="16dip"
+         android:textSize="16dp"
          android:singleLine="true"
          android:textStyle="bold"
-         android:paddingLeft="2dip"
-         android:paddingRight="2dip"
-         android:paddingBottom="5dip"
+         android:paddingLeft="2dp"
+         android:paddingRight="2dp"
+         android:paddingBottom="5dp"
          android:layout_below="@id/radio_text_tv"
          android:gravity="center_horizontal"
          android:text="@string/eradio_text_string"/>
diff --git a/fmapp/res/layout-land-finger/fmradio.xml b/fmapp/res/layout-small-land-finger/fmradio.xml
similarity index 100%
rename from fmapp/res/layout-land-finger/fmradio.xml
rename to fmapp/res/layout-small-land-finger/fmradio.xml
diff --git a/fmapp/res/layout-land-finger/fmtransmitter.xml b/fmapp/res/layout-small-land-finger/fmtransmitter.xml
similarity index 100%
rename from fmapp/res/layout-land-finger/fmtransmitter.xml
rename to fmapp/res/layout-small-land-finger/fmtransmitter.xml
diff --git a/fmapp/res/layout-land-finger/navigate.xml b/fmapp/res/layout-small-land-finger/navigate.xml
similarity index 100%
copy from fmapp/res/layout-land-finger/navigate.xml
copy to fmapp/res/layout-small-land-finger/navigate.xml
diff --git a/fmapp/res/layout-land-finger/station_info.xml b/fmapp/res/layout-small-land-finger/station_info.xml
similarity index 100%
rename from fmapp/res/layout-land-finger/station_info.xml
rename to fmapp/res/layout-small-land-finger/station_info.xml
diff --git a/fmapp/res/layout/alert_dialog_list.xml b/fmapp/res/layout-small/alert_dialog_list.xml
similarity index 100%
rename from fmapp/res/layout/alert_dialog_list.xml
rename to fmapp/res/layout-small/alert_dialog_list.xml
diff --git a/fmapp/res/layout/alert_dialog_text_entry.xml b/fmapp/res/layout-small/alert_dialog_text_entry.xml
similarity index 100%
rename from fmapp/res/layout/alert_dialog_text_entry.xml
rename to fmapp/res/layout-small/alert_dialog_text_entry.xml
diff --git a/fmapp/res/layout/fmradio.xml b/fmapp/res/layout-small/fmradio.xml
similarity index 87%
rename from fmapp/res/layout/fmradio.xml
rename to fmapp/res/layout-small/fmradio.xml
index e67bde1..e929965 100644
--- a/fmapp/res/layout/fmradio.xml
+++ b/fmapp/res/layout-small/fmradio.xml
@@ -39,7 +39,7 @@
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
-        android:layout_marginTop="5dip"
+        android:layout_marginTop="5dp"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true">
 
@@ -67,8 +67,8 @@
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:layout_gravity="center"
-        android:layout_marginTop="2dip"
-        android:layout_marginBottom="2dip"
+        android:layout_marginTop="2dp"
+        android:layout_marginBottom="2dp"
         android:layout_alignParentLeft="true"
         android:layout_alignParentBottom="true"
         android:layout_weight="0"
@@ -76,23 +76,23 @@
 
         <ImageButton android:id="@+id/btn_silent"
             android:src="@drawable/ic_silent_mode_off"
-            android:layout_marginLeft="10dip"
-            android:layout_marginRight="20dip"
-            android:layout_width="100dip"
-            android:layout_height="50dip"/>
+            android:layout_marginLeft="10dp"
+            android:layout_marginRight="20dp"
+            android:layout_width="100dp"
+            android:layout_height="50dp"/>
 
         <ImageButton android:id="@+id/btn_onoff"
             android:src="@drawable/ic_btn_onoff"
-            android:layout_marginLeft="20dip"
-            android:layout_marginRight="10dip"
-            android:layout_width="100dip"
-            android:layout_height="50dip"/>
+            android:layout_marginLeft="20dp"
+            android:layout_marginRight="10dp"
+            android:layout_width="100dp"
+            android:layout_height="50dp"/>
 
     </LinearLayout>
 
     <View
         android:layout_width="fill_parent"
-        android:layout_height="1dip"
+        android:layout_height="1dp"
         android:background="#ffffffff"
         android:layout_above="@+id/layout_on_off"/>
 
diff --git a/fmapp/res/layout/fmstats.xml b/fmapp/res/layout-small/fmstats.xml
similarity index 100%
rename from fmapp/res/layout/fmstats.xml
rename to fmapp/res/layout-small/fmstats.xml
diff --git a/fmapp/res/layout-800x480/fmtags.xml b/fmapp/res/layout-small/fmtags.xml
similarity index 100%
copy from fmapp/res/layout-800x480/fmtags.xml
copy to fmapp/res/layout-small/fmtags.xml
diff --git a/fmapp/res/layout/fmtransmitter.xml b/fmapp/res/layout-small/fmtransmitter.xml
similarity index 100%
rename from fmapp/res/layout/fmtransmitter.xml
rename to fmapp/res/layout-small/fmtransmitter.xml
diff --git a/fmapp/res/layout/frequency_picker.xml b/fmapp/res/layout-small/frequency_picker.xml
similarity index 100%
rename from fmapp/res/layout/frequency_picker.xml
rename to fmapp/res/layout-small/frequency_picker.xml
diff --git a/fmapp/res/layout/frequency_picker_dialog.xml b/fmapp/res/layout-small/frequency_picker_dialog.xml
similarity index 100%
rename from fmapp/res/layout/frequency_picker_dialog.xml
rename to fmapp/res/layout-small/frequency_picker_dialog.xml
diff --git a/fmapp/res/layout/navigate.xml b/fmapp/res/layout-small/navigate.xml
similarity index 80%
copy from fmapp/res/layout/navigate.xml
copy to fmapp/res/layout-small/navigate.xml
index 30cff7e..8d7a603 100644
--- a/fmapp/res/layout/navigate.xml
+++ b/fmapp/res/layout-small/navigate.xml
@@ -31,7 +31,7 @@
     <RelativeLayout android:id="@+id/message_row"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="5dip"
+        android:layout_marginTop="5dp"
         android:orientation="horizontal">
 
         <TextView android:id="@+id/record_msg_tv"
@@ -40,7 +40,7 @@
             android:layout_height="wrap_content"
             android:layout_alignParentTop="true"
             android:layout_alignParentLeft="true"
-            android:textSize="14dip"
+            android:textSize="14dp"
             android:textStyle="bold"
             android:text="@string/default_record"/>
 
@@ -51,10 +51,10 @@
             android:layout_centerHorizontal="true"
             android:layout_alignParentTop="true"
             android:layout_gravity="center"
-            android:layout_marginLeft="10dip"
-            android:layout_marginRight="10dip"
-            android:layout_width="140dip"
-            android:layout_height="45dip" />
+            android:layout_marginLeft="10dp"
+            android:layout_marginRight="10dp"
+            android:layout_width="140dp"
+            android:layout_height="45dp" />
 
         <TextView android:id="@+id/sleep_msg_tv"
            android:textAppearance="?android:attr/textAppearanceMedium"
@@ -63,7 +63,7 @@
            android:layout_alignParentTop="true"
            android:layout_alignParentRight="true"
            android:layout_alignBaseline="@+id/btn_presets_list"
-           android:textSize="14dip"
+           android:textSize="14dp"
            android:textStyle="bold"
            android:text="@string/default_sleep" />
 
@@ -81,27 +81,27 @@
          android:layout_height="wrap_content"
          android:orientation="horizontal"
          android:layout_gravity="center"
-         android:layout_marginBottom="5dip"
+         android:layout_marginBottom="5dp"
          android:gravity="center_horizontal">
 
          <Button android:id="@+id/presets_button_1"
              android:text="@string/default_station"
              android:layout_marginLeft="10dip"
-             android:layout_width="90dip"
-             android:layout_height="55dip" />
+             android:layout_width="90dp"
+             android:layout_height="55dp" />
 
          <Button android:id="@+id/presets_button_2"
              android:text="@string/default_station"
-             android:layout_marginLeft="10dip"
-             android:layout_marginRight="10dip"
-             android:layout_width="90dip"
-             android:layout_height="55dip" />
+             android:layout_marginLeft="10dp"
+             android:layout_marginRight="10dp"
+             android:layout_width="90dp"
+             android:layout_height="55dp" />
 
          <Button android:id="@+id/presets_button_3"
              android:text="@string/default_station"
-             android:layout_marginRight="10dip"
-             android:layout_width="90dip"
-             android:layout_height="55dip"
+             android:layout_marginRight="10dp"
+             android:layout_width="90dp"
+             android:layout_height="55dp"
              android:visibility="visible" />
 
      </LinearLayout>
@@ -112,27 +112,27 @@
          android:layout_height="wrap_content"
          android:orientation="horizontal"
          android:layout_gravity="center"
-         android:layout_marginBottom="5dip"
+         android:layout_marginBottom="5dp"
          android:gravity="center_horizontal">
 
          <Button android:id="@+id/presets_button_4"
              android:text="@string/default_blank"
-             android:layout_marginLeft="10dip"
-             android:layout_width="90dip"
-             android:layout_height="55dip" />
+             android:layout_marginLeft="10dp"
+             android:layout_width="90dp"
+             android:layout_height="55dp" />
 
          <Button android:id="@+id/presets_button_5"
              android:text="@string/default_blank"
-             android:layout_marginLeft="10dip"
-             android:layout_marginRight="10dip"
-             android:layout_width="90dip"
-             android:layout_height="55dip" />
+             android:layout_marginLeft="10dp"
+             android:layout_marginRight="10dp"
+             android:layout_width="90dp"
+             android:layout_height="55dp" />
 
          <ImageButton android:id="@+id/btn_preset_page"
              android:src="@drawable/preset_page_button"
-             android:layout_marginRight="10dip"
-             android:layout_width="90dip"
-             android:layout_height="55dip"
+             android:layout_marginRight="10dp"
+             android:layout_width="90dp"
+             android:layout_height="55dp"
              android:visibility="visible" />
 
      </LinearLayout>
@@ -149,7 +149,7 @@
           android:clickable="true"
           android:text="@string/stop_scanning"
           android:singleLine="true"
-          android:padding="20dip"
+          android:padding="20dp"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content" />
 
diff --git a/fmapp/res/layout/station_info.xml b/fmapp/res/layout-small/station_info.xml
similarity index 82%
rename from fmapp/res/layout/station_info.xml
rename to fmapp/res/layout-small/station_info.xml
index 876026a..0f3fce4 100644
--- a/fmapp/res/layout/station_info.xml
+++ b/fmapp/res/layout-small/station_info.xml
@@ -43,7 +43,7 @@
                 android:src="@drawable/ic_signal_2"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingLeft="5dip"
+                android:paddingLeft="5dp"
                 android:layout_alignParentTop="true"
                 android:layout_alignParentLeft="true"/>
 
@@ -54,7 +54,7 @@
                 android:layout_alignParentTop="true"
                 android:layout_centerHorizontal="true"
                 android:layout_alignBaseline="@id/signal_level"
-                android:textSize="20dip"
+                android:textSize="20dp"
                 android:singleLine="true"
                 android:textStyle="bold"
                 android:text="@string/prog_service_string"/>
@@ -63,11 +63,11 @@
                 android:textAppearance="?android:attr/textAppearanceSmall"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingRight="5dip"
+                android:paddingRight="5dp"
                 android:layout_alignParentTop="true"
                 android:layout_alignParentRight="true"
                 android:layout_alignBaseline="@id/signal_level"
-                android:textSize="14dip"
+                android:textSize="14dp"
                 android:text="@string/default_audio"/>
 
         </RelativeLayout>
@@ -76,8 +76,8 @@
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical"
-            android:paddingTop="5dip"
-            android:paddingBottom="5dip"
+            android:paddingTop="5dp"
+            android:paddingBottom="5dp"
             android:layout_alignWithParentIfMissing="true"
             android:gravity="center">
 
@@ -85,26 +85,26 @@
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:textSize="14dip"
-                android:paddingTop="2dip"
-                android:paddingRight="2dip"
-                android:paddingBottom="2dip"
-                android:paddingLeft="2dip"
+                android:textSize="14dp"
+                android:paddingTop="2dp"
+                android:paddingRight="2dp"
+                android:paddingBottom="2dp"
+                android:paddingLeft="2dp"
                 android:text="@string/station_id_string" />
 
             <RelativeLayout android:id="@+id/second_layout"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:layout_marginBottom="2dip"
-                android:layout_marginLeft="2dip"
-                android:layout_marginRight="2dip">
+                android:layout_marginTop="2dp"
+                android:layout_marginBottom="2dp"
+                android:layout_marginLeft="2dp"
+                android:layout_marginRight="2dp">
 
                 <TextView android:id="@+id/prog_frequency_tv"
                      android:textAppearance="?android:attr/textAppearanceLarge"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
-                     android:textSize="64dip"
+                     android:textSize="64dp"
                      android:layout_centerHorizontal="true"
                      android:text="@string/frequency_string"/>
 
@@ -112,8 +112,8 @@
                      android:clickable="true"
                      android:focusable="true"
                      android:layout_width="wrap_content"
-                     android:layout_height="100dip"
-                     android:paddingLeft="2dip"
+                     android:layout_height="100dp"
+                     android:paddingLeft="2dp"
                      android:layout_alignParentLeft="true"
                      android:visibility="visible"
                      android:layout_alignWithParentIfMissing="true"
@@ -123,8 +123,8 @@
                      android:clickable="true"
                      android:focusable="true"
                      android:layout_width="wrap_content"
-                     android:layout_height="100dip"
-                     android:paddingRight="2dip"
+                     android:layout_height="100dp"
+                     android:paddingRight="2dp"
                      android:layout_alignParentRight="true"
                      android:visibility="visible"
                      android:layout_alignWithParentIfMissing="true"
@@ -136,11 +136,11 @@
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:textSize="14dip"
-                android:paddingTop="2dip"
-                android:paddingRight="2dip"
-                android:paddingBottom="2dip"
-                android:paddingLeft="2dip"
+                android:textSize="14dp"
+                android:paddingTop="2dp"
+                android:paddingRight="2dp"
+                android:paddingBottom="2dp"
+                android:paddingLeft="2dp"
                 android:text="@string/pty_string" />
 
         </LinearLayout>
@@ -150,12 +150,12 @@
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="20dip"
+            android:textSize="20dp"
             android:singleLine="true"
             android:textStyle="bold"
-            android:paddingLeft="2dip"
-            android:paddingRight="2dip"
-            android:paddingBottom="5dip"
+            android:paddingLeft="2dp"
+            android:paddingRight="2dp"
+            android:paddingBottom="5dp"
             android:gravity="center_horizontal"
             android:text="@string/radio_text_string"/>
 
@@ -163,12 +163,12 @@
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="20dip"
+            android:textSize="20dp"
             android:singleLine="true"
             android:textStyle="bold"
-            android:paddingLeft="2dip"
-            android:paddingRight="2dip"
-            android:paddingBottom="5dip"
+            android:paddingLeft="2dp"
+            android:paddingRight="2dp"
+            android:paddingBottom="5dp"
             android:gravity="center_horizontal"
             android:text="@string/eradio_text_string"/>
     </LinearLayout>
diff --git a/fmapp/res/layout/statusbar.xml b/fmapp/res/layout-small/statusbar.xml
similarity index 100%
rename from fmapp/res/layout/statusbar.xml
rename to fmapp/res/layout-small/statusbar.xml
diff --git a/fmapp2/Android.mk b/fmapp2/Android.mk
new file mode 100644
index 0000000..3985572
--- /dev/null
+++ b/fmapp2/Android.mk
@@ -0,0 +1,25 @@
+ifeq ($(BOARD_HAVE_QCOM_FM),true)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src/com/caf/fmradio) \
+	src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl \
+	src/com/caf/fmradio/IFMRadioService.aidl \
+	src/com/caf/fmradio/IFMTransmitterServiceCallbacks.aidl \
+	src/com/caf/fmradio/IFMTransmitterService.aidl \
+
+
+ifeq ($(call is-android-codename-in-list,JELLY_BEAN ICECREAM_SANDWICH HONEYCOMB),true)
+LOCAL_SRC_FILES +=  $(call all-java-files-under, src/com/caf/hc_utils)
+else
+LOCAL_SRC_FILES +=  $(call all-java-files-under, src/com/caf/utils)
+endif
+LOCAL_PACKAGE_NAME := FM2
+LOCAL_CERTIFICATE := platform
+LOCAL_JNI_SHARED_LIBRARIES := libqcomfm_jni
+LOCAL_JAVA_LIBRARIES := qcom.fmradio
+
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/fmapp2/AndroidManifest.xml b/fmapp2/AndroidManifest.xml
new file mode 100644
index 0000000..4cef8c0
--- /dev/null
+++ b/fmapp2/AndroidManifest.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.caf.fmradio"
+    android:sharedUserId="android.uid.system" >
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
+
+    <application
+        android:icon="@drawable/ic_launcher_fmradio"
+        android:label="@string/app_name"
+        android:name=".FMAdapterApp">
+        <activity android:icon="@drawable/ic_launcher_fmradio"
+            android:name=".FMRadio"
+            android:label="@string/app_name"
+            android:clearTaskOnLaunch="true"
+            android:taskAffinity=""
+            android:launchMode="singleTop"
+            android:excludeFromRecents="true" >
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+            <intent-filter>
+                <action android:name="com.caf.fmradio.FMRADIO_ACTIVITY" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+
+        </activity>
+
+        <receiver android:name="com.caf.fmradio.FMMediaButtonIntentReceiver">
+            <intent-filter>
+                 <action android:name="android.intent.action.MEDIA_BUTTON" />
+            </intent-filter>
+        </receiver>
+
+        <activity android:name=".Settings"
+            android:label="@string/settings_menu">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+
+        </activity>
+
+        <activity android:icon="@drawable/ic_launcher_fm_tx"
+            android:name=".FMTransmitterActivity"
+            android:label="@string/tx_app_name"
+            android:clearTaskOnLaunch="true"
+            android:taskAffinity=""
+            android:excludeFromRecents="true">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+
+            <intent-filter>
+                <action android:name="com.caf.fmradio.FMTRANSMITTER_ACTIVITY" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+
+        </activity>
+
+        <receiver android:name="FMTransmitterConfigReceiver">
+
+            <intent-filter>
+                <action android:name="android.intent.action.BOOT_COMPLETED" />
+            </intent-filter>
+
+        </receiver>
+
+        <service android:name=".FMTransmitterService"
+            android:exported="true" />
+
+        <activity android:name=".FMStats"
+            android:label="@string/test_menu">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+
+        </activity>
+
+        <activity android:name=".FmTags"
+            android:label="@string/rt_plus_tags">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+
+        </activity>
+
+       <activity android:name=".StationListActivity"
+            android:label="@string/app_label_all_channels"
+            android:configChanges="orientation|keyboardHidden|screenSize|fontScale">
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+
+       </activity>
+
+       <service android:name=".FMRadioService"
+            android:exported="true" />
+
+    </application>
+
+</manifest>
diff --git a/fmapp2/fmtransmitter.xml b/fmapp2/fmtransmitter.xml
new file mode 100644
index 0000000..5e65620
--- /dev/null
+++ b/fmapp2/fmtransmitter.xml
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:orientation="vertical"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+
+	<!--
+		This LinearLayout contains Station Information display and the
+		function buttons
+	-->
+	<LinearLayout android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:layout_weight="1"
+		android:orientation="horizontal">
+
+		<LinearLayout android:background="@drawable/station_border"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:layout_weight="1"
+			android:orientation="vertical"
+			android:gravity="top|fill_vertical">
+
+			<RelativeLayout android:id="@+id/station_layout"
+				android:layout_width="fill_parent"
+				android:layout_height="fill_parent">
+
+				<!-- This included layout contains Station Information to display -->
+				<LinearLayout android:id="@+id/stationinfo_layout"
+					android:layout_width="fill_parent"
+					android:layout_height="wrap_content"
+					android:layout_marginTop="5px"
+					android:layout_marginLeft="5px"
+					android:layout_marginRight="5px"
+					android:orientation="vertical"
+					android:gravity="fill_vertical">
+
+					<LinearLayout android:id="@+id/station_frequency_row"
+						android:layout_width="fill_parent"
+						android:layout_height="wrap_content"
+						android:orientation="vertical"
+						android:paddingTop="25px"
+						android:paddingBottom="25px"
+						android:gravity="fill_vertical|center">
+
+						<TextView android:id="@+id/transmit_msg_tv"
+							android:textAppearance="?android:attr/textAppearanceSmall"
+							android:layout_width="wrap_content"
+							android:layout_height="wrap_content"
+							android:textSize="15px"
+							android:layout_centerHorizontal="true"
+							android:layout_alignWithParentIfMissing="true"
+							android:text="@string/transmit_msg_string" />
+
+						<TextView android:id="@+id/prog_frequency_tv"
+							android:textAppearance="?android:attr/textAppearanceLarge"
+							android:layout_width="wrap_content"
+							android:layout_height="wrap_content"
+							android:layout_centerHorizontal="true"
+							android:layout_alignWithParentIfMissing="true"
+							android:layout_alignParentTop="true"
+							android:layout_alignParentLeft="true"
+							android:textSize="56px"
+							android:text="@string/frequency_string" />
+					</LinearLayout>
+
+					<!-- Station Radio Text information display -->
+					<TextView android:id="@+id/radio_text_tv"
+						android:layout_width="fill_parent"
+						android:layout_height="wrap_content"
+						android:textAppearance="?android:attr/textAppearanceMedium"
+						android:textSize="16sp"
+						android:singleLine="true"
+						android:textStyle="bold"
+						android:paddingBottom="2px"
+						android:paddingLeft="5px"
+						android:paddingRight="5px"
+						android:gravity="center_horizontal"
+						android:text="@string/radio_text_string" />
+					<!-- android:gravity="center_horizontal" -->
+				</LinearLayout>
+
+				<ImageView android:id="@+id/btn_back"
+				    android:clickable="true"
+					android:focusable="true"
+					android:layout_width="wrap_content"
+					android:layout_height="fill_parent"
+					android:paddingLeft="10px"
+					android:paddingRight="2px"
+					android:layout_alignParentLeft="true"
+					android:layout_centerVertical="true"
+					android:visibility="visible"
+					android:src="@drawable/btn_arrow_left" />
+
+				<ImageView android:id="@+id/btn_forward"
+					android:clickable="true"
+					android:focusable="true"
+					android:layout_width="wrap_content"
+					android:layout_height="fill_parent"
+					android:paddingLeft="2px"
+					android:paddingRight="10px"
+					android:layout_alignParentRight="true"
+					android:layout_centerVertical="true"
+					android:visibility="visible"
+					android:src="@drawable/btn_arrow_right" />
+
+			</RelativeLayout>
+		</LinearLayout>
+		<LinearLayout android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:orientation="vertical"
+			android:layout_gravity="center"
+			android:layout_marginLeft="5px"
+			android:layout_marginRight="5px"
+			android:layout_marginBottom="2px">
+			<!-- On-Off button -->
+			<ImageButton android:id="@+id/btn_onoff"
+				android:layout_width="75px"
+				android:layout_height="75px"
+				android:src="@drawable/ic_btn_onoff"
+				android:layout_marginTop="15px"
+				android:layout_marginBottom="15px" />
+		</LinearLayout>
+
+	</LinearLayout>
+     <View
+        android:layout_width="fill_parent"
+        android:layout_height="1px"
+        android:background="#ffffffff" />
+
+	<!--
+		Layout contains the Next/Previous Presets and Tune buttons and status
+		msg text
+	-->
+     <LinearLayout android:id="@+id/presets_layout"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+    		android:layout_weight="0"
+            android:layout_gravity="center"
+            android:layout_marginTop="15dip"
+            android:layout_marginBottom="10dip"
+            android:gravity="center_horizontal">
+
+         <Button android:id="@+id/presets_button_1"
+         android:text="@string/default_station"
+         android:layout_marginLeft="20dip"
+         android:layout_marginRight="20dip"
+         android:textSize="24sp"
+         android:singleLine="true"
+         android:layout_width="110dip"
+         android:layout_height="65dip" />
+
+         <Button android:id="@+id/presets_button_2"
+             android:text="@string/default_station"
+             android:layout_marginRight="20dip"
+             android:textSize="24sp"
+             android:singleLine="true"
+             android:layout_width="110dip"
+             android:layout_height="65dip" />
+
+         <Button android:id="@+id/presets_button_3"
+         android:text="@string/default_station"
+         android:layout_marginRight="20dip"
+             android:textSize="24sp"
+             android:singleLine="true"
+             android:layout_width="110dip"
+             android:layout_height="65dip" />
+
+         <Button android:id="@+id/presets_button_4"
+             android:text="@string/default_blank"
+             android:layout_marginRight="20dip"
+             android:textSize="24sp"
+             android:singleLine="true"
+             android:layout_width="110dip"
+             android:layout_height="65dip" />
+
+         <Button android:id="@+id/presets_button_5"
+             android:text="@string/default_blank"
+             android:layout_marginRight="20dip"
+             android:textSize="24sp"
+             android:singleLine="true"
+             android:layout_width="110dip"
+             android:layout_height="65dip" />
+
+            <Button android:id="@+id/presets_button_6"
+                android:text="@string/default_blank"
+                android:layout_marginRight="20dip"
+                android:textSize="24sp"
+                android:singleLine="true"
+                android:layout_width="110dip"
+                android:layout_height="65dip"/>
+
+        </LinearLayout>
+
+
+</LinearLayout>
diff --git a/fmapp/res/layout-land-finger-800x480/fmradio.xml b/fmapp2/res/anim/preset_select.xml
similarity index 60%
copy from fmapp/res/layout-land-finger-800x480/fmradio.xml
copy to fmapp2/res/anim/preset_select.xml
index f2289fd..8fcf768 100644
--- a/fmapp/res/layout-land-finger-800x480/fmradio.xml
+++ b/fmapp2/res/anim/preset_select.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2009, 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009, 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:
@@ -26,28 +26,13 @@
  * 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"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content">
-
-    <!-- This LinearLayout contains Station Information display and the function buttons -->
-    <RelativeLayout android:id="@+id/station_info_wrapper_layout"
-        android:background="@drawable/station_border"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content">
-
-        <include layout="@layout/station_info" />
-
-     </RelativeLayout>
-
-     <RelativeLayout android:id="@+id/navigate_wrapper_layout"
-         android:layout_width="fill_parent"
-         android:layout_height="wrap_content"
-         android:layout_below="@id/station_info_wrapper_layout">
-
-         <!-- Layout contains the Next/Previous Presets and Tune buttons and status msg text-->
-         <include layout="@layout/navigate"/>
-
-     </RelativeLayout>
-
-</RelativeLayout>
+<scale xmlns:android="http://schemas.android.com/apk/res/android"
+    android:fromXScale="0.75"
+    android:toXScale="1.5"
+    android:fromYScale="0.75"
+    android:toYScale="1.5"
+    android:pivotX="50%"
+    android:pivotY="50%"
+    android:startOffset="0"
+    android:duration="500"
+    android:fillBefore="true" />
diff --git a/fmapp2/res/drawable-hdpi/bg.png b/fmapp2/res/drawable-hdpi/bg.png
new file mode 100644
index 0000000..fd10f0b
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/bg.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/bg_landscape.png b/fmapp2/res/drawable-hdpi/bg_landscape.png
new file mode 100644
index 0000000..83bfb23
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/bg_landscape.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_arrow_left_default.png b/fmapp2/res/drawable-hdpi/btn_arrow_left_default.png
new file mode 100644
index 0000000..857fb7a
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_arrow_left_default.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_arrow_left_press.png b/fmapp2/res/drawable-hdpi/btn_arrow_left_press.png
new file mode 100644
index 0000000..438e392
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_arrow_left_press.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_arrow_left_selected.png b/fmapp2/res/drawable-hdpi/btn_arrow_left_selected.png
new file mode 100644
index 0000000..fab8ee4
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_arrow_left_selected.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_arrow_right_default.png b/fmapp2/res/drawable-hdpi/btn_arrow_right_default.png
new file mode 100644
index 0000000..547e505
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_arrow_right_default.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_arrow_right_press.png b/fmapp2/res/drawable-hdpi/btn_arrow_right_press.png
new file mode 100644
index 0000000..96eacae
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_arrow_right_press.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_arrow_right_selected.png b/fmapp2/res/drawable-hdpi/btn_arrow_right_selected.png
new file mode 100644
index 0000000..67a86f5
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_arrow_right_selected.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_strip_trans_left_normal.9.png b/fmapp2/res/drawable-hdpi/btn_strip_trans_left_normal.9.png
new file mode 100644
index 0000000..31b3970
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_strip_trans_left_normal.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_strip_trans_left_pressed.9.png b/fmapp2/res/drawable-hdpi/btn_strip_trans_left_pressed.9.png
new file mode 100644
index 0000000..3b13559
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_strip_trans_left_pressed.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_strip_trans_left_selected.9.png b/fmapp2/res/drawable-hdpi/btn_strip_trans_left_selected.9.png
new file mode 100644
index 0000000..0607d23
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_strip_trans_left_selected.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_strip_trans_middle_normal.9.png b/fmapp2/res/drawable-hdpi/btn_strip_trans_middle_normal.9.png
new file mode 100644
index 0000000..d9f4f84
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_strip_trans_middle_normal.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_strip_trans_middle_pressed.9.png b/fmapp2/res/drawable-hdpi/btn_strip_trans_middle_pressed.9.png
new file mode 100644
index 0000000..3cc35e7
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_strip_trans_middle_pressed.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_strip_trans_middle_selected.9.png b/fmapp2/res/drawable-hdpi/btn_strip_trans_middle_selected.9.png
new file mode 100644
index 0000000..736e9b2
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_strip_trans_middle_selected.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_strip_trans_right_normal.9.png b/fmapp2/res/drawable-hdpi/btn_strip_trans_right_normal.9.png
new file mode 100644
index 0000000..3e83fd4
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_strip_trans_right_normal.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_strip_trans_right_pressed.9.png b/fmapp2/res/drawable-hdpi/btn_strip_trans_right_pressed.9.png
new file mode 100644
index 0000000..1076681
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_strip_trans_right_pressed.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/btn_strip_trans_right_selected.9.png b/fmapp2/res/drawable-hdpi/btn_strip_trans_right_selected.9.png
new file mode 100644
index 0000000..b0cf219
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/btn_strip_trans_right_selected.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/count_down.png b/fmapp2/res/drawable-hdpi/count_down.png
new file mode 100644
index 0000000..3c5f921
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/count_down.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/ic_btn_earphone_default.png b/fmapp2/res/drawable-hdpi/ic_btn_earphone_default.png
new file mode 100644
index 0000000..6a5b8db
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/ic_btn_earphone_default.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/ic_btn_earphone_diable.png b/fmapp2/res/drawable-hdpi/ic_btn_earphone_diable.png
new file mode 100644
index 0000000..f32b96e
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/ic_btn_earphone_diable.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/ic_btn_earphone_select.png b/fmapp2/res/drawable-hdpi/ic_btn_earphone_select.png
new file mode 100644
index 0000000..67afd3e
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/ic_btn_earphone_select.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/ic_btn_onoff_default.png b/fmapp2/res/drawable-hdpi/ic_btn_onoff_default.png
new file mode 100644
index 0000000..1c0f511
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/ic_btn_onoff_default.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/ic_btn_onoff_disable.png b/fmapp2/res/drawable-hdpi/ic_btn_onoff_disable.png
new file mode 100644
index 0000000..12b2d28
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/ic_btn_onoff_disable.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/ic_btn_onoff_press.png b/fmapp2/res/drawable-hdpi/ic_btn_onoff_press.png
new file mode 100644
index 0000000..efeebd3
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/ic_btn_onoff_press.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/ic_btn_spaker.png b/fmapp2/res/drawable-hdpi/ic_btn_spaker.png
new file mode 100644
index 0000000..f439e2e
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/ic_btn_spaker.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/ic_btn_spaker_select.png b/fmapp2/res/drawable-hdpi/ic_btn_spaker_select.png
new file mode 100644
index 0000000..bd5d57b
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/ic_btn_spaker_select.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/ic_launcher_fmradio.png b/fmapp2/res/drawable-hdpi/ic_launcher_fmradio.png
new file mode 100644
index 0000000..4815bce
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/ic_launcher_fmradio.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/recorder_start.png b/fmapp2/res/drawable-hdpi/recorder_start.png
new file mode 100644
index 0000000..a4425e2
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/recorder_start.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/recorder_stop.png b/fmapp2/res/drawable-hdpi/recorder_stop.png
new file mode 100644
index 0000000..bb8b32b
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/recorder_stop.png
Binary files differ
diff --git a/fmapp2/res/drawable-hdpi/stat_notify_fm.png b/fmapp2/res/drawable-hdpi/stat_notify_fm.png
new file mode 100644
index 0000000..d729ffb
--- /dev/null
+++ b/fmapp2/res/drawable-hdpi/stat_notify_fm.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/bg.png b/fmapp2/res/drawable-mdpi/bg.png
new file mode 100644
index 0000000..fd10f0b
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/bg.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/bg_landscape.png b/fmapp2/res/drawable-mdpi/bg_landscape.png
new file mode 100644
index 0000000..83bfb23
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/bg_landscape.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_arrow_left_default.png b/fmapp2/res/drawable-mdpi/btn_arrow_left_default.png
new file mode 100644
index 0000000..da077e6
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_arrow_left_default.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_arrow_left_press.png b/fmapp2/res/drawable-mdpi/btn_arrow_left_press.png
new file mode 100644
index 0000000..b18c859
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_arrow_left_press.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_arrow_left_selected.png b/fmapp2/res/drawable-mdpi/btn_arrow_left_selected.png
new file mode 100644
index 0000000..aa5ebe4
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_arrow_left_selected.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_arrow_right_default.png b/fmapp2/res/drawable-mdpi/btn_arrow_right_default.png
new file mode 100644
index 0000000..696f53a
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_arrow_right_default.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_arrow_right_press.png b/fmapp2/res/drawable-mdpi/btn_arrow_right_press.png
new file mode 100644
index 0000000..069df33
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_arrow_right_press.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_arrow_right_selected.png b/fmapp2/res/drawable-mdpi/btn_arrow_right_selected.png
new file mode 100644
index 0000000..d7d797b
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_arrow_right_selected.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_strip_trans_left_normal.9.png b/fmapp2/res/drawable-mdpi/btn_strip_trans_left_normal.9.png
new file mode 100644
index 0000000..2d7db2b
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_strip_trans_left_normal.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_strip_trans_left_pressed.9.png b/fmapp2/res/drawable-mdpi/btn_strip_trans_left_pressed.9.png
new file mode 100644
index 0000000..ceddd76
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_strip_trans_left_pressed.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_strip_trans_left_selected.9.png b/fmapp2/res/drawable-mdpi/btn_strip_trans_left_selected.9.png
new file mode 100644
index 0000000..bc40887
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_strip_trans_left_selected.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_strip_trans_middle_normal.9.png b/fmapp2/res/drawable-mdpi/btn_strip_trans_middle_normal.9.png
new file mode 100644
index 0000000..77ee4be
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_strip_trans_middle_normal.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_strip_trans_middle_pressed.9.png b/fmapp2/res/drawable-mdpi/btn_strip_trans_middle_pressed.9.png
new file mode 100644
index 0000000..19b33af
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_strip_trans_middle_pressed.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_strip_trans_middle_selected.9.png b/fmapp2/res/drawable-mdpi/btn_strip_trans_middle_selected.9.png
new file mode 100644
index 0000000..33ca95c
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_strip_trans_middle_selected.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_strip_trans_right_normal.9.png b/fmapp2/res/drawable-mdpi/btn_strip_trans_right_normal.9.png
new file mode 100644
index 0000000..2de79b5
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_strip_trans_right_normal.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_strip_trans_right_pressed.9.png b/fmapp2/res/drawable-mdpi/btn_strip_trans_right_pressed.9.png
new file mode 100644
index 0000000..41d2650
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_strip_trans_right_pressed.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/btn_strip_trans_right_selected.9.png b/fmapp2/res/drawable-mdpi/btn_strip_trans_right_selected.9.png
new file mode 100644
index 0000000..a65e65f
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/btn_strip_trans_right_selected.9.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/ic_btn_earphone_default.png b/fmapp2/res/drawable-mdpi/ic_btn_earphone_default.png
new file mode 100644
index 0000000..c729ed0
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/ic_btn_earphone_default.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/ic_btn_earphone_diable.png b/fmapp2/res/drawable-mdpi/ic_btn_earphone_diable.png
new file mode 100644
index 0000000..c0929ba
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/ic_btn_earphone_diable.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/ic_btn_earphone_select.png b/fmapp2/res/drawable-mdpi/ic_btn_earphone_select.png
new file mode 100644
index 0000000..fb51ce1
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/ic_btn_earphone_select.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/ic_btn_onoff_default.png b/fmapp2/res/drawable-mdpi/ic_btn_onoff_default.png
new file mode 100644
index 0000000..9303cfb
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/ic_btn_onoff_default.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/ic_btn_onoff_disable.png b/fmapp2/res/drawable-mdpi/ic_btn_onoff_disable.png
new file mode 100644
index 0000000..57e060a
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/ic_btn_onoff_disable.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/ic_btn_onoff_press.png b/fmapp2/res/drawable-mdpi/ic_btn_onoff_press.png
new file mode 100644
index 0000000..1228a66
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/ic_btn_onoff_press.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/ic_btn_spaker.png b/fmapp2/res/drawable-mdpi/ic_btn_spaker.png
new file mode 100644
index 0000000..b72fab9
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/ic_btn_spaker.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/ic_btn_spaker_select.png b/fmapp2/res/drawable-mdpi/ic_btn_spaker_select.png
new file mode 100644
index 0000000..250baea
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/ic_btn_spaker_select.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/ic_launcher_fmradio.png b/fmapp2/res/drawable-mdpi/ic_launcher_fmradio.png
new file mode 100644
index 0000000..3361ad5
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/ic_launcher_fmradio.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/recorder_selected.png b/fmapp2/res/drawable-mdpi/recorder_selected.png
new file mode 100644
index 0000000..1886ba8
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/recorder_selected.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/recorder_start.png b/fmapp2/res/drawable-mdpi/recorder_start.png
new file mode 100644
index 0000000..a4425e2
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/recorder_start.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/recorder_stop.png b/fmapp2/res/drawable-mdpi/recorder_stop.png
new file mode 100644
index 0000000..bb8b32b
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/recorder_stop.png
Binary files differ
diff --git a/fmapp2/res/drawable-mdpi/stat_notify_fm.png b/fmapp2/res/drawable-mdpi/stat_notify_fm.png
new file mode 100644
index 0000000..6861a44
--- /dev/null
+++ b/fmapp2/res/drawable-mdpi/stat_notify_fm.png
Binary files differ
diff --git a/fmapp2/res/drawable/album_border_large.1.png b/fmapp2/res/drawable/album_border_large.1.png
new file mode 100644
index 0000000..e5ffbc7
--- /dev/null
+++ b/fmapp2/res/drawable/album_border_large.1.png
Binary files differ
diff --git a/fmapp2/res/drawable/alert_dialog_icon.png b/fmapp2/res/drawable/alert_dialog_icon.png
new file mode 100644
index 0000000..0a7de04
--- /dev/null
+++ b/fmapp2/res/drawable/alert_dialog_icon.png
Binary files differ
diff --git a/fmapp2/res/drawable/application_border.xml b/fmapp2/res/drawable/application_border.xml
new file mode 100644
index 0000000..eaf0918
--- /dev/null
+++ b/fmapp2/res/drawable/application_border.xml
@@ -0,0 +1,33 @@
+<!--
+ * Copyright (c) 2009, 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <stroke android:width="1dp" android:color="#A0000000" />
+    <padding android:left="1dp" android:top="1dp"
+            android:right="1dp" android:bottom="1dp" />
+    <corners android:radius="1dp" />
+</shape>
diff --git a/fmapp2/res/drawable/bg.png b/fmapp2/res/drawable/bg.png
new file mode 100644
index 0000000..fd10f0b
--- /dev/null
+++ b/fmapp2/res/drawable/bg.png
Binary files differ
diff --git a/fmapp2/res/drawable/bg_landscape.png b/fmapp2/res/drawable/bg_landscape.png
new file mode 100644
index 0000000..83bfb23
--- /dev/null
+++ b/fmapp2/res/drawable/bg_landscape.png
Binary files differ
diff --git a/fmapp/res/layout-land-finger-800x480/fmradio.xml b/fmapp2/res/drawable/btn_arrow_left.xml
similarity index 60%
copy from fmapp/res/layout-land-finger-800x480/fmradio.xml
copy to fmapp2/res/drawable/btn_arrow_left.xml
index f2289fd..e64966c 100644
--- a/fmapp/res/layout-land-finger-800x480/fmradio.xml
+++ b/fmapp2/res/drawable/btn_arrow_left.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2009, 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009, 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:
@@ -26,28 +26,15 @@
  * 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"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content">
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <!-- This LinearLayout contains Station Information display and the function buttons -->
-    <RelativeLayout android:id="@+id/station_info_wrapper_layout"
-        android:background="@drawable/station_border"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content">
+    <item android:state_pressed="true"
+        android:drawable="@drawable/btn_arrow_left_press" />
 
-        <include layout="@layout/station_info" />
+    <item android:state_window_focused="true" android:state_focused="true"
+        android:drawable="@drawable/btn_arrow_left_selected" />
 
-     </RelativeLayout>
+    <item
+        android:drawable="@drawable/btn_arrow_left_default" />
 
-     <RelativeLayout android:id="@+id/navigate_wrapper_layout"
-         android:layout_width="fill_parent"
-         android:layout_height="wrap_content"
-         android:layout_below="@id/station_info_wrapper_layout">
-
-         <!-- Layout contains the Next/Previous Presets and Tune buttons and status msg text-->
-         <include layout="@layout/navigate"/>
-
-     </RelativeLayout>
-
-</RelativeLayout>
+</selector>
diff --git a/fmapp2/res/drawable/btn_arrow_left_default.png b/fmapp2/res/drawable/btn_arrow_left_default.png
new file mode 100644
index 0000000..2a35952
--- /dev/null
+++ b/fmapp2/res/drawable/btn_arrow_left_default.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_arrow_left_press.png b/fmapp2/res/drawable/btn_arrow_left_press.png
new file mode 100644
index 0000000..8b72f0a
--- /dev/null
+++ b/fmapp2/res/drawable/btn_arrow_left_press.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_arrow_left_selected.png b/fmapp2/res/drawable/btn_arrow_left_selected.png
new file mode 100644
index 0000000..6cd3c9f
--- /dev/null
+++ b/fmapp2/res/drawable/btn_arrow_left_selected.png
Binary files differ
diff --git a/fmapp/res/layout-land-finger-800x480/fmradio.xml b/fmapp2/res/drawable/btn_arrow_right.xml
similarity index 60%
copy from fmapp/res/layout-land-finger-800x480/fmradio.xml
copy to fmapp2/res/drawable/btn_arrow_right.xml
index f2289fd..e4ab6f9 100644
--- a/fmapp/res/layout-land-finger-800x480/fmradio.xml
+++ b/fmapp2/res/drawable/btn_arrow_right.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2009, 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009, 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:
@@ -26,28 +26,16 @@
  * 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"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content">
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <!-- This LinearLayout contains Station Information display and the function buttons -->
-    <RelativeLayout android:id="@+id/station_info_wrapper_layout"
-        android:background="@drawable/station_border"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content">
 
-        <include layout="@layout/station_info" />
+    <item android:state_pressed="true"
+        android:drawable="@drawable/btn_arrow_right_press" />
 
-     </RelativeLayout>
+    <item android:state_window_focused="true" android:state_focused="true"
+        android:drawable="@drawable/btn_arrow_right_selected" />
 
-     <RelativeLayout android:id="@+id/navigate_wrapper_layout"
-         android:layout_width="fill_parent"
-         android:layout_height="wrap_content"
-         android:layout_below="@id/station_info_wrapper_layout">
+    <item
+        android:drawable="@drawable/btn_arrow_right_default" />
 
-         <!-- Layout contains the Next/Previous Presets and Tune buttons and status msg text-->
-         <include layout="@layout/navigate"/>
-
-     </RelativeLayout>
-
-</RelativeLayout>
+</selector>
diff --git a/fmapp2/res/drawable/btn_arrow_right_default.png b/fmapp2/res/drawable/btn_arrow_right_default.png
new file mode 100644
index 0000000..ae6fd53
--- /dev/null
+++ b/fmapp2/res/drawable/btn_arrow_right_default.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_arrow_right_press.png b/fmapp2/res/drawable/btn_arrow_right_press.png
new file mode 100644
index 0000000..a4ae45b
--- /dev/null
+++ b/fmapp2/res/drawable/btn_arrow_right_press.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_arrow_right_selected.png b/fmapp2/res/drawable/btn_arrow_right_selected.png
new file mode 100644
index 0000000..93bcc77
--- /dev/null
+++ b/fmapp2/res/drawable/btn_arrow_right_selected.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_earphone.xml b/fmapp2/res/drawable/btn_earphone.xml
new file mode 100644
index 0000000..5a185ed
--- /dev/null
+++ b/fmapp2/res/drawable/btn_earphone.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012-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 "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.
+ */
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+        android:drawable="@drawable/ic_btn_earphone_select" />
+    <item android:state_enabled="true"
+        android:drawable="@drawable/ic_btn_earphone_default" />
+    <item android:state_enabled="false"
+         android:drawable="@drawable/ic_btn_earphone_diable" />
+</selector>
diff --git a/fmapp2/res/drawable/btn_onoff.xml b/fmapp2/res/drawable/btn_onoff.xml
new file mode 100644
index 0000000..a024238
--- /dev/null
+++ b/fmapp2/res/drawable/btn_onoff.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012-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 "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.
+ */
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+        android:drawable="@drawable/ic_btn_onoff_press" />
+    <item android:state_enabled="true"
+        android:drawable="@drawable/ic_btn_onoff_default" />
+    <item android:state_enabled="false"
+         android:drawable="@drawable/ic_btn_onoff_disable" />
+</selector>
diff --git a/fmapp2/res/drawable/btn_recorder.xml b/fmapp2/res/drawable/btn_recorder.xml
new file mode 100644
index 0000000..88a5302
--- /dev/null
+++ b/fmapp2/res/drawable/btn_recorder.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012-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 "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.
+ */
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+        android:drawable="@drawable/recorder_selected" />
+    <item android:state_enabled="true"
+        android:drawable="@drawable/recorder_stop" />
+    <item android:state_enabled="false"
+         android:drawable="@drawable/recorder_start" />
+</selector>
diff --git a/fmapp2/res/drawable/btn_speaker.xml b/fmapp2/res/drawable/btn_speaker.xml
new file mode 100644
index 0000000..a22e62a
--- /dev/null
+++ b/fmapp2/res/drawable/btn_speaker.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012-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 "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.
+ */
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+        android:drawable="@drawable/ic_btn_spaker_select" />
+    <item android:state_enabled="true"
+        android:drawable="@drawable/ic_btn_spaker" />
+</selector>
diff --git a/fmapp2/res/drawable/btn_strip_trans_left.xml b/fmapp2/res/drawable/btn_strip_trans_left.xml
new file mode 100644
index 0000000..0a30f34
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_left.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012-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 "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.
+ */
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_pressed="true"
+        android:drawable="@drawable/btn_strip_trans_left_pressed" />
+
+    <item android:state_focused="true"
+        android:drawable="@drawable/btn_strip_trans_left_selected" />
+
+    <item android:state_enabled="true"
+        android:drawable="@drawable/btn_strip_trans_left_normal" />
+
+</selector>
diff --git a/fmapp2/res/drawable/btn_strip_trans_left_normal.9.png b/fmapp2/res/drawable/btn_strip_trans_left_normal.9.png
new file mode 100644
index 0000000..31b3970
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_left_normal.9.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_strip_trans_left_pressed.9.png b/fmapp2/res/drawable/btn_strip_trans_left_pressed.9.png
new file mode 100644
index 0000000..3b13559
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_left_pressed.9.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_strip_trans_left_selected.9.png b/fmapp2/res/drawable/btn_strip_trans_left_selected.9.png
new file mode 100644
index 0000000..0607d23
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_left_selected.9.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_strip_trans_middle.xml b/fmapp2/res/drawable/btn_strip_trans_middle.xml
new file mode 100644
index 0000000..b6b95a6
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_middle.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012-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 "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.
+ */
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_pressed="true"
+        android:drawable="@drawable/btn_strip_trans_middle_pressed" />
+
+    <item android:state_focused="true"
+        android:drawable="@drawable/btn_strip_trans_middle_selected" />
+
+    <item android:state_enabled="true"
+        android:drawable="@drawable/btn_strip_trans_middle_normal" />
+
+</selector>
diff --git a/fmapp2/res/drawable/btn_strip_trans_middle_normal.9.png b/fmapp2/res/drawable/btn_strip_trans_middle_normal.9.png
new file mode 100644
index 0000000..d9f4f84
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_middle_normal.9.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_strip_trans_middle_pressed.9.png b/fmapp2/res/drawable/btn_strip_trans_middle_pressed.9.png
new file mode 100644
index 0000000..3cc35e7
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_middle_pressed.9.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_strip_trans_middle_selected.9.png b/fmapp2/res/drawable/btn_strip_trans_middle_selected.9.png
new file mode 100644
index 0000000..736e9b2
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_middle_selected.9.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_strip_trans_right.xml b/fmapp2/res/drawable/btn_strip_trans_right.xml
new file mode 100644
index 0000000..512c963
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_right.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012-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 "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.
+ */
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_pressed="true"
+        android:drawable="@drawable/btn_strip_trans_right_pressed" />
+
+    <item android:state_focused="true"
+        android:drawable="@drawable/btn_strip_trans_right_selected" />
+
+    <item android:state_enabled="true"
+        android:drawable="@drawable/btn_strip_trans_right_normal" />
+
+</selector>
diff --git a/fmapp2/res/drawable/btn_strip_trans_right_normal.9.png b/fmapp2/res/drawable/btn_strip_trans_right_normal.9.png
new file mode 100644
index 0000000..3e83fd4
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_right_normal.9.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_strip_trans_right_pressed.9.png b/fmapp2/res/drawable/btn_strip_trans_right_pressed.9.png
new file mode 100644
index 0000000..1076681
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_right_pressed.9.png
Binary files differ
diff --git a/fmapp2/res/drawable/btn_strip_trans_right_selected.9.png b/fmapp2/res/drawable/btn_strip_trans_right_selected.9.png
new file mode 100644
index 0000000..b0cf219
--- /dev/null
+++ b/fmapp2/res/drawable/btn_strip_trans_right_selected.9.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_earphone_default.png b/fmapp2/res/drawable/ic_btn_earphone_default.png
new file mode 100644
index 0000000..6a5b8db
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_earphone_default.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_earphone_diable.png b/fmapp2/res/drawable/ic_btn_earphone_diable.png
new file mode 100644
index 0000000..f32b96e
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_earphone_diable.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_earphone_select.png b/fmapp2/res/drawable/ic_btn_earphone_select.png
new file mode 100644
index 0000000..67afd3e
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_earphone_select.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_forward.png b/fmapp2/res/drawable/ic_btn_forward.png
new file mode 100644
index 0000000..0936fac
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_forward.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_forward_dis.png b/fmapp2/res/drawable/ic_btn_forward_dis.png
new file mode 100644
index 0000000..cd9a2f5
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_forward_dis.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_onoff.png b/fmapp2/res/drawable/ic_btn_onoff.png
new file mode 100644
index 0000000..4405b43
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_onoff.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_onoff_default.png b/fmapp2/res/drawable/ic_btn_onoff_default.png
new file mode 100644
index 0000000..1c0f511
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_onoff_default.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_onoff_disable.png b/fmapp2/res/drawable/ic_btn_onoff_disable.png
new file mode 100644
index 0000000..12b2d28
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_onoff_disable.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_onoff_press.png b/fmapp2/res/drawable/ic_btn_onoff_press.png
new file mode 100644
index 0000000..efeebd3
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_onoff_press.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_preset.png b/fmapp2/res/drawable/ic_btn_preset.png
new file mode 100644
index 0000000..35449b3
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_preset.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_search.png b/fmapp2/res/drawable/ic_btn_search.png
new file mode 100644
index 0000000..7eea584
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_search.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_search_stop.png b/fmapp2/res/drawable/ic_btn_search_stop.png
new file mode 100644
index 0000000..0b8c4e8
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_search_stop.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_spaker.png b/fmapp2/res/drawable/ic_btn_spaker.png
new file mode 100644
index 0000000..f439e2e
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_spaker.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_btn_spaker_select.png b/fmapp2/res/drawable/ic_btn_spaker_select.png
new file mode 100644
index 0000000..bd5d57b
--- /dev/null
+++ b/fmapp2/res/drawable/ic_btn_spaker_select.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_launcher_fm_tx.png b/fmapp2/res/drawable/ic_launcher_fm_tx.png
new file mode 100644
index 0000000..c6e41b2
--- /dev/null
+++ b/fmapp2/res/drawable/ic_launcher_fm_tx.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_launcher_fmradio.png b/fmapp2/res/drawable/ic_launcher_fmradio.png
new file mode 100644
index 0000000..2b1250c
--- /dev/null
+++ b/fmapp2/res/drawable/ic_launcher_fmradio.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_menu_record.png b/fmapp2/res/drawable/ic_menu_record.png
new file mode 100644
index 0000000..60f7a01
--- /dev/null
+++ b/fmapp2/res/drawable/ic_menu_record.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_signal_2.png b/fmapp2/res/drawable/ic_signal_2.png
new file mode 100644
index 0000000..efe4b5f
--- /dev/null
+++ b/fmapp2/res/drawable/ic_signal_2.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_silent_mode.png b/fmapp2/res/drawable/ic_silent_mode.png
new file mode 100644
index 0000000..c89291a
--- /dev/null
+++ b/fmapp2/res/drawable/ic_silent_mode.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_silent_mode_off.png b/fmapp2/res/drawable/ic_silent_mode_off.png
new file mode 100644
index 0000000..4748b9e
--- /dev/null
+++ b/fmapp2/res/drawable/ic_silent_mode_off.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_status_fm_tx.png b/fmapp2/res/drawable/ic_status_fm_tx.png
new file mode 100644
index 0000000..29383c9
--- /dev/null
+++ b/fmapp2/res/drawable/ic_status_fm_tx.png
Binary files differ
diff --git a/fmapp2/res/drawable/ic_stereo.png b/fmapp2/res/drawable/ic_stereo.png
new file mode 100644
index 0000000..b9bfec6
--- /dev/null
+++ b/fmapp2/res/drawable/ic_stereo.png
Binary files differ
diff --git a/fmapp2/res/drawable/icon.png b/fmapp2/res/drawable/icon.png
new file mode 100644
index 0000000..7502484
--- /dev/null
+++ b/fmapp2/res/drawable/icon.png
Binary files differ
diff --git a/fmapp2/res/drawable/image_border_bg_normal.9.png b/fmapp2/res/drawable/image_border_bg_normal.9.png
new file mode 100644
index 0000000..18e3607
--- /dev/null
+++ b/fmapp2/res/drawable/image_border_bg_normal.9.png
Binary files differ
diff --git a/fmapp/res/layout-land-finger-800x480/fmradio.xml b/fmapp2/res/drawable/preset_page_button.xml
similarity index 60%
copy from fmapp/res/layout-land-finger-800x480/fmradio.xml
copy to fmapp2/res/drawable/preset_page_button.xml
index f2289fd..cb1457b 100644
--- a/fmapp/res/layout-land-finger-800x480/fmradio.xml
+++ b/fmapp2/res/drawable/preset_page_button.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2009, 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012, 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:
@@ -26,28 +26,10 @@
  * 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"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content">
-
-    <!-- This LinearLayout contains Station Information display and the function buttons -->
-    <RelativeLayout android:id="@+id/station_info_wrapper_layout"
-        android:background="@drawable/station_border"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content">
-
-        <include layout="@layout/station_info" />
-
-     </RelativeLayout>
-
-     <RelativeLayout android:id="@+id/navigate_wrapper_layout"
-         android:layout_width="fill_parent"
-         android:layout_height="wrap_content"
-         android:layout_below="@id/station_info_wrapper_layout">
-
-         <!-- Layout contains the Next/Previous Presets and Tune buttons and status msg text-->
-         <include layout="@layout/navigate"/>
-
-     </RelativeLayout>
-
-</RelativeLayout>
+ <selector xmlns:android="http://schemas.android.com/apk/res/android">
+     <item android:state_enabled="false"
+           android:drawable="@drawable/ic_btn_forward_dis" /> <!-- disabled -->
+     <item android:state_enabled="true"
+           android:drawable="@drawable/ic_btn_forward" /> <!-- enabled -->
+     <item android:drawable="@drawable/ic_btn_forward" /> <!-- default -->
+ </selector>
diff --git a/fmapp2/res/drawable/recorder_selected.png b/fmapp2/res/drawable/recorder_selected.png
new file mode 100644
index 0000000..24e79ad
--- /dev/null
+++ b/fmapp2/res/drawable/recorder_selected.png
Binary files differ
diff --git a/fmapp2/res/drawable/recorder_start.png b/fmapp2/res/drawable/recorder_start.png
new file mode 100644
index 0000000..5297a31
--- /dev/null
+++ b/fmapp2/res/drawable/recorder_start.png
Binary files differ
diff --git a/fmapp2/res/drawable/recorder_stop.png b/fmapp2/res/drawable/recorder_stop.png
new file mode 100644
index 0000000..6017be9
--- /dev/null
+++ b/fmapp2/res/drawable/recorder_stop.png
Binary files differ
diff --git a/fmapp2/res/drawable/stat_notify_fm.png b/fmapp2/res/drawable/stat_notify_fm.png
new file mode 100644
index 0000000..16ed9bc
--- /dev/null
+++ b/fmapp2/res/drawable/stat_notify_fm.png
Binary files differ
diff --git a/fmapp2/res/drawable/station_border.xml b/fmapp2/res/drawable/station_border.xml
new file mode 100644
index 0000000..2aee777
--- /dev/null
+++ b/fmapp2/res/drawable/station_border.xml
@@ -0,0 +1,33 @@
+<!--
+ * Copyright (c) 2009, 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <stroke android:width="1dp" android:color="#FFFFFFFF" />
+    <padding android:left="1dp" android:top="1dp"
+            android:right="1dp" android:bottom="1dp" />
+    <corners android:radius="1dp" />
+</shape>
diff --git a/fmapp2/res/layout-800x480/fmradio.xml b/fmapp2/res/layout-800x480/fmradio.xml
new file mode 100644
index 0000000..83b9f7c
--- /dev/null
+++ b/fmapp2/res/layout-800x480/fmradio.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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"
+    android:id="@+id/fmradio"
+    android:background="@drawable/bg"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <RelativeLayout android:id="@+id/layout_on_off"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginTop="3dp"
+        android:layout_alignParentTop="true">
+
+        <ImageView android:id="@+id/btn_onoff"
+            android:src="@drawable/btn_onoff"
+            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="15dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <TextView android:id="@+id/sleep_msg_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@drawable/count_down"
+            android:layout_toRightOf="@+id/btn_onoff"
+            android:textSize="14sp"
+            android:layout_marginLeft="5dp"
+            android:textStyle="bold"
+            android:visibility="invisible"
+            android:text="@string/default_sleep" />
+
+        <TextView android:id="@+id/prog_service_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_marginLeft="2dp"
+            android:layout_marginRight="2dp"
+            android:layout_toLeftOf="@+id/btn_silent"
+            android:layout_toRightOf="@+id/sleep_msg_tv"
+            android:textSize="16sp"
+            android:singleLine="true"
+            android:textStyle="bold"
+            android:text="@string/prog_service_string"/>
+
+        <ImageView android:id="@+id/btn_silent"
+            android:src="@drawable/ic_silent_mode_off"
+            android:layout_toLeftOf="@+id/btn_speaker_earphone"
+            android:layout_width="wrap_content"
+            android:layout_marginRight="10dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_height="wrap_content" />
+
+        <ImageView android:id="@+id/btn_speaker_earphone"
+            android:src="@drawable/btn_earphone"
+            android:layout_alignParentRight="true"
+            android:layout_marginRight="15dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+    </RelativeLayout>
+
+    <LinearLayout android:id="@+id/stationinfo_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginTop="5dp"
+        android:layout_below="@+id/layout_on_off">
+
+        <!-- This included layout contains Station Information to display -->
+        <include layout="@layout/station_info" />
+
+    </LinearLayout>
+
+    <com.caf.fmradio.HorizontalNumberPicker
+        android:id="@+id/fm_picker"
+        android:layout_width="fill_parent"
+        android:layout_height="200dp"
+        android:layout_marginBottom="50dp"
+        android:layout_below="@+id/stationinfo_layout"/>
+
+    <HorizontalScrollView
+        android:layout_width="fill_parent"
+        android:layout_height="60dp"
+        android:layout_alignParentBottom="true"
+        android:scrollbars="none">
+
+        <LinearLayout  android:id="@+id/favorite_list"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:orientation="horizontal">
+
+            <Button android:id="@+id/presets_button_1"
+                style="@style/ButtonStripLeft"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_2"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_3"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_4"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_5"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_6"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_7"
+                style="@style/ButtonStripRight"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+        </LinearLayout>
+
+    </HorizontalScrollView>
+
+</RelativeLayout>
diff --git a/fmapp/res/layout-800x480/fmtags.xml b/fmapp2/res/layout-800x480/fmtags.xml
similarity index 100%
rename from fmapp/res/layout-800x480/fmtags.xml
rename to fmapp2/res/layout-800x480/fmtags.xml
diff --git a/fmapp2/res/layout-800x480/fmtransmitter.xml b/fmapp2/res/layout-800x480/fmtransmitter.xml
new file mode 100644
index 0000000..f12e808
--- /dev/null
+++ b/fmapp2/res/layout-800x480/fmtransmitter.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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"
+    android:id="@+id/fmtransmitter"
+    android:background="@drawable/bg"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <RelativeLayout android:id="@+id/on_off_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="2dp"
+        android:layout_marginBottom="2dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true" >
+
+        <ImageView android:id="@+id/btn_onoff"
+            android:src="@drawable/btn_onoff"
+            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="15dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <TextView android:id="@+id/transmit_msg_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="15dp"
+            android:layout_centerInParent="true"
+            android:layout_alignWithParentIfMissing="true"
+            android:text="@string/transmit_msg_string"/>
+
+    </RelativeLayout>
+
+    <RelativeLayout android:id="@+id/stationinfo_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_marginTop="150dp" >
+
+        <RelativeLayout android:id="@+id/frequency_layout"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+
+            <ImageView android:id="@+id/btn_back"
+                android:clickable="true"
+                android:focusable="true"
+                android:layout_alignParentLeft="true"
+                android:paddingLeft="15dp"
+                android:visibility="visible"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/btn_arrow_left"/>
+
+            <TextView android:id="@+id/prog_frequency_tv"
+                android:textAppearance="?android:attr/textAppearanceLarge"
+                android:textSize="25dp"
+                android:layout_centerInParent="true"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/frequency_string"/>
+
+            <ImageView android:id="@+id/btn_forward"
+                android:clickable="true"
+                android:focusable="true"
+                android:paddingRight="15dp"
+                android:layout_alignParentRight="true"
+                android:visibility="visible"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/btn_arrow_right"/>
+
+        </RelativeLayout>
+
+        <!-- Station Radio Text information display -->
+        <RelativeLayout android:id="@+id/radio_text_layout"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/frequency_layout">
+
+            <TextView android:id="@+id/radio_text_tv"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="20dp"
+                android:singleLine="true"
+                android:textStyle="bold"
+                android:paddingLeft="2dp"
+                android:paddingRight="2dp"
+                android:paddingBottom="5dp"
+                android:layout_marginTop="20dp"
+                android:layout_marginBottom="10dp"
+                android:layout_centerInParent="true"
+                android:text="@string/radio_text_string"/>
+
+        </RelativeLayout>
+
+    </RelativeLayout>
+
+    <com.caf.fmradio.HorizontalNumberPicker
+        android:id="@+id/fm_picker"
+        android:layout_width="fill_parent"
+        android:layout_height="200dp"
+        android:layout_marginBottom="50dp"
+        android:layout_below="@id/stationinfo_layout"/>
+
+    <HorizontalScrollView
+        android:layout_width="fill_parent"
+        android:layout_height="60dp"
+        android:layout_alignParentBottom="true"
+        android:scrollbars="none">
+
+        <LinearLayout  android:id="@+id/favorite_list"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:orientation="horizontal">
+
+            <Button android:id="@+id/presets_button_1"
+                style="@style/ButtonStripLeft"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_2"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_3"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_4"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_5"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_6"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_7"
+                style="@style/ButtonStripRight"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+        </LinearLayout>
+
+    </HorizontalScrollView>
+
+</RelativeLayout>
diff --git a/fmapp/res/layout-800x480/navigate.xml b/fmapp2/res/layout-800x480/navigate.xml
similarity index 100%
rename from fmapp/res/layout-800x480/navigate.xml
rename to fmapp2/res/layout-800x480/navigate.xml
diff --git a/fmapp/res/layout/station_info.xml b/fmapp2/res/layout-800x480/station_info.xml
similarity index 72%
copy from fmapp/res/layout/station_info.xml
copy to fmapp2/res/layout-800x480/station_info.xml
index 876026a..87a8f7e 100644
--- a/fmapp/res/layout/station_info.xml
+++ b/fmapp2/res/layout-800x480/station_info.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009, 2012, 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:
@@ -43,31 +43,33 @@
                 android:src="@drawable/ic_signal_2"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingLeft="5dip"
+                android:paddingLeft="5dp"
                 android:layout_alignParentTop="true"
-                android:layout_alignParentLeft="true"/>
+                android:layout_alignParentLeft="true"
+                android:visibility="gone" />
 
-            <TextView android:id="@+id/prog_service_tv"
+            <TextView android:id="@+id/record_msg_tv"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_alignParentTop="true"
-                android:layout_centerHorizontal="true"
-                android:layout_alignBaseline="@id/signal_level"
-                android:textSize="20dip"
-                android:singleLine="true"
+                android:drawableLeft="@drawable/recorder_start"
+                android:layout_marginLeft="20dp"
+                android:textSize="14sp"
                 android:textStyle="bold"
-                android:text="@string/prog_service_string"/>
+                android:clickable="true"
+                android:visibility="invisible"
+                android:text="@string/default_record"/>
+
 
             <TextView android:id="@+id/stereo_text_tv"
                 android:textAppearance="?android:attr/textAppearanceSmall"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingRight="5dip"
+                android:paddingRight="16dp"
                 android:layout_alignParentTop="true"
                 android:layout_alignParentRight="true"
                 android:layout_alignBaseline="@id/signal_level"
-                android:textSize="14dip"
+                android:textSize="13sp"
                 android:text="@string/default_audio"/>
 
         </RelativeLayout>
@@ -76,8 +78,8 @@
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical"
-            android:paddingTop="5dip"
-            android:paddingBottom="5dip"
+            android:paddingTop="5dp"
+            android:paddingBottom="5dp"
             android:layout_alignWithParentIfMissing="true"
             android:gravity="center">
 
@@ -85,35 +87,52 @@
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:textSize="14dip"
-                android:paddingTop="2dip"
-                android:paddingRight="2dip"
-                android:paddingBottom="2dip"
-                android:paddingLeft="2dip"
+                android:textSize="14sp"
+                android:paddingTop="2dp"
+                android:paddingRight="2dp"
+                android:paddingBottom="2dp"
+                android:paddingLeft="2dp"
                 android:text="@string/station_id_string" />
 
-            <RelativeLayout android:id="@+id/second_layout"
+            <TextView android:id="@+id/pty_tv"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="14sp"
+                android:paddingTop="2dp"
+                android:paddingRight="2dp"
+                android:paddingBottom="2dp"
+                android:paddingLeft="2dp"
+                android:text="@string/pty_string" />
+
+        </LinearLayout>
+
+        <RelativeLayout android:id="@+id/second_layout"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:layout_marginBottom="2dip"
-                android:layout_marginLeft="2dip"
-                android:layout_marginRight="2dip">
+                android:layout_marginTop="1dp"
+                android:layout_marginBottom="1dp"
+                android:layout_marginLeft="2dp"
+                android:layout_marginRight="2dp">
 
                 <TextView android:id="@+id/prog_frequency_tv"
                      android:textAppearance="?android:attr/textAppearanceLarge"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
-                     android:textSize="64dip"
-                     android:layout_centerHorizontal="true"
+                     android:textSize="25dp"
+                     android:gravity="center"
+                     android:clickable="true"
+                     android:focusable="true"
+                     android:layout_toLeftOf="@+id/btn_forward"
+                     android:layout_toRightOf="@+id/btn_back"
                      android:text="@string/frequency_string"/>
 
                 <ImageView android:id="@+id/btn_back"
                      android:clickable="true"
                      android:focusable="true"
                      android:layout_width="wrap_content"
-                     android:layout_height="100dip"
-                     android:paddingLeft="2dip"
+                     android:layout_height="wrap_content"
+                     android:paddingLeft="15dp"
                      android:layout_alignParentLeft="true"
                      android:visibility="visible"
                      android:layout_alignWithParentIfMissing="true"
@@ -123,39 +142,28 @@
                      android:clickable="true"
                      android:focusable="true"
                      android:layout_width="wrap_content"
-                     android:layout_height="100dip"
-                     android:paddingRight="2dip"
+                     android:layout_height="wrap_content"
+                     android:paddingRight="15dp"
                      android:layout_alignParentRight="true"
                      android:visibility="visible"
                      android:layout_alignWithParentIfMissing="true"
                      android:src="@drawable/btn_arrow_right"/>
 
-            </RelativeLayout>
+         </RelativeLayout>
 
-            <TextView android:id="@+id/pty_tv"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:textSize="14dip"
-                android:paddingTop="2dip"
-                android:paddingRight="2dip"
-                android:paddingBottom="2dip"
-                android:paddingLeft="2dip"
-                android:text="@string/pty_string" />
-
-        </LinearLayout>
 
         <!-- Station Radio Text information display -->
         <TextView android:id="@+id/radio_text_tv"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="20dip"
+            android:textSize="15sp"
             android:singleLine="true"
             android:textStyle="bold"
-            android:paddingLeft="2dip"
-            android:paddingRight="2dip"
-            android:paddingBottom="5dip"
+            android:paddingLeft="2dp"
+            android:paddingRight="2dp"
+            android:paddingBottom="5dp"
+            android:paddingTop="20dp"
             android:gravity="center_horizontal"
             android:text="@string/radio_text_string"/>
 
@@ -163,14 +171,15 @@
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="20dip"
+            android:textSize="15sp"
             android:singleLine="true"
             android:textStyle="bold"
-            android:paddingLeft="2dip"
-            android:paddingRight="2dip"
-            android:paddingBottom="5dip"
+            android:paddingLeft="2dp"
+            android:paddingRight="2dp"
+            android:paddingBottom="5dp"
             android:gravity="center_horizontal"
             android:text="@string/eradio_text_string"/>
+
     </LinearLayout>
 
 </merge>
diff --git a/fmapp2/res/layout-land-finger-800x480/fmradio.xml b/fmapp2/res/layout-land-finger-800x480/fmradio.xml
new file mode 100644
index 0000000..4a4519a
--- /dev/null
+++ b/fmapp2/res/layout-land-finger-800x480/fmradio.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012-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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/fmradio"
+    android:background="@drawable/bg_landscape"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <RelativeLayout android:id="@+id/layout_on_off"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true">
+
+        <ImageView android:id="@+id/btn_onoff"
+            android:src="@drawable/btn_onoff"
+            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="15dp"
+            android:layout_width="wrap_content"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_height="wrap_content" />
+
+        <TextView android:id="@+id/record_msg_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@drawable/recorder_start"
+            android:layout_marginLeft="25dp"
+            android:layout_toRightOf="@+id/btn_onoff"
+            android:textSize="14sp"
+            android:textStyle="bold"
+            android:clickable="true"
+            android:focusable="true"
+            android:visibility="invisible"
+            android:text="@string/default_record"/>
+
+        <TextView android:id="@+id/prog_service_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_toRightOf="@+id/record_msg_tv"
+            android:layout_toLeftOf="@+id/btn_silent"
+            android:textSize="16sp"
+            android:singleLine="true"
+            android:textStyle="bold"
+            android:text="@string/prog_service_string"/>
+
+        <ImageView android:id="@+id/btn_silent"
+            android:src="@drawable/ic_silent_mode_off"
+            android:layout_toLeftOf="@+id/btn_speaker_earphone"
+            android:layout_width="wrap_content"
+            android:layout_marginRight="10dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_height="wrap_content" />
+
+        <ImageView android:id="@+id/btn_speaker_earphone"
+            android:src="@drawable/btn_earphone"
+            android:layout_alignParentRight="true"
+            android:layout_marginRight="15dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+    </RelativeLayout>
+
+    <RelativeLayout android:id="@+id/stationinfo_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/layout_on_off">
+
+        <!-- This included layout contains Station Information to display -->
+        <include layout="@layout/station_info" />
+
+    </RelativeLayout>
+
+    <com.caf.fmradio.HorizontalNumberPicker
+        android:id="@+id/fm_picker"
+        android:layout_width="fill_parent"
+        android:layout_height="175dp"
+        android:layout_marginBottom="50dp"
+        android:layout_below="@+id/stationinfo_layout"/>
+
+    <HorizontalScrollView
+        android:layout_width="fill_parent"
+        android:layout_height="50dp"
+        android:fillViewport="true"
+        android:layout_alignParentBottom="true"
+        android:scrollbars="none">
+
+        <LinearLayout android:id="@+id/favorite_list"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <Button android:id="@+id/presets_button_1"
+                style="@style/ButtonStripLeft"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_weight="1"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_2"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_weight="1"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_3"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_weight="1"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_4"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_weight="1"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_5"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_weight="1"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_6"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_weight="1"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_7"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_weight="1"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+        </LinearLayout>
+
+    </HorizontalScrollView>
+
+</RelativeLayout>
diff --git a/fmapp2/res/layout-land-finger-800x480/fmtransmitter.xml b/fmapp2/res/layout-land-finger-800x480/fmtransmitter.xml
new file mode 100644
index 0000000..d32ffbc
--- /dev/null
+++ b/fmapp2/res/layout-land-finger-800x480/fmtransmitter.xml
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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"
+    android:id="@+id/fmtransmitter"
+    android:background="@drawable/bg_landscape"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <RelativeLayout android:id="@+id/on_off_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="2dp"
+        android:layout_marginBottom="2dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true" >
+
+        <ImageView android:id="@+id/btn_onoff"
+            android:src="@drawable/btn_onoff"
+            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="15dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <TextView android:id="@+id/transmit_msg_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="15dp"
+            android:layout_centerInParent="true"
+            android:layout_alignWithParentIfMissing="true"
+            android:text="@string/transmit_msg_string"/>
+
+    </RelativeLayout>
+
+    <RelativeLayout android:id="@+id/stationinfo_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_below="@id/on_off_layout"
+        android:layout_marginTop="20dp" >
+
+        <RelativeLayout android:id="@+id/frequency_layout"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+
+            <ImageView android:id="@+id/btn_back"
+                android:clickable="true"
+                android:focusable="true"
+                android:layout_alignParentLeft="true"
+                android:paddingLeft="15dp"
+                android:visibility="visible"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/btn_arrow_left"/>
+
+            <TextView android:id="@+id/prog_frequency_tv"
+                android:textAppearance="?android:attr/textAppearanceLarge"
+                android:textSize="25dp"
+                android:layout_centerInParent="true"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/frequency_string"/>
+
+            <ImageView android:id="@+id/btn_forward"
+                android:clickable="true"
+                android:focusable="true"
+                android:paddingRight="15dp"
+                android:layout_alignParentRight="true"
+                android:visibility="visible"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/btn_arrow_right"/>
+
+        </RelativeLayout>
+
+        <!-- Station Radio Text information display -->
+        <RelativeLayout android:id="@+id/radio_text_layout"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/frequency_layout">
+
+            <TextView android:id="@+id/radio_text_tv"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="20dp"
+                android:singleLine="true"
+                android:textStyle="bold"
+                android:paddingLeft="2dp"
+                android:paddingRight="2dp"
+                android:layout_marginTop="20dp"
+                android:layout_marginBottom="10dp"
+                android:layout_centerInParent="true"
+                android:text="@string/radio_text_string"/>
+
+        </RelativeLayout>
+
+    </RelativeLayout>
+
+    <com.caf.fmradio.HorizontalNumberPicker
+        android:id="@+id/fm_picker"
+        android:layout_width="fill_parent"
+        android:layout_height="167dp"
+        android:layout_marginBottom="55dp"
+        android:layout_below="@id/stationinfo_layout"/>
+
+    <HorizontalScrollView
+        android:layout_width="fill_parent"
+        android:layout_height="50dp"
+        android:layout_alignParentBottom="true"
+        android:scrollbars="none">
+
+        <LinearLayout  android:id="@+id/favorite_list"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:orientation="horizontal">
+
+            <Button android:id="@+id/presets_button_1"
+                style="@style/ButtonStripLeft"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_2"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_3"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_4"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_5"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_6"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_7"
+                style="@style/ButtonStripRight"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+        </LinearLayout>
+
+    </HorizontalScrollView>
+
+</RelativeLayout>
+
diff --git a/fmapp/res/layout-land-finger/navigate.xml b/fmapp2/res/layout-land-finger-800x480/navigate.xml
similarity index 100%
copy from fmapp/res/layout-land-finger/navigate.xml
copy to fmapp2/res/layout-land-finger-800x480/navigate.xml
diff --git a/fmapp/res/layout/station_info.xml b/fmapp2/res/layout-land-finger-800x480/station_info.xml
similarity index 60%
copy from fmapp/res/layout/station_info.xml
copy to fmapp2/res/layout-land-finger-800x480/station_info.xml
index 876026a..3f44573 100644
--- a/fmapp/res/layout/station_info.xml
+++ b/fmapp2/res/layout-land-finger-800x480/station_info.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009, 2012, 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:
@@ -28,12 +28,10 @@
 -->
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <LinearLayout android:id="@+id/station_info"
+    <RelativeLayout android:id="@+id/station_info"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        android:layout_weight="0"
-        android:orientation="vertical"
-        android:gravity="top">
+        android:orientation="vertical">
 
         <RelativeLayout android:id="@+id/top_most"
             android:layout_width="fill_parent"
@@ -43,77 +41,116 @@
                 android:src="@drawable/ic_signal_2"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingLeft="5dip"
+                android:paddingLeft="5dp"
                 android:layout_alignParentTop="true"
-                android:layout_alignParentLeft="true"/>
+                android:layout_alignParentLeft="true"
+                android:visibility="gone" />
 
-            <TextView android:id="@+id/prog_service_tv"
+            <TextView android:id="@+id/sleep_msg_tv"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_alignParentTop="true"
-                android:layout_centerHorizontal="true"
-                android:layout_alignBaseline="@id/signal_level"
-                android:textSize="20dip"
+                android:drawableLeft="@drawable/count_down"
+                android:textSize="14sp"
+                android:layout_marginLeft="25dp"
+                android:textStyle="bold"
+                android:visibility="invisible"
+                android:text="@string/default_sleep" />
+
+            <TextView android:id="@+id/eradio_text_tv"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
                 android:singleLine="true"
                 android:textStyle="bold"
-                android:text="@string/prog_service_string"/>
+                android:paddingLeft="5dp"
+                android:paddingRight="5dp"
+                android:layout_toLeftOf="@+id/sleep_msg_tv"
+                android:layout_toRightOf="@+id/stereo_text_tv"
+                android:layout_centerInParent="true"
+                android:text="@string/eradio_text_string"/>
 
             <TextView android:id="@+id/stereo_text_tv"
                 android:textAppearance="?android:attr/textAppearanceSmall"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingRight="5dip"
+                android:paddingRight="16dp"
                 android:layout_alignParentTop="true"
                 android:layout_alignParentRight="true"
                 android:layout_alignBaseline="@id/signal_level"
-                android:textSize="14dip"
+                android:textSize="13sp"
                 android:text="@string/default_audio"/>
 
         </RelativeLayout>
 
-        <LinearLayout android:id="@+id/station_frequency_row"
+        <RelativeLayout android:id="@+id/station_frequency_row"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:paddingTop="5dip"
-            android:paddingBottom="5dip"
-            android:layout_alignWithParentIfMissing="true"
-            android:gravity="center">
+            android:paddingTop="1dp"
+            android:paddingBottom="1dp"
+            android:layout_below="@+id/top_most"
+            android:layout_alignWithParentIfMissing="true">
 
             <TextView android:id="@+id/call_sign_tv"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:textSize="14dip"
-                android:paddingTop="2dip"
-                android:paddingRight="2dip"
-                android:paddingBottom="2dip"
-                android:paddingLeft="2dip"
+                android:textSize="14sp"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentLeft="true"
+                android:paddingLeft="16dp"
                 android:text="@string/station_id_string" />
 
-            <RelativeLayout android:id="@+id/second_layout"
+            <TextView android:id="@+id/radio_text_tv"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:textStyle="bold"
+                android:layout_centerInParent="true"
+                android:text="@string/radio_text_string"/>
+
+            <TextView android:id="@+id/pty_tv"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="14sp"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentRight="true"
+                android:paddingRight="16dp"
+                android:text="@string/pty_string" />
+
+        </RelativeLayout>
+
+        <RelativeLayout android:id="@+id/second_layout"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:layout_marginBottom="2dip"
-                android:layout_marginLeft="2dip"
-                android:layout_marginRight="2dip">
+                android:layout_marginTop="1dp"
+                android:layout_marginBottom="1dp"
+                android:layout_marginLeft="2dp"
+                android:layout_below="@+id/station_frequency_row"
+                android:layout_marginRight="2dp">
 
                 <TextView android:id="@+id/prog_frequency_tv"
                      android:textAppearance="?android:attr/textAppearanceLarge"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
-                     android:textSize="64dip"
-                     android:layout_centerHorizontal="true"
+                     android:textSize="25dp"
+                     android:gravity="center"
+                     android:clickable="true"
+                     android:focusable="true"
+                     android:layout_toLeftOf="@+id/btn_forward"
+                     android:layout_toRightOf="@+id/btn_back"
                      android:text="@string/frequency_string"/>
 
                 <ImageView android:id="@+id/btn_back"
                      android:clickable="true"
                      android:focusable="true"
                      android:layout_width="wrap_content"
-                     android:layout_height="100dip"
-                     android:paddingLeft="2dip"
+                     android:layout_height="wrap_content"
+                     android:paddingLeft="15dp"
                      android:layout_alignParentLeft="true"
                      android:visibility="visible"
                      android:layout_alignWithParentIfMissing="true"
@@ -123,54 +160,15 @@
                      android:clickable="true"
                      android:focusable="true"
                      android:layout_width="wrap_content"
-                     android:layout_height="100dip"
-                     android:paddingRight="2dip"
+                     android:layout_height="wrap_content"
+                     android:paddingRight="15dp"
                      android:layout_alignParentRight="true"
                      android:visibility="visible"
                      android:layout_alignWithParentIfMissing="true"
                      android:src="@drawable/btn_arrow_right"/>
 
-            </RelativeLayout>
+         </RelativeLayout>
 
-            <TextView android:id="@+id/pty_tv"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:textSize="14dip"
-                android:paddingTop="2dip"
-                android:paddingRight="2dip"
-                android:paddingBottom="2dip"
-                android:paddingLeft="2dip"
-                android:text="@string/pty_string" />
-
-        </LinearLayout>
-
-        <!-- Station Radio Text information display -->
-        <TextView android:id="@+id/radio_text_tv"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="20dip"
-            android:singleLine="true"
-            android:textStyle="bold"
-            android:paddingLeft="2dip"
-            android:paddingRight="2dip"
-            android:paddingBottom="5dip"
-            android:gravity="center_horizontal"
-            android:text="@string/radio_text_string"/>
-
-        <TextView android:id="@+id/eradio_text_tv"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="20dip"
-            android:singleLine="true"
-            android:textStyle="bold"
-            android:paddingLeft="2dip"
-            android:paddingRight="2dip"
-            android:paddingBottom="5dip"
-            android:gravity="center_horizontal"
-            android:text="@string/eradio_text_string"/>
-    </LinearLayout>
+    </RelativeLayout>
 
 </merge>
diff --git a/fmapp2/res/layout-land-finger/fmradio.xml b/fmapp2/res/layout-land-finger/fmradio.xml
new file mode 100644
index 0000000..23d74fb
--- /dev/null
+++ b/fmapp2/res/layout-land-finger/fmradio.xml
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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"
+    android:id="@+id/fmradio"
+    android:background="@drawable/bg_landscape"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <RelativeLayout android:id="@+id/layout_on_off"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true">
+
+        <ImageView android:id="@+id/btn_onoff"
+            android:src="@drawable/btn_onoff"
+            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="15dp"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <TextView android:id="@+id/record_msg_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@drawable/recorder_start"
+            android:layout_marginLeft="2dp"
+            android:layout_toRightOf="@+id/btn_onoff"
+            android:textSize="14sp"
+            android:textStyle="bold"
+            android:clickable="true"
+            android:focusable="true"
+            android:visibility="invisible"
+            android:text="@string/default_record"/>
+
+        <TextView android:id="@+id/prog_service_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_toRightOf="@+id/record_msg_tv"
+            android:layout_toLeftOf="@+id/btn_silent"
+            android:textSize="16sp"
+            android:singleLine="true"
+            android:textStyle="bold"
+            android:text="@string/prog_service_string"/>
+
+        <ImageView android:id="@+id/btn_silent"
+            android:src="@drawable/ic_silent_mode_off"
+            android:layout_toLeftOf="@+id/btn_speaker_earphone"
+            android:layout_width="wrap_content"
+            android:layout_marginRight="10dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_height="wrap_content" />
+
+        <ImageView android:id="@+id/btn_speaker_earphone"
+            android:src="@drawable/btn_earphone"
+            android:layout_alignParentRight="true"
+            android:layout_marginRight="15dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+    </RelativeLayout>
+
+    <RelativeLayout android:id="@+id/stationinfo_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="1dp"
+        android:layout_below="@+id/layout_on_off">
+
+        <!-- This included layout contains Station Information to display -->
+        <include layout="@layout/station_info" />
+
+    </RelativeLayout>
+
+    <com.caf.fmradio.HorizontalNumberPicker
+        android:id="@+id/fm_picker"
+        android:layout_width="fill_parent"
+        android:layout_height="175dp"
+        android:layout_marginBottom="50dp"
+        android:layout_below="@+id/stationinfo_layout"/>
+
+    <HorizontalScrollView
+        android:layout_width="fill_parent"
+        android:layout_height="50dp"
+        android:layout_alignParentBottom="true"
+        android:scrollbars="none">
+
+        <LinearLayout android:id="@+id/favorite_list"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <Button android:id="@+id/presets_button_1"
+                style="@style/ButtonStripLeft"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_2"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_3"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_4"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_5"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_6"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_7"
+                style="@style/ButtonStripRight"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_height="wrap_content"/>
+
+        </LinearLayout>
+
+    </HorizontalScrollView>
+
+</RelativeLayout>
diff --git a/fmapp2/res/layout-land-finger/fmtransmitter.xml b/fmapp2/res/layout-land-finger/fmtransmitter.xml
new file mode 100644
index 0000000..1e350b0
--- /dev/null
+++ b/fmapp2/res/layout-land-finger/fmtransmitter.xml
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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"
+    android:id="@+id/fmtransmitter"
+    android:background="@drawable/bg_landscape"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <RelativeLayout android:id="@+id/on_off_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="2dp"
+        android:layout_marginBottom="2dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true" >
+
+        <ImageView android:id="@+id/btn_onoff"
+            android:src="@drawable/btn_onoff"
+            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="15dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <TextView android:id="@+id/transmit_msg_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="15dp"
+            android:layout_centerInParent="true"
+            android:layout_alignWithParentIfMissing="true"
+            android:text="@string/transmit_msg_string"/>
+
+    </RelativeLayout>
+
+    <RelativeLayout android:id="@+id/stationinfo_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_below="@id/on_off_layout"
+        android:layout_marginTop="20dp" >
+
+        <RelativeLayout android:id="@+id/frequency_layout"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+
+            <ImageView android:id="@+id/btn_back"
+                android:clickable="true"
+                android:focusable="true"
+                android:layout_alignParentLeft="true"
+                android:paddingLeft="15dp"
+                android:visibility="visible"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/btn_arrow_left"/>
+
+            <TextView android:id="@+id/prog_frequency_tv"
+                android:textAppearance="?android:attr/textAppearanceLarge"
+                android:textSize="25dp"
+                android:layout_centerInParent="true"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/frequency_string"/>
+
+            <ImageView android:id="@+id/btn_forward"
+                android:clickable="true"
+                android:focusable="true"
+                android:paddingRight="15dp"
+                android:layout_alignParentRight="true"
+                android:visibility="visible"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/btn_arrow_right"/>
+
+        </RelativeLayout>
+
+        <!-- Station Radio Text information display -->
+        <RelativeLayout android:id="@+id/radio_text_layout"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/frequency_layout">
+
+            <TextView android:id="@+id/radio_text_tv"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="20dp"
+                android:singleLine="true"
+                android:textStyle="bold"
+                android:paddingLeft="2dp"
+                android:paddingRight="2dp"
+                android:paddingBottom="5dp"
+                android:layout_marginTop="20dp"
+                android:layout_marginBottom="10dp"
+                android:layout_centerInParent="true"
+                android:text="@string/radio_text_string"/>
+
+        </RelativeLayout>
+
+    </RelativeLayout>
+
+    <com.caf.fmradio.HorizontalNumberPicker
+        android:id="@+id/fm_picker"
+        android:layout_width="fill_parent"
+        android:layout_height="175dp"
+        android:layout_marginBottom="50dp"
+        android:layout_below="@id/stationinfo_layout"/>
+
+    <HorizontalScrollView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:scrollbars="none">
+
+        <LinearLayout  android:id="@+id/favorite_list"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <Button android:id="@+id/presets_button_1"
+                style="@style/ButtonStripLeft"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_2"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_3"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_4"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_5"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_6"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_7"
+                style="@style/ButtonStripRight"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="12sp"
+                android:singleLine="true"
+                android:layout_width="85dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+        </LinearLayout>
+
+    </HorizontalScrollView>
+
+</RelativeLayout>
+
diff --git a/fmapp/res/layout-land-finger/navigate.xml b/fmapp2/res/layout-land-finger/navigate.xml
similarity index 100%
rename from fmapp/res/layout-land-finger/navigate.xml
rename to fmapp2/res/layout-land-finger/navigate.xml
diff --git a/fmapp/res/layout/station_info.xml b/fmapp2/res/layout-land-finger/station_info.xml
similarity index 60%
copy from fmapp/res/layout/station_info.xml
copy to fmapp2/res/layout-land-finger/station_info.xml
index 876026a..9383894 100644
--- a/fmapp/res/layout/station_info.xml
+++ b/fmapp2/res/layout-land-finger/station_info.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009, 2012, 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:
@@ -28,12 +28,10 @@
 -->
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <LinearLayout android:id="@+id/station_info"
+    <RelativeLayout android:id="@+id/station_info"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        android:layout_weight="0"
-        android:orientation="vertical"
-        android:gravity="top">
+        android:orientation="vertical">
 
         <RelativeLayout android:id="@+id/top_most"
             android:layout_width="fill_parent"
@@ -43,77 +41,114 @@
                 android:src="@drawable/ic_signal_2"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingLeft="5dip"
+                android:paddingLeft="5dp"
                 android:layout_alignParentTop="true"
-                android:layout_alignParentLeft="true"/>
+                android:layout_alignParentLeft="true"
+                android:visibility="gone" />
 
-            <TextView android:id="@+id/prog_service_tv"
+            <TextView android:id="@+id/sleep_msg_tv"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_alignParentTop="true"
-                android:layout_centerHorizontal="true"
-                android:layout_alignBaseline="@id/signal_level"
-                android:textSize="20dip"
+                android:drawableLeft="@drawable/count_down"
+                android:textSize="14sp"
+                android:layout_marginLeft="25dp"
+                android:textStyle="bold"
+                android:visibility="invisible"
+                android:text="@string/default_sleep" />
+
+            <TextView android:id="@+id/eradio_text_tv"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
                 android:singleLine="true"
                 android:textStyle="bold"
-                android:text="@string/prog_service_string"/>
+                android:paddingLeft="5dp"
+                android:paddingRight="5dp"
+                android:layout_toRightOf="@+id/sleep_msg_tv"
+                android:layout_toLeftOf="@+id/stereo_text_tv"
+                android:layout_centerInParent="true"
+                android:text="@string/eradio_text_string"/>
 
             <TextView android:id="@+id/stereo_text_tv"
                 android:textAppearance="?android:attr/textAppearanceSmall"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingRight="5dip"
+                android:paddingRight="16dp"
                 android:layout_alignParentTop="true"
                 android:layout_alignParentRight="true"
                 android:layout_alignBaseline="@id/signal_level"
-                android:textSize="14dip"
+                android:textSize="13sp"
                 android:text="@string/default_audio"/>
 
         </RelativeLayout>
 
-        <LinearLayout android:id="@+id/station_frequency_row"
+        <RelativeLayout android:id="@+id/station_frequency_row"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:paddingTop="5dip"
-            android:paddingBottom="5dip"
-            android:layout_alignWithParentIfMissing="true"
-            android:gravity="center">
+            android:paddingTop="1dp"
+            android:paddingBottom="1dp"
+            android:layout_below="@+id/top_most"
+            android:layout_alignWithParentIfMissing="true">
 
             <TextView android:id="@+id/call_sign_tv"
                 android:textAppearance="?android:attr/textAppearanceMedium"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:textSize="14dip"
-                android:paddingTop="2dip"
-                android:paddingRight="2dip"
-                android:paddingBottom="2dip"
-                android:paddingLeft="2dip"
+                android:textSize="14sp"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentLeft="true"
+                android:paddingLeft="16dp"
                 android:text="@string/station_id_string" />
 
-            <RelativeLayout android:id="@+id/second_layout"
+            <TextView android:id="@+id/radio_text_tv"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:textStyle="bold"
+                android:layout_centerInParent="true"
+                android:text="@string/radio_text_string"/>
+
+            <TextView android:id="@+id/pty_tv"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="14sp"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentRight="true"
+                android:paddingRight="16dp"
+                android:text="@string/pty_string" />
+
+        </RelativeLayout>
+
+        <RelativeLayout android:id="@+id/second_layout"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="2dip"
-                android:layout_marginBottom="2dip"
-                android:layout_marginLeft="2dip"
-                android:layout_marginRight="2dip">
+                android:layout_marginTop="1dp"
+                android:layout_marginBottom="1dp"
+                android:layout_marginLeft="2dp"
+                android:layout_below="@+id/station_frequency_row"
+                android:layout_marginRight="2dp">
 
                 <TextView android:id="@+id/prog_frequency_tv"
                      android:textAppearance="?android:attr/textAppearanceLarge"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
-                     android:textSize="64dip"
-                     android:layout_centerHorizontal="true"
+                     android:textSize="25dp"
+                     android:gravity="center"
+                     android:layout_toLeftOf="@+id/btn_forward"
+                     android:layout_toRightOf="@+id/btn_back"
                      android:text="@string/frequency_string"/>
 
                 <ImageView android:id="@+id/btn_back"
                      android:clickable="true"
                      android:focusable="true"
                      android:layout_width="wrap_content"
-                     android:layout_height="100dip"
-                     android:paddingLeft="2dip"
+                     android:layout_height="wrap_content"
+                     android:paddingLeft="15dp"
                      android:layout_alignParentLeft="true"
                      android:visibility="visible"
                      android:layout_alignWithParentIfMissing="true"
@@ -123,54 +158,15 @@
                      android:clickable="true"
                      android:focusable="true"
                      android:layout_width="wrap_content"
-                     android:layout_height="100dip"
-                     android:paddingRight="2dip"
+                     android:layout_height="wrap_content"
+                     android:paddingRight="15dp"
                      android:layout_alignParentRight="true"
                      android:visibility="visible"
                      android:layout_alignWithParentIfMissing="true"
                      android:src="@drawable/btn_arrow_right"/>
 
-            </RelativeLayout>
+         </RelativeLayout>
 
-            <TextView android:id="@+id/pty_tv"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:textSize="14dip"
-                android:paddingTop="2dip"
-                android:paddingRight="2dip"
-                android:paddingBottom="2dip"
-                android:paddingLeft="2dip"
-                android:text="@string/pty_string" />
-
-        </LinearLayout>
-
-        <!-- Station Radio Text information display -->
-        <TextView android:id="@+id/radio_text_tv"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="20dip"
-            android:singleLine="true"
-            android:textStyle="bold"
-            android:paddingLeft="2dip"
-            android:paddingRight="2dip"
-            android:paddingBottom="5dip"
-            android:gravity="center_horizontal"
-            android:text="@string/radio_text_string"/>
-
-        <TextView android:id="@+id/eradio_text_tv"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="20dip"
-            android:singleLine="true"
-            android:textStyle="bold"
-            android:paddingLeft="2dip"
-            android:paddingRight="2dip"
-            android:paddingBottom="5dip"
-            android:gravity="center_horizontal"
-            android:text="@string/eradio_text_string"/>
-    </LinearLayout>
+    </RelativeLayout>
 
 </merge>
diff --git a/fmapp/res/layout-land-finger-800x480/fmradio.xml b/fmapp2/res/layout/alert_dialog_list.xml
similarity index 65%
copy from fmapp/res/layout-land-finger-800x480/fmradio.xml
copy to fmapp2/res/layout/alert_dialog_list.xml
index f2289fd..8b9ae52 100644
--- a/fmapp/res/layout-land-finger-800x480/fmradio.xml
+++ b/fmapp2/res/layout/alert_dialog_list.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2009, 2012, The Linux Foundation. All rights reserved.
+ * 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:
@@ -26,28 +26,14 @@
  * 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"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
-    android:layout_height="wrap_content">
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
 
-    <!-- This LinearLayout contains Station Information display and the function buttons -->
-    <RelativeLayout android:id="@+id/station_info_wrapper_layout"
-        android:background="@drawable/station_border"
+    <ListView android:id="@+id/list"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content">
+    </ListView>
 
-        <include layout="@layout/station_info" />
-
-     </RelativeLayout>
-
-     <RelativeLayout android:id="@+id/navigate_wrapper_layout"
-         android:layout_width="fill_parent"
-         android:layout_height="wrap_content"
-         android:layout_below="@id/station_info_wrapper_layout">
-
-         <!-- Layout contains the Next/Previous Presets and Tune buttons and status msg text-->
-         <include layout="@layout/navigate"/>
-
-     </RelativeLayout>
-
-</RelativeLayout>
+</LinearLayout>
diff --git a/fmapp/res/layout-land-finger-800x480/fmradio.xml b/fmapp2/res/layout/alert_dialog_text_entry.xml
similarity index 66%
copy from fmapp/res/layout-land-finger-800x480/fmradio.xml
copy to fmapp2/res/layout/alert_dialog_text_entry.xml
index f2289fd..a54fc00 100644
--- a/fmapp/res/layout-land-finger-800x480/fmradio.xml
+++ b/fmapp2/res/layout/alert_dialog_text_entry.xml
@@ -26,28 +26,25 @@
  * 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"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
-    android:layout_height="wrap_content">
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
 
-    <!-- This LinearLayout contains Station Information display and the function buttons -->
-    <RelativeLayout android:id="@+id/station_info_wrapper_layout"
-        android:background="@drawable/station_border"
+    <EditText
+        android:id="@+id/list_edit"
+        android:layout_height="wrap_content"
         android:layout_width="fill_parent"
-        android:layout_height="wrap_content">
+        android:layout_marginLeft="20dp"
+        android:layout_marginRight="20dp"
+        android:scrollHorizontally="true"
+        android:hint="Enter a name"
+        android:singleLine="true"
+        android:inputType="text"
+        android:autoText="false"
+        android:capitalize="none"
+        android:gravity="fill_horizontal"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:saveEnabled="false"/>
 
-        <include layout="@layout/station_info" />
-
-     </RelativeLayout>
-
-     <RelativeLayout android:id="@+id/navigate_wrapper_layout"
-         android:layout_width="fill_parent"
-         android:layout_height="wrap_content"
-         android:layout_below="@id/station_info_wrapper_layout">
-
-         <!-- Layout contains the Next/Previous Presets and Tune buttons and status msg text-->
-         <include layout="@layout/navigate"/>
-
-     </RelativeLayout>
-
-</RelativeLayout>
+</LinearLayout>
diff --git a/fmapp2/res/layout/delete_dialog.xml b/fmapp2/res/layout/delete_dialog.xml
new file mode 100644
index 0000000..44df762
--- /dev/null
+++ b/fmapp2/res/layout/delete_dialog.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012, 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, Inc. 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 "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.
+ */
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <TextView android:id="@+id/prompt"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="8dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp"
+        android:drawableLeft="@android:drawable/ic_dialog_alert"
+        android:drawablePadding="8dp">
+    </TextView>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:padding="6dp">
+
+        <Button android:id="@+id/delete"
+            android:layout_width="120dp"
+            android:layout_height="wrap_content"
+            android:text="@string/button_delete"
+            android:layout_gravity="center_horizontal"
+            android:layout_alignParentLeft="true" />
+
+        <Button android:id="@+id/cancel"
+            android:layout_width="120dp"
+            android:layout_height="wrap_content"
+            android:text="@string/button_cancel"
+            android:layout_alignParentRight="true" />
+
+    </RelativeLayout>
+
+</LinearLayout>
diff --git a/fmapp2/res/layout/fmradio.xml b/fmapp2/res/layout/fmradio.xml
new file mode 100644
index 0000000..4aef544
--- /dev/null
+++ b/fmapp2/res/layout/fmradio.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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"
+    android:id="@+id/fmradio"
+    android:background="@drawable/bg"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <RelativeLayout android:id="@+id/layout_on_off"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginTop="3dp"
+        android:layout_alignParentTop="true">
+
+        <ImageView android:id="@+id/btn_onoff"
+            android:src="@drawable/btn_onoff"
+            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="15dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <TextView android:id="@+id/sleep_msg_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@drawable/count_down"
+            android:layout_toRightOf="@+id/btn_onoff"
+            android:textSize="14sp"
+            android:layout_marginLeft="5dp"
+            android:textStyle="bold"
+            android:visibility="invisible"
+            android:text="@string/default_sleep" />
+
+        <TextView android:id="@+id/prog_service_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:layout_marginLeft="2dp"
+            android:layout_marginRight="2dp"
+            android:layout_toLeftOf="@+id/btn_silent"
+            android:layout_toRightOf="@+id/sleep_msg_tv"
+            android:textSize="16sp"
+            android:singleLine="true"
+            android:textStyle="bold"
+            android:text="@string/prog_service_string"/>
+
+	<ImageView android:id="@+id/btn_silent"
+            android:src="@drawable/ic_silent_mode_off"
+            android:layout_toLeftOf="@+id/btn_speaker_earphone"
+            android:layout_width="wrap_content"
+            android:layout_marginRight="10dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_height="wrap_content" />
+
+        <ImageView android:id="@+id/btn_speaker_earphone"
+            android:src="@drawable/btn_earphone"
+            android:layout_alignParentRight="true"
+            android:layout_marginRight="15dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+    </RelativeLayout>
+
+    <LinearLayout android:id="@+id/stationinfo_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginTop="5dp"
+        android:layout_below="@+id/layout_on_off">
+
+        <!-- This included layout contains Station Information to display -->
+        <include layout="@layout/station_info" />
+
+    </LinearLayout>
+
+    <com.caf.fmradio.HorizontalNumberPicker
+        android:id="@+id/fm_picker"
+        android:layout_width="fill_parent"
+        android:layout_height="200dp"
+        android:layout_marginBottom="50dp"
+        android:layout_below="@+id/stationinfo_layout"/>
+
+    <HorizontalScrollView
+        android:layout_width="fill_parent"
+        android:layout_height="60dp"
+        android:layout_alignParentBottom="true"
+        android:scrollbars="none">
+
+        <LinearLayout  android:id="@+id/favorite_list"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:orientation="horizontal">
+
+            <Button android:id="@+id/presets_button_1"
+                style="@style/ButtonStripLeft"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_2"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_3"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_4"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_5"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_6"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_7"
+                style="@style/ButtonStripRight"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+        </LinearLayout>
+
+    </HorizontalScrollView>
+
+</RelativeLayout>
diff --git a/fmapp2/res/layout/fmstats.xml b/fmapp2/res/layout/fmstats.xml
new file mode 100644
index 0000000..d9306d5
--- /dev/null
+++ b/fmapp2/res/layout/fmstats.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2011, 2012, 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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:scrollbars="vertical"
+    android:layout_height="fill_parent"
+    android:layout_width="fill_parent">
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:orientation="vertical">
+
+       <Spinner
+           android:id="@+id/spinner"
+           android:layout_width="fill_parent"
+           android:layout_height="75dp"
+           android:prompt="@string/test_prompt"
+           android:textSize="25sp"/>
+
+       <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+           android:layout_width="fill_parent"
+           android:layout_height="100dp">
+
+           <Button
+               android:id= "@+id/Runbutton"
+               android:text="@string/test_run"
+               android:layout_width="wrap_content"
+               android:layout_height="100dp"
+               android:textSize="25sp"
+               android:visibility="gone"/>
+
+           <ProgressBar android:id="@+id/progressbar"
+               android:layout_width="100dp"
+               android:layout_height="100dp"
+               android:layout_toRightOf="@id/Runbutton"
+               android:visibility="gone"/>
+
+           <TextView
+               android:id="@+id/label"
+               android:layout_width="fill_parent"
+               android:layout_height="wrap_content"
+               android:textSize="15sp"
+               android:text="@string/enter_rssi"
+               android:visibility="gone"/>
+
+           <EditText
+               android:id="@+id/txtbox1"
+               android:layout_width="100dp"
+               android:layout_height="50dp"
+               android:text="@string/type_rd"
+               android:textSize="15sp"
+               android:layout_alignParentRight="true"
+               android:visibility="gone"/>
+
+           <Button
+               android:id= "@+id/Setbutton"
+               android:text="@string/set_rmmsi_delta"
+               android:layout_width="wrap_content"
+               android:layout_height="100dp"
+               android:layout_below="@id/txtbox1"
+               android:textSize="15sp"
+               android:visibility="gone"/>
+
+       </RelativeLayout>
+
+       <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+           android:id="@+id/maintable"
+           android:layout_width="fill_parent"
+           android:layout_height="fill_parent"
+           android:scrollbars="vertical">
+
+           <TableRow
+               android:id="@+id/mainrow">
+           </TableRow>
+
+       </TableLayout>
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/fmapp/res/layout/fmtags.xml b/fmapp2/res/layout/fmtags.xml
similarity index 100%
rename from fmapp/res/layout/fmtags.xml
rename to fmapp2/res/layout/fmtags.xml
diff --git a/fmapp2/res/layout/fmtransmitter.xml b/fmapp2/res/layout/fmtransmitter.xml
new file mode 100644
index 0000000..b2ba8e5
--- /dev/null
+++ b/fmapp2/res/layout/fmtransmitter.xml
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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"
+    android:id="@+id/fmtransmitter"
+    android:background="@drawable/bg"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <RelativeLayout android:id="@+id/on_off_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="2dp"
+        android:layout_marginBottom="2dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true" >
+
+        <ImageView android:id="@+id/btn_onoff"
+            android:src="@drawable/btn_onoff"
+            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="15dp"
+            android:clickable="true"
+            android:focusable="true"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content" />
+
+        <TextView android:id="@+id/transmit_msg_tv"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="15dp"
+            android:layout_centerInParent="true"
+            android:layout_alignWithParentIfMissing="true"
+            android:text="@string/transmit_msg_string"/>
+
+    </RelativeLayout>
+
+    <RelativeLayout android:id="@+id/stationinfo_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_below="@id/on_off_layout"
+        android:layout_marginTop="150dp" >
+
+        <RelativeLayout android:id="@+id/frequency_layout"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+
+            <ImageView android:id="@+id/btn_back"
+                android:clickable="true"
+                android:focusable="true"
+                android:layout_alignParentLeft="true"
+                android:paddingLeft="15dp"
+                android:visibility="visible"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/btn_arrow_left"/>
+
+            <TextView android:id="@+id/prog_frequency_tv"
+                android:textAppearance="?android:attr/textAppearanceLarge"
+                android:textSize="25dp"
+                android:layout_centerInParent="true"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/frequency_string"/>
+
+            <ImageView android:id="@+id/btn_forward"
+                android:clickable="true"
+                android:focusable="true"
+                android:paddingRight="15dp"
+                android:layout_alignParentRight="true"
+                android:visibility="visible"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/btn_arrow_right"/>
+
+        </RelativeLayout>
+
+        <!-- Station Radio Text information display -->
+        <RelativeLayout android:id="@+id/radio_text_layout"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/frequency_layout">
+
+            <TextView android:id="@+id/radio_text_tv"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="20dp"
+                android:singleLine="true"
+                android:textStyle="bold"
+                android:paddingLeft="2dp"
+                android:paddingRight="2dp"
+                android:paddingBottom="5dp"
+                android:layout_marginTop="20dp"
+                android:layout_marginBottom="10dp"
+                android:layout_centerInParent="true"
+                android:text="@string/radio_text_string"/>
+
+        </RelativeLayout>
+
+    </RelativeLayout>
+
+    <com.caf.fmradio.HorizontalNumberPicker
+        android:id="@+id/fm_picker"
+        android:layout_width="fill_parent"
+        android:layout_height="200dp"
+        android:layout_marginBottom="50dp"
+        android:layout_below="@id/stationinfo_layout"/>
+
+    <HorizontalScrollView
+        android:layout_width="fill_parent"
+        android:layout_height="60dp"
+        android:layout_alignParentBottom="true"
+        android:scrollbars="none">
+
+        <LinearLayout  android:id="@+id/favorite_list"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:orientation="horizontal">
+
+            <Button android:id="@+id/presets_button_1"
+                style="@style/ButtonStripLeft"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_2"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_3"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_4"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_5"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_6"
+                style="@style/ButtonStripMiddle"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+            <Button android:id="@+id/presets_button_7"
+                style="@style/ButtonStripRight"
+                android:text="@string/add_station"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textSize="15sp"
+                android:singleLine="true"
+                android:layout_width="80dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"/>
+
+        </LinearLayout>
+
+    </HorizontalScrollView>
+
+</RelativeLayout>
+
diff --git a/fmapp2/res/layout/frequency_picker.xml b/fmapp2/res/layout/frequency_picker.xml
new file mode 100644
index 0000000..cef47f9
--- /dev/null
+++ b/fmapp2/res/layout/frequency_picker.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright (c) 2013, The Linux Foundation. All rights reserved.
+** Not a Contribution.
+**
+** Copyright 2007, 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_gravity="center_horizontal"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <!-- MHz -->
+    <android.widget.NumberPicker
+        android:id="@+id/mhz"
+        android:layout_width="80dp"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="1dp"
+        android:layout_marginRight="1dp"
+        android:focusable="true"
+        android:focusableInTouchMode="true" />
+
+    <!-- KHz -->
+    <android.widget.NumberPicker
+        android:id="@+id/khz"
+        android:layout_width="80dp"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="1dp"
+        android:layout_marginRight="1dp"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        />
+</LinearLayout>
diff --git a/fmapp2/res/layout/frequency_picker_dialog.xml b/fmapp2/res/layout/frequency_picker_dialog.xml
new file mode 100644
index 0000000..3d95123
--- /dev/null
+++ b/fmapp2/res/layout/frequency_picker_dialog.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright (c) 2013, The Linux Foundation. All rights reserved.
+** Not a Contribution.
+**
+** Copyright 2007, 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.caf.utils.FrequencyPicker xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/frequencyPicker"
+    android:padding="5dp"
+    android:layout_gravity="center_horizontal"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"/>
diff --git a/fmapp/res/layout/navigate.xml b/fmapp2/res/layout/navigate.xml
similarity index 98%
rename from fmapp/res/layout/navigate.xml
rename to fmapp2/res/layout/navigate.xml
index 30cff7e..5e6b665 100644
--- a/fmapp/res/layout/navigate.xml
+++ b/fmapp2/res/layout/navigate.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009, 2012, 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:
diff --git a/fmapp2/res/layout/rename_dialog.xml b/fmapp2/res/layout/rename_dialog.xml
new file mode 100644
index 0000000..2374c9c
--- /dev/null
+++ b/fmapp2/res/layout/rename_dialog.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012, 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, Inc. 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 "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.
+ */
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/rename"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:padding="10dp">
+
+    <EditText android:id="@+id/name"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:inputType="text"
+        android:textColor="#FFF"
+        android:singleLine="true"
+        android:maxLength="16">
+     <requestFocus />
+     </EditText>
+     <RelativeLayout
+         android:layout_width="match_parent"
+         android:layout_height="wrap_content"
+         android:padding="6dp" >
+
+         <Button android:id="@+id/save"
+             android:layout_width="120dp"
+             android:layout_height="wrap_content"
+             android:text="@string/button_ok"
+             android:layout_alignParentLeft="true" />
+
+         <Button android:id="@+id/cancel"
+             android:layout_width="120dp"
+             android:layout_height="wrap_content"
+             android:text="@string/button_cancel"
+             android:layout_alignParentRight="true" />
+
+    </RelativeLayout>
+
+</LinearLayout>
diff --git a/fmapp2/res/layout/station_info.xml b/fmapp2/res/layout/station_info.xml
new file mode 100644
index 0000000..fc7d62e
--- /dev/null
+++ b/fmapp2/res/layout/station_info.xml
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <LinearLayout android:id="@+id/station_info"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:orientation="vertical"
+        android:gravity="top">
+
+        <RelativeLayout android:id="@+id/top_most"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content">
+
+            <ImageView android:id="@+id/signal_level"
+                android:src="@drawable/ic_signal_2"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingLeft="5dp"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentLeft="true"
+                android:visibility="gone" />
+
+            <TextView android:id="@+id/sleep_msg_tv"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:drawableLeft="@drawable/count_down"
+                android:textSize="14sp"
+                android:layout_marginLeft="25dp"
+                android:textStyle="bold"
+                android:visibility="invisible"
+                android:text="@string/default_sleep" />
+
+            <TextView android:id="@+id/record_msg_tv"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:drawableLeft="@drawable/recorder_start"
+                android:layout_marginLeft="20dp"
+                android:textSize="14sp"
+                android:textStyle="bold"
+                android:clickable="true"
+                android:visibility="invisible"
+                android:text="@string/default_record"/>
+
+            <TextView android:id="@+id/stereo_text_tv"
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingRight="16dp"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentRight="true"
+                android:layout_alignBaseline="@id/signal_level"
+                android:textSize="13sp"
+                android:text="@string/default_audio"/>
+
+        </RelativeLayout>
+
+        <LinearLayout android:id="@+id/station_frequency_row"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:paddingTop="5dp"
+            android:paddingBottom="5dp"
+            android:layout_alignWithParentIfMissing="true"
+            android:gravity="center">
+
+            <TextView android:id="@+id/call_sign_tv"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="14sp"
+                android:paddingTop="2dp"
+                android:paddingRight="2dp"
+                android:paddingBottom="2dp"
+                android:paddingLeft="2dp"
+                android:text="@string/station_id_string" />
+
+            <TextView android:id="@+id/pty_tv"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="14sp"
+                android:paddingTop="2dp"
+                android:paddingRight="2dp"
+                android:paddingBottom="2dp"
+                android:paddingLeft="2dp"
+                android:text="@string/pty_string" />
+
+        </LinearLayout>
+
+        <RelativeLayout android:id="@+id/second_layout"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="2dp"
+            android:layout_marginBottom="2dp"
+            android:layout_marginLeft="2dp"
+            android:layout_marginRight="2dp">
+
+            <TextView android:id="@+id/prog_frequency_tv"
+                android:textAppearance="?android:attr/textAppearanceLarge"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="25dp"
+                android:gravity="center"
+                android:layout_toLeftOf="@+id/btn_forward"
+                android:layout_toRightOf="@+id/btn_back"
+                android:text="@string/frequency_string"/>
+
+            <ImageView android:id="@+id/btn_back"
+                android:clickable="true"
+                android:focusable="true"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingLeft="15dp"
+                android:layout_alignParentLeft="true"
+                android:visibility="visible"
+                android:layout_alignWithParentIfMissing="true"
+                android:src="@drawable/btn_arrow_left"/>
+
+            <ImageView android:id="@+id/btn_forward"
+                android:clickable="true"
+                android:focusable="true"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingRight="15dp"
+                android:layout_alignParentRight="true"
+                android:visibility="visible"
+                android:layout_alignWithParentIfMissing="true"
+                android:src="@drawable/btn_arrow_right"/>
+
+         </RelativeLayout>
+
+        <!-- Station Radio Text information display -->
+        <TextView android:id="@+id/radio_text_tv"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textSize="15sp"
+            android:singleLine="true"
+            android:textStyle="bold"
+            android:paddingLeft="2dp"
+            android:paddingRight="2dp"
+            android:paddingBottom="5dp"
+            android:paddingTop="20dp"
+            android:gravity="center_horizontal"
+            android:text="@string/radio_text_string"/>
+
+        <TextView android:id="@+id/eradio_text_tv"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textSize="15sp"
+            android:singleLine="true"
+            android:textStyle="bold"
+            android:paddingLeft="2dp"
+            android:paddingRight="2dp"
+            android:paddingBottom="5dp"
+            android:gravity="center_horizontal"
+            android:text="@string/eradio_text_string"/>
+
+    </LinearLayout>
+
+</merge>
diff --git a/fmapp2/res/layout/station_list.xml b/fmapp2/res/layout/station_list.xml
new file mode 100644
index 0000000..18d31f0
--- /dev/null
+++ b/fmapp2/res/layout/station_list.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012, 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, Inc. 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 "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.
+ */
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+    <!--Change layout_height value "wrap_content" to "fill_parent" can dispaly last item dividing line -->
+    <ListView android:id="@+id/station_list"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent" >
+    </ListView>
+
+</LinearLayout>
diff --git a/fmapp2/res/layout/station_list_item.xml b/fmapp2/res/layout/station_list_item.xml
new file mode 100644
index 0000000..40c05d5
--- /dev/null
+++ b/fmapp2/res/layout/station_list_item.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012, 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, Inc. 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 "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.
+ */
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/item"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical">
+
+   <TableLayout
+       android:id="@+id/TableLayout1"
+       android:layout_width="match_parent"
+       android:layout_height="wrap_content"
+       android:stretchColumns="1">
+
+       <TableRow>
+           <TextView
+               android:id="@+id/fixName"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:paddingLeft="30dp"
+               android:paddingTop="15dp"
+               android:text="@string/station_name" />
+
+           <TextView
+               android:id="@+id/name"
+               android:layout_width="wrap_content"
+               android:layout_height="wrap_content"
+               android:ellipsize="marquee"
+               android:marqueeRepeatLimit="marquee_forever" />
+
+       </TableRow>
+       <TableRow >
+
+	    <TextView
+	        android:id="@+id/freq"
+	        android:layout_width="wrap_content"
+	        android:layout_height="wrap_content"
+	        android:paddingLeft="30dp"
+	        android:paddingBottom="15dp"
+	        android:textSize="20sp"
+	        android:layout_span="2" />
+
+       </TableRow>
+
+    </TableLayout>
+
+</LinearLayout>
diff --git a/fmapp2/res/layout/statusbar.xml b/fmapp2/res/layout/statusbar.xml
new file mode 100644
index 0000000..677ed74
--- /dev/null
+++ b/fmapp2/res/layout/statusbar.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012, 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, Inc. 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 "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.
+ */
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="horizontal">
+
+    <ImageView android:id="@+id/icon"
+        android:layout_gravity="center_vertical"
+        android:paddingLeft="10dp"
+        android:paddingRight="10dp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+    </ImageView>
+
+    <TextView android:id="@+id/frequency"
+        android:textAppearance="?android:attr/textAppearanceMediumInverse"
+        android:textColor="#FFFFFFFF"
+        android:focusable="true"
+        android:ellipsize="marquee"
+        android:singleLine="true"
+        android:layout_gravity="center"
+        android:layout_width="wrap_content"
+       android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/fmapp2/res/values-zh-rCN/arrays.xml b/fmapp2/res/values-zh-rCN/arrays.xml
new file mode 100644
index 0000000..d0a95a0
--- /dev/null
+++ b/fmapp2/res/values-zh-rCN/arrays.xml
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012-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 "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>
+
+  <string-array name="ster_mon_entries">
+    <item>立体声</item>
+    <item>单声道</item>
+  </string-array>
+
+  <string-array name="record_durations_entries">
+    <item>5 分钟</item>
+    <item>15 分钟</item>
+    <item>30 分钟</item>
+    <item>直至停止</item>
+  </string-array>
+
+  <string-array name="sleep_duration_values">
+    <item>15 分钟之后</item>
+    <item>30 分钟之后</item>
+    <item>45 分钟之后</item>
+    <item>1 小时之后</item>
+  </string-array>
+
+  <string-array name="search_category_rbds_entries">
+    <item>全部电台</item>
+    <item>成人点击</item>
+    <item>古典</item>
+    <item>经典摇滚</item>
+    <item>校园</item>
+    <item>乡村</item>
+    <item>紧急</item>
+    <item>紧急  测试</item>
+    <item>外语频道</item>
+    <item>信息频道</item>
+    <item>爵士</item>
+    <item>新闻</item>
+    <item>怀旧</item>
+    <item>老歌</item>
+    <item>个性</item>
+    <item>公共频道</item>
+    <item>宗教音乐</item>
+    <item>宗教交流</item>
+    <item>节奏布鲁斯</item>
+    <item>摇滚</item>
+    <item>轻音乐</item>
+    <item>轻摇滚</item>
+    <item>轻节奏布鲁斯</item>
+    <item>体育</item>
+    <item>交流</item>
+    <item>前40</item>
+    <item>天气</item>
+  </string-array>
+
+  <string-array name="search_category_rds_entries">
+    <item>全部电台</item>
+    <item>文化</item>
+    <item>新闻时事</item>
+    <item>儿童节目</item>
+    <item>乡村音乐</item>
+    <item>记录</item>
+    <item>戏剧</item>
+    <item>轻音乐</item>
+    <item>教育</item>
+    <item>紧急</item>
+    <item>紧急测试</item>
+    <item>经济</item>
+    <item>民族音乐</item>
+    <item>信息</item>
+    <item>爵士音乐</item>
+    <item>轻古典音乐</item>
+    <item>休闲</item>
+    <item>新闻</item>
+    <item>民族音乐</item>
+    <item>其他音乐</item>
+    <item>怀旧</item>
+    <item>听众来电</item>
+    <item>流行音乐</item>
+    <item>宗教</item>
+    <item>摇滚音乐</item>
+    <item>科学</item>
+    <item>古典</item>
+    <item>社会事务</item>
+    <item>体育</item>
+    <item>旅行</item>
+    <item>变奏</item>
+    <item>天气</item>
+  </string-array>
+
+
+  <string-array name="presetlist_edit_category">
+    <item>重命名</item>
+    <item>自动选择</item>
+    <item>删除</item>
+  </string-array>
+
+
+  <string-array name="regional_band_entries">
+    <item>北美</item>
+    <item>欧洲</item>
+    <item>日本</item>
+    <item>日本 (宽频)</item>
+    <item>澳大利亚</item>
+    <item>奥地利</item>
+    <item>比利时</item>
+    <item>巴西</item>
+    <item>中国</item>
+    <item>捷克</item>
+    <item>丹麦</item>
+    <item>芬兰</item>
+    <item>法国</item>
+    <item>德国</item>
+    <item>希腊</item>
+    <item>香港</item>
+    <item>印度</item>
+    <item>爱尔兰</item>
+    <item>意大利</item>
+    <item>韩国</item>
+    <item>墨西哥</item>
+    <item>荷兰</item>
+    <item>新西兰</item>
+    <item>挪威</item>
+    <item>波兰</item>
+    <item>葡萄牙</item>
+    <item>俄罗斯</item>
+    <item>新加坡</item>
+    <item>斯洛伐克</item>
+    <item>西班牙</item>
+    <item>瑞士</item>
+    <item>瑞典</item>
+    <item>台湾</item>
+    <item>土耳其</item>
+    <item>英国</item>
+    <item>美国</item>
+  </string-array>
+
+  <string-array name="regional_band_summary">
+    <item>北美 (87.5MHz - 108.0MHz ,步长 200 Khz)</item>
+    <item>欧洲 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>日本 (76.0MHz - 90.0MHz ,步长 100 Khz)</item>
+    <item>日本 (宽频) (90.0MHz - 108.0MHz ,步长 50 Khz)</item>
+    <item>澳大利亚 (87.7MHz - 108.0MHz , 步长 100 Khz)</item>
+    <item>奥地利 (87.5MHz - 108.0MHz , 步长 50 Khz)</item>
+    <item>比利时 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>巴西 (87.8MHz - 108.0MHz ,步长 200 Khz)</item>
+    <item>中国 (87.0MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>捷克 (87.5MHz - 108.0MHz , 步长 100 Khz)</item>
+    <item>丹麦 (87.5MHz - 108.0MHz ,步长 50 Khz)</item>
+    <item>芬兰 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>法国 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>德国 (87.5MHz - 108.0MHz ,步长 50 Khz)</item>
+    <item>希腊 (87.5MHz - 108.0MHz ,步长 50 Khz)</item>
+    <item>香港 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>印度 (91.0MHz - 106.4MHz ,步长 100 Khz)</item>
+    <item>爱尔兰 (87.5MHz - 108.0MHz ,步长  50 Khz)</item>
+    <item>意大利 (87.5MHz - 108.0MHz , 步长 50 Khz)</item>
+    <item>韩国 (87.5MHz - 108.0MHz ,步长 200 Khz)</item>
+    <item>墨西哥 (88.1MHz - 107.9MHz ,步长  200 Khz)</item>
+    <item>荷兰 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>新西兰 (88.0MHz - 107.0MHz ,步长  100 Khz)</item>
+    <item>挪威 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>波兰 (88.0MHz - 108.0MHz ,步长 50 Khz)</item>
+    <item>葡萄牙 (87.5MHz - 108.0MHz ,步长 50 Khz)</item>
+    <item>俄国 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>新加坡 (88.0MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>斯洛伐克 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>西班牙 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>瑞士 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>瑞典 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>台湾 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>土耳其 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>英国 (87.5MHz - 108.0MHz ,步长 100 Khz)</item>
+    <item>美国 (88.1MHz - 107.9MHz ,步长 200 Khz)</item>
+  </string-array>
+</resources>
diff --git a/fmapp2/res/values-zh-rCN/strings.xml b/fmapp2/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..cbea52b
--- /dev/null
+++ b/fmapp2/res/values-zh-rCN/strings.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2012-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 "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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">FM 收音机</string>
+    <string name="menu_settings">设置</string>
+    <string name="menu_record_start">开始录音</string>
+    <string name="menu_record_stop">停止录音</string>
+    <string name="menu_all_channels">全部频道</string>
+    <string name="app_label_all_channels">全部频道</string>
+    <string name="button_ok">确定</string>
+    <string name="button_cancel">取消</string>
+    <string name="button_delete">删除</string>
+    <string name="error_sdcard_access">不能访问SD卡</string>
+    <string name="fm_service_started">FM 服务</string>
+    <string name="menu_sleep">自动关闭</string>
+    <string name="menu_sleep_cancel">取消自动关闭</string>
+    <string name="menu_scan_start">搜索</string>
+    <string name="button_text_stop">停止</string>
+    <string name="menu_scan_stop">停止搜索</string>
+    <string name="msg_seeking">搜索 FM 电台</string>
+    <string name="msg_scanning">搜索所有 FM 电台</string>
+    <string name="msg_scanning_pty">搜索 "<xliff:g id="pty_name">%1$s</xliff:g>"</string>
+    <string name="msg_noantenna">请插入耳机</string>
+    <!-- The messsage shown when FM radio was turned on, headset was plugged out -->
+    <string name="msg_headset_plug_out">收音机播放中拔出了耳机,收音机已经自动关闭。</string>
+    <string name="dialog_sleep_title">收音机自动关闭</string>
+    <string name="preset_name_dialog_title">输入名称 </string>
+    <string name="preset_name_title">重命名</string>
+    <string name="preset_search_title">搜索</string>
+    <string name="preset_search_name">搜索 "<xliff:g id="preset_name">%1$s</xliff:g>"</string>
+    <string name="preset_add">添加</string>
+    <string name="preset_replace">替换</string>
+    <string name="preset_tune">设定频率</string>
+    <string name="preset_rename">重命名</string>
+    <string name="preset_delete">删除</string>
+    <string name="sel_band_menu">选择地区</string>
+    <string name="settings_menu">设置</string>
+    <string name="regional_band">地区</string>
+    <string name="aud_output_mode">音频输出模式</string>
+    <string name="sel_audio_output">选择音频输出</string>
+    <string name="record_dur">录音时长</string>
+    <string name="sel_rec_dur">选择录音时长</string>
+    <string name="auto_select_af">备用频率</string>
+    <string name="auto_select_af_enabled">自动选择开启</string>
+    <string name="auto_select_af_disabled">自动选择关闭</string>
+    <string name="settings_revert_confirm_title">确定清除设置</string>
+    <string name="settings_revert_confirm_msg">将删除所有设置</string>
+    <string name="settings_back_summary">Return to previous view</string>
+    <string name="settings_revert_defaults_title">恢复出厂设置</string>
+    <string name="settings_revert_defaults_summary">清除所有设置</string>
+    <string name="audio_type_stereo">立体声</string>
+    <string name="audio_type_mono">单声道</string>
+    <string name="spaceIsLow_content">"USB 存储设备空间不足,请更改录音时长设置,或删除某些录音或者其他文件。</string>
+    <string name="alert_dialog_ok">确定</string>
+    <string name="alert_dialog_cancel">取消</string>
+    <string name="search_dialog_title">搜索电台</string>
+
+        <string name="fm_command_timeout_title">超时</string>
+        <string name="fm_tune_timeout_msg">打开FM电台无响应。
+                     如果问题持续, 请重新启动FM收音机。</string>
+        <string name="fm_command_failed_title">FM 操作失败</string>
+        <string name="fm_cmd_failed_msg">FM 操作失败。如果问题持续, 请重新启动FM收音机。
+        </string>
+        <string name="fm_cmd_failed_msg_hdmi">FM 操作失败。 不支持 FM 和 HDMI 并发 。
+        </string>
+        <string name="fm_cmd_failed_call_on">FM 操作失败。通话期间禁止FM音频 </string>
+
+    <string name="station_name">电台:</string>
+    <string name="station_exists">此频率已存在!</string>
+    <string name="stat_notif_frequency">FM 收音机 "<xliff:g id="frequency">%1$s</xliff:g>" MHz</string>
+    <string name="cannot_startup_during_call">通话中不能启动FM!</string>
+    <string name="cannot_startup_during_airplane">"飞行模式中不能启动FM!"</string>
+    <string name="station_list_delete_station">删除:<xliff:g id="name">%s</xliff:g></string>
+    <string name="station_list_delete_station_prompt">要删除 <xliff:g id="name">%s</xliff:g> 吗?</string>
+    <string name="sdcard_no_space_cannot_recording">SD卡空间不足,不能录音</string>
+    <string name="recording_stop_no_space">SD卡空间不足,录音停止</string>
+    <string name="station_name_empty">电台名字不能为空,请新重输入</string>
+    <string name="station_name_exist">已存在名为\"<xliff:g id="name">%s</xliff:g>\"的电台,请输入其他名称。</string>
+    <!-- the title of rename dialog lack of translation -->
+    <string name="dialog_presetlist_rename_title">"请输入名字"</string>
+
+    <!-- prompt message for stopping record -->
+    <string name="save_record_file">"录音已保存至 "<xliff:g id="record_file">%1$s</xliff:g>"</string>
+    <!-- all recordings will show up in the media database with this 'artist' name -->
+    <string name="audio_db_artist_name">我的 FM 录音</string>
+    <!-- all recordings will show up in the media database with this 'album' name -->
+    <string name="audio_db_album_name">FM 录音</string>
+    <!-- all recordings will show up in the media database in a playlist with this name -->
+    <string name="audio_db_playlist_name">FM 录音</string>
+</resources>
diff --git a/fmapp2/res/values-zh-rTW/strings.xml b/fmapp2/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..cf3d605
--- /dev/null
+++ b/fmapp2/res/values-zh-rTW/strings.xml
@@ -0,0 +1,101 @@
+<!--
+Copyright (c) 2012, 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 "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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">FM 收音機</string>
+    <string name="menu_settings">設定</string>
+    <string name="menu_record_start">開始錄音</string>
+    <string name="menu_record_stop">停止錄音</string>
+    <string name="menu_all_channels">全部頻道</string>
+    <string name="app_label_all_channels">全部頻道</string>
+    <string name="button_ok">確定</string>
+    <string name="button_cancel">取消</string>
+    <string name="button_delete">取消</string>
+    <string name="error_sdcard_access">不能訪問SD卡</string>
+    <string name="fm_service_started">FM 服務</string>
+    <string name="menu_sleep">自動關閉</string>
+    <string name="menu_sleep_cancel">取消自動關閉</string>
+    <string name="menu_scan_start">搜索</string>
+    <string name="button_text_stop">停止</string>
+    <string name="menu_scan_stop">停止搜索</string>
+    <string name="msg_seeking">搜索 FM 電台</string>
+    <string name="msg_scanning">搜索所有 FM 電台</string>
+    <string name="msg_scanning_pty">搜索 "<xliff:g id="pty_name">%1$s</xliff:g>"</string>
+    <string name="msg_noantenna">請插入耳機</string>
+    <string name="dialog_sleep_title">收音機自動關閉</string>
+    <string name="preset_name_dialog_title">輸入名稱 </string>
+    <string name="preset_name_title">重命名</string>
+    <string name="preset_search_title">搜索</string>
+    <string name="preset_search_name">搜索 "<xliff:g id="preset_name">%1$s</xliff:g>"</string>
+    <string name="preset_add">添加</string>
+    <string name="preset_replace">替換</string>
+    <string name="preset_tune">設定頻率</string>
+    <string name="preset_rename">重命名</string>
+    <string name="preset_delete">刪除</string>
+    <string name="sel_band_menu">選擇地區</string>
+    <string name="settings_menu">設定</string>
+    <string name="regional_band">地區</string>
+    <string name="aud_output_mode">音頻輸出模式</string>
+    <string name="sel_audio_output">選擇音頻輸出</string>
+    <string name="record_dur">錄音時長</string>
+    <string name="sel_rec_dur">選擇錄音時長</string>
+    <string name="auto_select_af">備用頻率</string>
+    <string name="auto_select_af_enabled">自動選擇開啟</string>
+    <string name="auto_select_af_disabled">自動選擇關閉</string>
+    <string name="settings_revert_confirm_title">確定清除設定</string>
+    <string name="settings_revert_confirm_msg">將刪除所有設定</string>
+    <string name="settings_revert_defaults_title">恢復出廠設定</string>
+    <string name="settings_revert_defaults_summary">清除所有設定</string>
+    <string name="audio_type_stereo">立體聲</string>
+    <string name="audio_type_mono">單聲道</string>
+    <string name="spaceIsLow_content">USB 存儲設備空間不足,請更改錄音時長設置,或刪除某些錄音或者其他檔案。</string>
+    <string name="alert_dialog_ok">確定</string>
+    <string name="alert_dialog_cancel">取消</string>
+    <string name="search_dialog_title">搜索電台</string>
+    <string name="fm_command_timeout_title">超時</string>
+    <string name="fm_tune_timeout_msg">打開FM 電台無響應。如果問題持續,請重新啟動FM 收音機。</string>
+    <string name="fm_command_failed_title">FM 操作失敗</string>
+    <string name="fm_cmd_failed_msg">FM 操作失敗。如果問題持續,請重新啟動FM 收音機。</string>
+    <string name="fm_cmd_failed_msg_hdmi">FM 操作失敗。不支持FM和 HDMI 並發。 </string>
+    <string name="fm_cmd_failed_call_on">FM 操作失敗。通話期間禁止FM音頻 </string>
+    <string name="station_name">電台:</string>
+    <string name="station_exists">此頻率已存在!</string>
+    <string name="stat_notif_frequency">FM 收音機 "<xliff:g id="frequency">%1$s</xliff:g>" MHz</string>
+    <string name="cannot_startup_during_call">通话中不能启动FM!</string>
+    <string name="cannot_startup_during_airplane">"通話中不能啟動FM!"</string>
+    <string name="station_list_delete_station">删除:<xliff:g id="name">%s</xliff:g></string>
+    <string name="station_list_delete_station_prompt">要删除 <xliff:g id="name">%s</xliff:g> 吗?</string>
+    <string name="sdcard_no_space_cannot_recording">SD卡空間不足,不能錄音</string>
+    <string name="recording_stop_no_space">SD卡空間不足,錄音停止</string>
+    <string name="station_name_empty">電台名字不能為空,請新重輸入</string>
+    <string name="station_name_exist">已存在名為\"<xliff:g id="name">%s</xliff:g>\"的電台,請輸入其他名稱。</string>
+    <string name="dialog_presetlist_rename_title">請輸入名字</string>
+
+    <!-- prompt message for stopping record -->
+    <string name="save_record_file">錄音已保存至 "<xliff:g id="record_file">%1$s</xliff:g>"</string>
+</resources>
diff --git a/fmapp2/res/values/arrays.xml b/fmapp2/res/values/arrays.xml
new file mode 100644
index 0000000..cb673c8
--- /dev/null
+++ b/fmapp2/res/values/arrays.xml
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2011, 2012 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>
+
+  <string-array name="ster_mon_entries">
+    <item>Stereo</item>
+    <item>Mono</item>
+  </string-array>
+
+  <string-array name="ster_mon_values">
+    <item>0</item>
+    <item>1</item>
+  </string-array>
+
+  <string-array name="record_durations_entries">
+    <item>5 minutes</item>
+    <item>15 minutes</item>
+    <item>30 minutes</item>
+    <item>Until stopped</item>
+  </string-array>
+
+
+  <string-array name="record_duration_values">
+    <item>5</item>
+    <item>15</item>
+    <item>30</item>
+    <item>-1</item>
+  </string-array>
+
+  <string-array name="sleep_duration_values">
+    <item>15 minutes</item>
+    <item>30 minutes</item>
+    <item>45 minutes</item>
+    <item>1 Hour</item>
+  </string-array>
+
+    <!-- This array should be in seconds and should match the values above -->
+  <string-array name="sleep_duration_values_seconds">
+    <item>900</item>
+    <item>1800</item>
+    <item>2700</item>
+    <item>3600</item>
+  </string-array>
+
+  <string-array name="search_category_rbds_entries">
+    <item>All Stations</item>
+    <item>Adult Hits</item>
+    <item>Classical</item>
+    <item>Classic Rock</item>
+    <item>College</item>
+    <item>Country</item>
+    <item>Emergency</item>
+    <item>Emergency Test</item>
+    <item>Foreign Language</item>
+    <item>Information</item>
+    <item>Jazz</item>
+    <item>News</item>
+    <item>Nostalgia</item>
+    <item>Oldies</item>
+    <item>Personality</item>
+    <item>Public</item>
+    <item>Religious Music</item>
+    <item>Religious Talk</item>
+    <item>Rhythm and Blues</item>
+    <item>Rock</item>
+    <item>Soft</item>
+    <item>Soft Rock</item>
+    <item>Soft Rhythm and Blues</item>
+    <item>Sports</item>
+    <item>Talk</item>
+    <item>Top 40</item>
+    <item>Weather</item>
+  </string-array>
+
+  <string-array name="search_category_rbds_values">
+    <item>0</item>
+    <item>7</item>
+    <item>15</item>
+    <item>6</item>
+    <item>23</item>
+    <item>10</item>
+    <item>31</item>
+    <item>30</item>
+    <item>18</item>
+    <item>2</item>
+    <item>14</item>
+    <item>1</item>
+    <item>13</item>
+    <item>11</item>
+    <item>21</item>
+    <item>22</item>
+    <item>19</item>
+    <item>20</item>
+    <item>16</item>
+    <item>5</item>
+    <item>12</item>
+    <item>8</item>
+    <item>17</item>
+    <item>3</item>
+    <item>4</item>
+    <item>9</item>
+    <item>29</item>
+  </string-array>
+
+
+  <string-array name="search_category_rds_entries">
+    <item>All Stations</item>
+    <item>Culture</item>
+    <item>Current Affairs</item>
+    <item>Children programs</item>
+    <item>Country Music</item>
+    <item>Documentary</item>
+    <item>Drama</item>
+    <item>Easy Listening Music</item>
+    <item>Education</item>
+    <item>Emergency</item>
+    <item>Emergency Test</item>
+    <item>Finance</item>
+    <item>Folk Music</item>
+    <item>Information</item>
+    <item>Jazz Music</item>
+    <item>Light classical</item>
+    <item>Leisure</item>
+    <item>News</item>
+    <item>National Music</item>
+    <item>Other Music</item>
+    <item>Oldies Music</item>
+    <item>Phone In</item>
+    <item>Pop Music</item>
+    <item>Religion</item>
+    <item>Rock Music</item>
+    <item>Science</item>
+    <item>Serious classical</item>
+    <item>Social Affairs</item>
+    <item>Sport</item>
+    <item>Travel</item>
+    <item>Varied</item>
+    <item>Weather</item>
+  </string-array>
+
+  <string-array name="search_category_rds_values">
+    <item>0</item>
+    <item>7</item>
+    <item>2</item>
+    <item>18</item>
+    <item>25</item>
+    <item>29</item>
+    <item>6</item>
+    <item>12</item>
+    <item>5</item>
+    <item>31</item>
+    <item>30</item>
+    <item>17</item>
+    <item>28</item>
+    <item>3</item>
+    <item>24</item>
+    <item>13</item>
+    <item>23</item>
+    <item>1</item>
+    <item>26</item>
+    <item>15</item>
+    <item>27</item>
+    <item>21</item>
+    <item>10</item>
+    <item>20</item>
+    <item>11</item>
+    <item>8</item>
+    <item>14</item>
+    <item>19</item>
+    <item>4</item>
+    <item>22</item>
+    <item>9</item>
+    <item>16</item>
+  </string-array>
+
+  <string-array name="presetlist_edit_category">
+    <item>Rename</item>
+    <item>Auto-Select</item>
+    <item>Delete</item>
+  </string-array>
+
+
+  <string-array name="regional_band_entries">
+    <item>North America</item>
+    <item>Europe</item>
+    <item>Japan</item>
+    <item>Japan (Wide)</item>
+    <item>Australia</item>
+    <item>Austria</item>
+    <item>Belgium</item>
+    <item>Brazil</item>
+    <item>China</item>
+    <item>Czech</item>
+    <item>Denmark</item>
+    <item>Finland</item>
+    <item>France</item>
+    <item>Germany</item>
+    <item>Greece</item>
+    <item>Hong Kong</item>
+    <item>India</item>
+    <item>Ireland</item>
+    <item>Italy</item>
+    <item>Korea</item>
+    <item>Mexico</item>
+    <item>Netherlands</item>
+    <item>New Zealand</item>
+    <item>Norway</item>
+    <item>Poland</item>
+    <item>Portugal</item>
+    <item>Russia</item>
+    <item>Singapore</item>
+    <item>Slovakia</item>
+    <item>Spain</item>
+    <item>Switzerland</item>
+    <item>Sweden</item>
+    <item>Taiwan</item>
+    <item>Turkey</item>
+    <item>United Kingdom </item>
+    <item>United States</item>
+  </string-array>
+
+  <string-array name="regional_band_values">
+    <item>0</item>
+    <item>1</item>
+    <item>2</item>
+    <item>3</item>
+    <item>4</item>
+    <item>5</item>
+    <item>6</item>
+    <item>7</item>
+    <item>8</item>
+    <item>9</item>
+    <item>10</item>
+    <item>11</item>
+    <item>12</item>
+    <item>13</item>
+    <item>14</item>
+    <item>15</item>
+    <item>16</item>
+    <item>17</item>
+    <item>18</item>
+    <item>19</item>
+    <item>20</item>
+    <item>21</item>
+    <item>22</item>
+    <item>23</item>
+    <item>24</item>
+    <item>25</item>
+    <item>26</item>
+    <item>27</item>
+    <item>28</item>
+    <item>29</item>
+    <item>30</item>
+    <item>31</item>
+    <item>32</item>
+    <item>33</item>
+    <item>34</item>
+    <item>35</item>
+  </string-array>
+
+  <string-array name="regional_band_summary">
+    <item>North America (87.5MHz To 108.0MHz In 200 Khz Steps)</item>
+    <item>Europe (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Japan (76.0MHz To  90.0MHz In 100 Khz Steps)</item>
+    <item>Japan (Wide) (90.0MHz To 108.0MHz In 50 Khz Steps)</item>
+    <item>Australia (87.7MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Austria (87.5MHz To 108.0MHz In  50 Khz Steps)</item>
+    <item>Belgium (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Brazil (87.8MHz To 108.0MHz In 200 Khz Step)</item>
+    <item>China (87.0MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Czech (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Denmark (87.5MHz To 108.0MHz In 50 Khz Steps)</item>
+    <item>Finland (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>France (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Germany (87.5MHz To 108.0MHz In 50 Khz Steps)</item>
+    <item>Greece (87.5MHz To 108.0MHz In 50 Khz Steps)</item>
+    <item>Hong Kong (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>India (91.0MHz To 106.4MHz In 100 Khz Steps)</item>
+    <item>Ireland (87.5MHz To 108.0MHz In 50 Khz Steps)</item>
+    <item>Italy (87.5MHz To 108.0MHz In 50 Khz Steps)</item>
+    <item>Korea (87.5MHz To 108.0MHz In 200 Khz Steps)</item>
+    <item>Mexico (88.1MHz To 107.9MHz In 200 Khz Steps)</item>
+    <item>Netherlands (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>New Zealand (88.0MHz To 107.0MHz In 100 Khz Steps)</item>
+    <item>Norway (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Poland (88.0MHz To 108.0MHz In 50 Khz Steps)</item>
+    <item>Portugal (87.5MHz To 108.0MHz In 50 Khz Steps)</item>
+    <item>Russia (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Singapore (88.0MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Slovakia (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Spain (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Switzerland (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Sweden (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Taiwan (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>Turkey (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>United Kingdom (87.5MHz To 108.0MHz In 100 Khz Steps)</item>
+    <item>United States (88.1MHz To 107.9MHz In 200 Khz Steps)</item>
+  </string-array>
+
+  <string-array name="rf_cfg">
+      <item> Get Current Station Parameters</item>
+      <item> Get Station Parameters Repeat 20 times</item>
+      <item> Get Search  station parameters</item>
+      <item> Get FM Band sweep parameters</item>
+      <item> Configure FM Search Parameters</item>
+  </string-array>
+
+  <string-array name="cfg_rf1">
+      <item> Set FM RSSI Delta</item>
+      <item> Set Signal Threshold</item>
+      <item> RF Statistics</item>
+  </string-array>
+
+  <string-array name="cfg_rf2">
+      <item> Set SINR Samples Count</item>
+      <item> Set SINR Threshold</item>
+      <item> Set IntfDetoutLow Threshold</item>
+      <item> Set IntfDetoutHigh Threshold</item>
+      <item> RF Statistics</item>
+  </string-array>
+
+  <string-array name="stats_options">
+      <item> Select the option</item>
+      <item> Configure FM Search parameters</item>
+      <item> RF Statistics</item>
+  </string-array>
+
+</resources>
diff --git a/fmapp2/res/values/strings.xml b/fmapp2/res/values/strings.xml
new file mode 100644
index 0000000..0c46991
--- /dev/null
+++ b/fmapp2/res/values/strings.xml
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">FM Radio New</string>
+    <string name="tx_app_name">FM Tx New</string>
+
+    <string name="default_sleep"></string>
+    <string name="menu_add_to_preset">Add to Presets</string>
+    <string name="menu_settings">Settings</string>
+    <string name="menu_record_start">Start Recording</string>
+    <string name="menu_record_stop">Stop Recording</string>
+    <string name="menu_all_channels">All Channels</string>
+    <string name="app_label_all_channels">All Channels</string>
+    <string name="button_ok">OK</string>
+    <string name="button_cancel">Cancel</string>
+    <string name="button_delete">Delete</string>
+    <string name="error_sdcard_access">Unable to access SD card</string>
+    <string name="fm_service_started">FM Service</string>
+    <string name="menu_sleep">Sleep</string>
+    <string name="menu_sleep_cancel">Cancel Sleep</string>
+    <string name="menu_wired_headset">Wired Headset</string>
+    <string name="menu_speaker_on">Enable Speaker</string>
+    <string name="menu_display_tags">Show Tags</string>
+    <string name="menu_speaker_off">Disable Speaker</string>
+    <string name="menu_scan_start">Scan</string>
+    <string name="menu_scan_stop">Stop Searching</string>
+    <string name="menu_stats">FM RF Stats</string>
+    <string name="button_text_stop">Stop</string>
+    <string name="msg_seeking">Searching FM Station</string>
+    <string name="msg_scanning">Scanning for all FM Stations</string>
+    <string name="msg_scanning_pty">Scanning for "<xliff:g id="pty_name">%1$s</xliff:g>"</string>
+    <string name="msg_search_title">FM - <xliff:g id="frequency_string">%1$s</xliff:g></string>
+    <string name="msg_searching">Searching for Strong Stations to create a Preset List </string>
+    <string name="msg_searching_title">Auto-Select Presets</string>
+    <string name="msg_weak_searching">Searching for frequencies to transmit</string>
+
+    <string name="msg_noantenna">Please plug in a Headset to use FM
+        Radio </string>
+    <string name="msg_headsetpluggedin">Disconnect all Headsets for using FM Tx</string>
+    <string name="msg_callactive">FM Tx is not supported when there is active voice call</string>
+    <string name="dialog_sleep_title">Select Auto-Off Sleep Time</string>
+        <string name="preset_select_name">Select "<xliff:g id="preset_name">%1$s</xliff:g>"</string>
+        <string name="presetlist_select_name">Select "<xliff:g id="presetlist_name">%1$s</xliff:g>"</string>
+    <string name="presetlist_add_new">Add New List</string>
+    <string name="dialog_presetlist_title">Preset Lists</string>
+        <string name="presetlist_prefix_name">FM - </string>
+        <string name="dialog_presetlist_rename_title">Enter a name </string>
+        <string name="dialog_preset_rename_title">Enter a name </string>
+        <string name="presetlist_delete_name">Delete "<xliff:g id="presetlist_name">%1$s</xliff:g>" and its Stations?</string>
+        <string name="presetlist_autoselect_title">Confirm Auto-Select</string>
+        <string name="presetlist_autoselect_name">Auto-Select will delete all the Presets in the list  "<xliff:g id="presetlist_name">%1$s</xliff:g>", Continue?</string>
+        <string name="fmtx_autoselect_name">Auto-Select will delete all the Presets, Continue?</string>
+
+    <string name="enter_frequency">Tune to Station</string>
+    <string name="enter_new_frequency_title">Enter Frequency </string>
+
+    <string name="preset_now_playing">Now Playing </string>
+        <string name="preset_pref_title">"<xliff:g id="preset_name">%1$s</xliff:g>"
+        (<xliff:g id="preset_freq">%2$s</xliff:g>)</string>
+        <string name="preset_delete_title">Delete Preset</string>
+
+        <string name="preset_delete_name">Delete "<xliff:g id="preset_name">%1$s</xliff:g>"
+        from "<xliff:g id="presetlist_name">%2$s</xliff:g>"</string>
+
+        <string name="preset_confirm_delete_name">Delete "<xliff:g id="preset_name">%1$s</xliff:g>"
+        from "<xliff:g id="presetlist_name">%2$s</xliff:g>" ?</string>
+
+    <string name="preset_name_dialog_title">Enter a name </string>
+    <string name="preset_name_summary">"<xliff:g id="preset_name">%1$s</xliff:g>" </string>
+    <string name="preset_name_title">Rename</string>
+
+    <string name="preset_search_title">Search</string>
+    <string name="preset_search_name">Search for "<xliff:g id="preset_name">%1$s</xliff:g>"</string>
+
+    <string name="preset_preference_title">FM Stations in "<xliff:g id="preset_name">%1$s</xliff:g>" </string>
+
+    <string name="preset_empty_title">No Stations in the List</string>
+    <string name="preset_empty_add_summary">Add Stations</string>
+
+    <string name="preset_add">Add</string>
+    <string name="preset_replace">Replace</string>
+    <string name="preset_tune">Tune</string>
+    <string name="preset_rename">Rename</string>
+    <string name="preset_delete">Delete</string>
+    <string name="preset_search">Search for "<xliff:g id="preset_pi">%1$s</xliff:g>"
+        </string>
+
+    <string name="stat_notif_frequency">FM Radio Station "<xliff:g id="frequency">%1$s</xliff:g>" MHz</string>
+    <string name="stat_notif_tx_frequency">FM Transmitting at: "<xliff:g id="frequency">%1$s</xliff:g>"</string>
+
+
+    <string name="sel_band_menu">Select Regional Band</string>
+    <string name="test_menu">Select Test</string>
+
+    <string name="settings_menu">Settings</string>
+    <string name="regional_band">Regional Band</string>
+
+    <string name="aud_output_mode">Audio Output Mode</string>
+    <string name="sel_audio_output">Select Audio Output</string>
+
+    <string name="record_dur">Record Duration</string>
+    <string name="sel_rec_dur">Select Record Duration</string>
+
+    <string name="auto_select_af">Alternate Frequency</string>
+    <string name="auto_select_af_enabled">Auto Select Enabled</string>
+    <string name="auto_select_af_disabled">Auto Select Disabled</string>
+
+    <string name="fac_defaults">Revert to Factory Defaults</string>
+    <string name="revert_to_fac">Revert to Factory Defaults</string>
+    <string name="settings_back">Back</string>
+
+    <string name="settings_revert_confirm_title">Confirm Reset Settings</string>
+    <string name="settings_revert_confirm_msg">This will delete all settings including Presets</string>
+
+    <string name="settings_back_summary">Return to previous view</string>
+    <string name="settings_revert_defaults_title">Revert to Factory Defaults</string>
+    <string name="settings_revert_defaults_summary">Reset all settings</string>
+
+    <string name="audio_type_stereo">Stereo</string>
+    <string name="audio_type_mono">Mono</string>
+
+    <string name="default_band">United States</string>
+    <string name="default_audio">Stereo</string>
+    <string name="default_record_duration">5 minutes</string>
+    <string name="factory_reset_dialog_title">Confirm Reset</string>
+    <string name="factory_reset_dialog_message">This will delete all settings including Presets</string>
+    <string name="station_move">Move</string>
+    <string name="station_edit">Edit</string>
+    <!-- alert to the user that USB storage must be available before using FM recording  [CHAR LIMIT=NONE] -->
+   <string name="no_storage">Mount SD card before start recording.</string>
+   <!-- alert to the user that the USB storage is being disk-checked [CHAR LIMIT=30] -->
+   <string name="preparing_sd">Preparing SD card</string>
+   <!-- alert to the user that the FM fails to read or write the USB storage. [CHAR LIMIT=NONE] -->
+   <string name="access_sd_fail">Couldn\'t access SD card.</string>
+   <!-- Low-memory dialog message [CHAR LIMT=NONE] -->
+   <string name="spaceIsLow_content">Your SD card storage is running out of space. Change the quality setting or delete some images or other files.</string>
+   <!-- The messsage shown when FM record reaches size limit. -->
+   <string name="FMRecording_reach_size_limit">Size limit reached.</string>
+
+    <string name="delete_station_title">Delete</string>
+    <string name="find_af_station">Find</string>
+    <string name="menu_add_list">Add List</string>
+    <string name="menu_rename_list">Rename List</string>
+    <string name="menu_reorder_list">Reorder List</string>
+    <string name="menu_scan_for_preset">Scan for Presets</string>
+    <string name="menu_delete_list">Delete List</string>
+    <string name="alert_dialog_ok">Ok</string>
+    <string name="alert_dialog_cancel">Cancel</string>
+
+    <string name="search_dialog_title">Scan Stations</string>
+
+    <string name="search_category_key">search_category_type</string>
+    <string name="search_category">Select Search Type</string>
+    <string name="search_category_title">Search Type</string>
+    <string name="default_search_category">Seek</string>
+    <string name="search_category_tune">Tune</string>
+
+    <string name="search_category_type_key">search_category_value_type</string>
+    <string name="search_category_type">Select Search by Program Type</string>
+    <string name="search_category_type_title">Search by Program Type</string>
+    <string name="default_search_category_type">All Stations</string>
+
+    <string name="presets_back">Back</string>
+    <string name="presets_back_summary">Return to previous view</string>
+
+    <string name="nav_mode_presets">Presets</string>
+    <string name="nav_mode_stations">Stations</string>
+
+    <string name="prog_service_string"></string>
+    <string name="radio_text_string">This is the long Radio Text String Message that needs to scroll</string>
+    <string name="eradio_text_string">Extended Radio Text Message</string>
+    <string name="pty_string"></string>
+    <string name="frequency_string"></string>
+    <string name="station_id_string"></string>
+
+
+        <string name="fm_command_timeout_title">Timeout</string>
+        <string name="fm_tune_timeout_msg">No response received to Tune FM
+            Station. If problem persists, please turn off FM and turn it back
+            on.</string>
+
+        <string name="fm_command_failed_title">FM Operation failed</string>
+        <string name="fm_cmd_failed_msg">FM operation failed. If problem
+            persists, please turn off FM and turn it back on.
+        </string>
+        <string name="fm_cmd_failed_msg_hdmi">FM operation failed. FM and HDMI concurrecny is not supported.
+        </string>
+        <string name="fm_cmd_failed_call_on">FM operation failed. FM audio is not allowed during call. </string>
+
+    <skip/>
+    <!-- Do not translate. Duration format. -->
+    <string name="durationformat"><xliff:g id="format">%2$d:%5$02d</xliff:g></string>
+
+    <string name="default_record"></string>
+    <string name="default_preset_list_name"> FM List </string>
+    <string name="default_station"> FM </string>
+    <string name="default_blank"> </string>
+    <string name="add_station">+</string>
+    <string name="stop_scanning">Stop Scanning</string>
+    <string name="transmit_msg_string">Transmitting at:</string>
+    <!-- the name under which recordings will be visible in the media database is formatted like this -->
+    <string name="audio_db_title_format"><xliff:g id="format">yyyy-MM-dd HH:mm:ss</xliff:g></string>
+    <!-- all recordings will show up in the media database with this 'artist' name -->
+    <string name="audio_db_artist_name">My FM recordings</string>
+    <!-- all recordings will show up in the media database with this 'album' name -->
+    <string name="audio_db_album_name">FM recordings</string>
+    <!-- all recordings will show up in the media database in a playlist with this name -->
+    <string name="audio_db_playlist_name">FM recordings</string>
+    <string name="test_prompt">Choose a test</string>
+    <string name="test_run">Run Test</string>
+    <string name="set_rmmsi_delta">Configure RMSSI Delta</string>
+    <string name="set_sigth">Configure Signal Th</string>
+    <string name="type_rd"></string>
+    <string name="srch_params">Configure RMSSI Delta</string>
+    <string name="srch_params_1">Configure Signal Th </string>
+    <string name="enter_rssi">Enter RMSSI Delta</string>
+    <string name="enter_sigth">Enter Signal Th</string>
+    <string name="enter_SinrSmplsCnt">Enter SINR Samples Count</string>
+    <string name="set_SinrSmplsCnt">Configure SINR Samples</string>
+    <string name="enter_SinrTh">Enter SINR Threshold</string>
+    <string name="set_SinrTh">Configure SINR Threshold</string>
+    <string name="enter_IntfLowTh">Enter Intf Det Low Threshold</string>
+    <string name="set_IntfLowTh">Config Intf Det Low Threshold</string>
+    <string name="enter_IntfHighTh">Enter Intf Det High Threshold</string>
+    <string name="set_IntfHighTh">Config Intf Det High Threshold</string>
+
+    <string name="station_name">Station:</string>
+    <string name="station_exists">This frequency already exists!</string>
+    <string name="station_list_delete_station">Delete:<xliff:g id="name">%s</xliff:g></string>
+    <string name="station_list_delete_station_prompt">Are you sure to delete <xliff:g id="name">%s</xliff:g> .</string>
+    <string name="station_name_empty">Station name is empty, please input again.</string>
+    <string name="station_name_exist">There is already a station named \"<xliff:g id="name">%s</xliff:g>\". Please input a different name.</string>
+
+    <string name="rt_plus_tags">Tags</string>
+
+</resources>
diff --git a/fmapp2/res/values/styles.xml b/fmapp2/res/values/styles.xml
new file mode 100644
index 0000000..e9c9bcf
--- /dev/null
+++ b/fmapp2/res/values/styles.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2009, 2012, 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>
+    <style name="FMStationSeekBar">
+        <item name="android:indeterminateOnly">false</item>
+        <item name="android:progressDrawable">@android:drawable/progress_horizontal</item>
+        <item name="android:indeterminateDrawable">@android:drawable/progress_horizontal</item>
+        <item name="android:minHeight">20dp</item>
+        <item name="android:maxHeight">20dp</item>
+        <item name="android:thumbOffset">8dp</item>
+        <item name="android:focusable">true</item>
+    </style>
+
+    <style name="ButtonStripLeft">
+        <item name="android:gravity">center</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:background">@drawable/btn_strip_trans_left</item>
+    </style>
+
+    <style name="ButtonStripMiddle">
+        <item name="android:gravity">center</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:background">@drawable/btn_strip_trans_middle</item>
+    </style>
+
+    <style name="ButtonStripRight">
+        <item name="android:gravity">center</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:background">@drawable/btn_strip_trans_right</item>
+    </style>
+
+</resources>
diff --git a/fmapp2/src/com/caf/fmradio/FMAdapterApp.java b/fmapp2/src/com/caf/fmradio/FMAdapterApp.java
new file mode 100644
index 0000000..dbc17c5
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/FMAdapterApp.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @hide
+ */
+
+package com.caf.fmradio;
+
+import android.app.Application;
+import android.util.Log;
+
+public class FMAdapterApp extends Application {
+    private static final String TAG = "FMAdapterApp";
+    private static final boolean DBG = true;
+    //For Debugging only
+    private static int sRefCount=0;
+
+    static {
+        if (DBG) Log.d(TAG,"Loading FM-JNI Library");
+        System.loadLibrary("qcomfm_jni");
+    }
+
+    public FMAdapterApp() {
+        super();
+        if (DBG) {
+            synchronized (FMAdapterApp.class) {
+                sRefCount++;
+                Log.d(TAG, "REFCOUNT: Constructed "+ this + " Instance Count = " + sRefCount);
+            }
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+
+    @Override
+    protected void finalize() {
+        if (DBG) {
+            synchronized (FMAdapterApp.class) {
+                sRefCount--;
+                Log.d(TAG, "REFCOUNT: Finalized: " + this +", Instance Count = " + sRefCount);
+            }
+        }
+    }
+}
diff --git a/fmapp2/src/com/caf/fmradio/FMMediaButtonIntentReceiver.java b/fmapp2/src/com/caf/fmradio/FMMediaButtonIntentReceiver.java
new file mode 100644
index 0000000..9bc4d77
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/FMMediaButtonIntentReceiver.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012-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 "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.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.util.Log;
+import android.view.KeyEvent;
+import android.os.Bundle;
+import java.lang.Object;
+
+public class FMMediaButtonIntentReceiver extends BroadcastReceiver {
+
+private static final String TAG = "FMMediaButtonIntentReceiver";
+public static final String FM_MEDIA_BUTTON = "com.caf.fmradio.action.MEDIA_BUTTON";
+public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+       if ((action != null) && action.equals("android.intent.action.MEDIA_BUTTON")) {
+           KeyEvent event = (KeyEvent)
+                    intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+
+           if (event == null) {
+               return;
+           }
+           int keycode = event.getKeyCode();
+           int key_action = event.getAction();
+           if (((KeyEvent.KEYCODE_HEADSETHOOK == keycode) &&
+               (key_action == KeyEvent.ACTION_DOWN)) ||
+               (KeyEvent.KEYCODE_MEDIA_PAUSE == keycode) ||
+               (KeyEvent.KEYCODE_MEDIA_PLAY == keycode)) {
+
+               Log.d(TAG, "ACTION_MEDIA_BUTTON intent received for ACTION_DOWN");
+               Intent i = new Intent(FM_MEDIA_BUTTON);
+               i.putExtra(Intent.EXTRA_KEY_EVENT, event);
+               context.sendBroadcast(i);
+           }
+       }
+   }
+}
diff --git a/fmapp2/src/com/caf/fmradio/FMRadio.java b/fmapp2/src/com/caf/fmradio/FMRadio.java
new file mode 100644
index 0000000..caa9bb2
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/FMRadio.java
@@ -0,0 +1,3037 @@
+/*
+ * 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.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothDevice;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnKeyListener;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+import android.media.AudioSystem;
+import android.media.AudioManager;
+import android.media.MediaRecorder;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.util.DisplayMetrics;
+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.KeyEvent;
+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.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.text.TextUtils;
+
+import java.util.*;
+import java.io.File;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.ArrayList;
+
+import com.caf.utils.FrequencyPicker;
+import com.caf.utils.FrequencyPickerDialog;
+import android.content.ServiceConnection;
+import android.media.MediaRecorder;
+
+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;
+
+import android.content.SharedPreferences;
+
+public class FMRadio extends Activity
+{
+   public static final String LOGTAG = "FMRadio";
+
+   public static final boolean RECORDING_ENABLE = true;
+   MediaRecorder mRecorder = null;
+
+   /* menu Identifiers */
+   private static final int MENU_SCAN_START = Menu.FIRST + 2;
+   private static final int MENU_SCAN_STOP = Menu.FIRST + 3;
+   private static final int MENU_RECORD_START = Menu.FIRST + 4;
+   private static final int MENU_RECORD_STOP = Menu.FIRST + 5;
+   private static final int MENU_SLEEP = Menu.FIRST + 6;
+   private static final int MENU_SLEEP_CANCEL = Menu.FIRST + 7;
+   private static final int MENU_SETTINGS = Menu.FIRST + 8;
+   private static final int MENU_SPEAKER = Menu.FIRST + 9;
+   private static final int MENU_TAGS = Menu.FIRST + 10;
+   private static final int MENU_STAT_TEST = Menu.FIRST + 11;
+   private static final int MENU_STATION_LIST = Menu.FIRST + 12;
+   /* 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;
+   private static final int DIALOG_PICK_FREQUENCY = 8;
+   private static final int DIALOG_PROGRESS_PROGRESS = 9;
+   private static final int DIALOG_PRESET_OPTIONS = 10;
+   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;
+
+   /* Activity Return ResultIdentifiers */
+   private static final int ACTIVITY_RESULT_SETTINGS = 1;
+
+   /* Activity Return ResultIdentifiers */
+   private static final int MAX_PRESETS_PER_PAGE = 7;
+
+
+   /* Station's Audio is Stereo */
+   private static final int FMRADIO_UI_STATION_AUDIO_STEREO = 1;
+   /* Station's Audio is Mono */
+   private static final int FMRADIO_UI_STATION_AUDIO_MONO = 2;
+
+   /* The duration during which the "Sleep: xx:xx" string will be toggling
+    */
+   private static final int SLEEP_TOGGLE_SECONDS = 60;
+
+   /* The number of Preset Stations to create.
+    * The hardware supports a maximum of 12.
+    */
+   private static final int NUM_AUTO_PRESETS_SEARCH= 12;
+   /*
+    * Command time out: For asynchonous operations, if no response
+    * is received with int this duration, a timeout msg will be displayed.
+    */
+   private static final int CMD_TIMEOUT_DELAY_MS = 5000;
+   private static final int MSG_CMD_TIMEOUT = 101;
+
+   private static final int CMD_NONE = 0;
+   private static final int CMD_TUNE = 1;
+   private static final int CMD_FMON = 2;
+   private static final int CMD_FMOFF = 3;
+   private static final int CMD_FMCONFIGURE = 4;
+   private static final int CMD_MUTE = 5;
+   private static final int CMD_SEEK = 6;
+   private static final int CMD_SCAN = 7;
+   private static final int CMD_SEEKPI = 8;
+   private static final int CMD_SEARCHLIST = 9;
+   private static final int CMD_CANCELSEARCH = 10;
+   private static final int CMD_SET_POWER_MODE = 11;
+   private static final int CMD_SET_AUDIO_MODE = 12;
+   private static final int CMD_SET_AUTOAF = 13;
+   private static final int CMD_GET_INTERNALANTENNA_MODE = 14;
+
+   private static final int PRESETS_OPTIONS_TUNE = 0;
+   private static final int PRESETS_OPTIONS_REPLACE = 1;
+   private static final int PRESETS_OPTIONS_RENAME = 2;
+   private static final int PRESETS_OPTIONS_DELETE = 3;
+   private static final int PRESETS_OPTIONS_SEARCHPI = 4;
+
+   public static final String SCAN_STATION_PREFS_NAME = "scan_station_list";
+   public static final String NUM_OF_STATIONS= "number_of_stations";
+   public static final String STATION_NAME = "name_of_station";
+   public static final String STATION_FREQUENCY = "frequency_of_station";
+
+   private static IFMRadioService mService = null;
+   private static FmSharedPreferences mPrefs;
+
+   /* Button Resources */
+   private ImageView mOnOffButton;
+   private ImageView mMuteButton;
+   private ImageView mSpeakerButton;
+   /* Button to navigate Preset pages */
+   private ImageButton mPresetPageButton;
+   /* 6 Preset Buttons */
+   private Button[] mPresetButtons = {null, null, null, null, null, null, null};
+   private Button mPresetListButton;
+   // private ImageButton mSearchButton;
+   private ImageView mForwardButton;
+   private ImageView mBackButton;
+
+   /* Top row in the station info layout */
+   private ImageView mRSSI;
+   private TextView mProgramServiceTV;
+   private TextView mStereoTV;
+
+   /* Middle row in the station info layout */
+   private TextView mTuneStationFrequencyTV;
+   private TextView mStationCallSignTV;
+   private TextView mProgramTypeTV;
+
+   /* Bottom row in the station info layout */
+   private TextView mRadioTextTV;
+   private TextView mERadioTextTV;
+
+   /* Sleep and Recording Messages */
+   private TextView mSleepMsgTV;
+   private TextView mRecordingMsgTV;
+
+   private double mOutputFreq;
+   private int mPresetPageNumber = 0;
+   private int mStereo = -1;
+
+   // default audio device - speaker
+   private static int mAudioRoute = FMRadioService.RADIO_AUDIO_DEVICE_WIRED_HEADSET;
+   private static boolean mFMStats = false;
+
+
+   /* Current Status Indicators */
+   private static boolean mRecording = false;
+   private static boolean mIsScaning = false;
+   private static boolean mIsSeeking = false;
+   private static boolean mIsSearching = false;
+   private static int mScanPty = 0;
+
+   private Animation mAnimation = null;
+   private ScrollerText mRadioTextScroller = null;
+   private ScrollerText mERadioTextScroller = null;
+
+   private static PresetStation mTunedStation = new PresetStation("", 102100);
+   private PresetStation mPresetButtonStation = null;
+
+   /* Radio Vars */
+   final Handler mHandler = new Handler();
+   /* Search Progress Dialog */
+   private ProgressDialog mProgressDialog = null;
+
+   /* Asynchronous command active */
+   private static int mCommandActive = 0;
+
+   /* Command that failed (Sycnhronous or Asynchronous) */
+   private static int mCommandFailed = 0;
+
+   private  HorizontalNumberPicker mPicker;
+   private int mFrequency;
+
+   /** Index of arrays.xml key word "search_category_rbds_entries or search_category_rds_entries resources*/
+   private int mItemsIndex = -1;
+   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 LoadedDataAndState SavedDataAndState = null;
+
+   /** fm stats property string */
+   public static final String FM_STATS_PROP = "persist.fm.stats";
+
+   /** Called when the activity is first created. */
+   @Override
+   public void onCreate(Bundle savedInstanceState) {
+      super.onCreate(savedInstanceState);
+      setVolumeControlStream(AudioManager.STREAM_MUSIC);
+      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();
+      DisplayMetrics outMetrics = new DisplayMetrics();
+      getWindowManager().getDefaultDisplay().getMetrics(outMetrics );
+
+      setContentView(R.layout.fmradio);
+      SavedDataAndState = (LoadedDataAndState)getLastNonConfigurationInstance();
+
+      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);
+            }
+        });
+      }
+
+      mAnimation = AnimationUtils.loadAnimation(this,
+                                                R.anim.preset_select);
+
+      mMuteButton = (ImageView)findViewById(R.id.btn_silent);
+      if (mMuteButton != null) {
+          mMuteButton.setOnClickListener(mMuteModeClickListener);
+      }
+
+      mSpeakerButton = (ImageView)findViewById(R.id.btn_speaker_earphone);
+      if (mSpeakerButton != null) {
+          mSpeakerButton.setOnClickListener(mSpeakerClickListener);
+      }
+
+      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);
+          mForwardButton.setOnLongClickListener(mForwardLongClickListener);
+      }
+
+      mBackButton = (ImageView)findViewById(R.id.btn_back);
+      if (mBackButton != null) {
+          mBackButton.setOnClickListener(mBackClickListener);
+          mBackButton.setOnLongClickListener(mBackLongClickListener);
+      }
+
+      /* 6 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_PER_PAGE; nButton++) {
+         if (mPresetButtons[nButton] != null) {
+             mPresetButtons[nButton]
+               .setOnClickListener(mPresetButtonClickListener);
+             mPresetButtons[nButton]
+               .setOnLongClickListener(mPresetButtonOnLongClickListener);
+         }
+      }
+
+      mTuneStationFrequencyTV = (TextView)findViewById(R.id.prog_frequency_tv);
+      if (mTuneStationFrequencyTV != null) {
+         mTuneStationFrequencyTV.setOnLongClickListener(mFrequencyViewClickListener);
+      }
+      mProgramServiceTV = (TextView)findViewById(R.id.prog_service_tv);
+      mStereoTV = (TextView)findViewById(R.id.stereo_text_tv);
+
+      mStationCallSignTV = (TextView)findViewById(R.id.call_sign_tv);
+      mProgramTypeTV = (TextView)findViewById(R.id.pty_tv);
+
+      mRadioTextTV = (TextView)findViewById(R.id.radio_text_tv);
+      mERadioTextTV = (TextView)findViewById(R.id.eradio_text_tv);
+      mSleepMsgTV = (TextView)findViewById(R.id.sleep_msg_tv);
+      mRecordingMsgTV = (TextView)findViewById(R.id.record_msg_tv);
+      if (mRecordingMsgTV != null) {
+          mRecordingMsgTV.setOnClickListener(mRecordButtonListener);
+      }
+      /* Disable displaying RSSI */
+      mRSSI = (ImageView)findViewById(R.id.signal_level);
+      if (mRSSI != null) {
+          mRSSI.setVisibility(View.INVISIBLE);
+      }
+
+      if ((mRadioTextScroller == null) && (mRadioTextTV != null)) {
+          mRadioTextScroller = new ScrollerText(mRadioTextTV);
+      }
+
+      if ((mERadioTextScroller == null) && (mERadioTextTV != null)) {
+          mERadioTextScroller = new ScrollerText(mERadioTextTV);
+      }
+
+
+      //HDMI and FM concurrecny is not supported.
+      if (isHdmiOn()) {
+          showDialog(DIALOG_CMD_FAILED_HDMI_ON);
+      }
+      else {
+         if (false == bindToService(this, osc)) {
+             Log.d(LOGTAG, "onCreate: Failed to Start Service");
+         } else {
+             Log.d(LOGTAG, "onCreate: Start Service completed successfully");
+         }
+      }
+   }
+
+   protected void setDisplayvalue(){
+       int max = mPrefs.getUpperLimit();
+       int min = mPrefs.getLowerLimit();
+       int step = mPrefs.getFrequencyStepSize();
+       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);
+       }
+
+       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);
+       }
+       mPicker.setDisplayedValues(displayValues, true);
+       mPicker.setWrapSelectorWheel(true);
+       mPicker.invalidate();
+   }
+   protected int valueToFrequency(int value) {
+       mFrequency = mPrefs.getLowerLimit() + value *
+                             mPrefs.getFrequencyStepSize();
+       return mFrequency;
+   }
+
+   @Override
+   public void onRestart() {
+      Log.d(LOGTAG, "FMRadio: onRestart");
+      try {
+         if (null != mService) {
+              mService.requestFocus();
+         }
+      } catch (Exception e) {
+         e.printStackTrace();
+      }
+      super.onRestart();
+   }
+
+   @Override
+   public void onStop() {
+      Log.d(LOGTAG, "FMRadio: onStop");
+      if(isSleepTimerActive()) {
+          mSleepUpdateHandlerThread.interrupt();
+          long timeNow = ((SystemClock.elapsedRealtime()));
+          if (timeNow < mSleepAtPhoneTime) {
+              try {
+                if (null != mService) {
+                    mService.delayedStop((mSleepAtPhoneTime - timeNow),
+                                               FMRadioService.STOP_SERVICE);
+                }
+              }catch (Exception e) {
+                e.printStackTrace();
+              }
+          }
+      }
+      if(isRecordTimerActive()) {
+          try {
+              if (null != mRecordUpdateHandlerThread) {
+                  mRecordUpdateHandlerThread.interrupt();
+              }
+          }catch (NullPointerException e) {
+              e.printStackTrace();
+          }
+          long rtimeNow = ((SystemClock.elapsedRealtime()));
+          if (rtimeNow < mRecordDuration) {
+              try {
+                if (null != mService) {
+                    mService.delayedStop((mRecordDuration - rtimeNow),
+                                              FMRadioService.STOP_RECORD);
+                }
+              }catch (Exception e) {
+                e.printStackTrace();
+              }
+          }
+      }
+      super.onStop();
+   }
+
+   @Override
+   public void onStart() {
+      super.onStart();
+      Log.d(LOGTAG, "FMRadio: onStart");
+      try {
+         if(mService != null) {
+            mService.registerCallbacks(mServiceCallbacks);
+         }
+      }catch (RemoteException e) {
+         e.printStackTrace();
+      }
+      if(isSleepTimerActive()) {
+          Log.d(LOGTAG, "isSleepTimerActive is true");
+          try {
+            if (null != mService) {
+                mService.cancelDelayedStop(FMRadioService.STOP_SERVICE);
+            }
+          } catch (Exception e) {
+            e.printStackTrace();
+          }
+          initiateSleepThread();
+      }
+      if(isRecordTimerActive()) {
+          Log.d(LOGTAG, "isRecordTimerActive is true");
+          try {
+            if (null != mService) {
+                mService.cancelDelayedStop(FMRadioService.STOP_RECORD);
+            }
+          }catch (Exception e) {
+            e.printStackTrace();
+          }
+          if(isRecording()) {
+              initiateRecordThread();
+          }
+      }
+   }
+
+   @Override
+   protected void onPause() {
+      Log.d(LOGTAG, "FMRadio: onPause");
+      super.onPause();
+      mRadioTextScroller.stopScroll();
+      mERadioTextScroller.stopScroll();
+      FmSharedPreferences.setTunedFrequency(mTunedStation.getFrequency());
+      mPrefs.Save();
+   }
+
+   @Override
+   public void onResume() {
+      super.onResume();
+      Log.d(LOGTAG, "FMRadio: onResume");
+      mPrefs.Load();
+      if (mPicker != null) {
+          setDisplayvalue();
+      }
+      PresetStation station = new PresetStation("",
+                                   FmSharedPreferences.getTunedFrequency());
+      if (station != null) {
+          mTunedStation.Copy(station);
+      }
+      mHandler.post(mUpdateProgramService);
+      mHandler.post(mUpdateRadioText);
+      mHandler.post(mOnStereo);
+      mUpdatePickerValue = true;
+      updateStationInfoToUI();
+      enableRadioOnOffUI();
+   }
+   private class LoadedDataAndState {
+      public LoadedDataAndState(){};
+      public boolean onOrOff;
+   }
+   @Override
+   public Object onRetainNonConfigurationInstance() {
+      final 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 void onDestroy() {
+      Log.d(LOGTAG, "FMRadio: onDestroy");
+      cleanupTimeoutHandler();
+      if (mService != null) {
+          try {
+               if(!mService.isFmOn()) {
+                  endSleepTimer();
+               }
+          }catch (RemoteException e) {
+               e.printStackTrace();
+          }
+      }
+      unbindFromService(this);
+      mService = null;
+      Log.d(LOGTAG, "onDestroy: unbindFromService completed");
+      super.onDestroy();
+   }
+
+   @Override
+   public boolean onCreateOptionsMenu(Menu menu) {
+      super.onCreateOptionsMenu(menu);
+      MenuItem item;
+      boolean radioOn = isFmOn();
+      boolean recording = isRecording();
+      boolean mSpeakerPhoneOn = isSpeakerEnabled();
+      boolean sleepActive = isSleepTimerActive();
+      boolean searchActive = isScanActive() || isSeekActive();
+
+      item = menu.add(0, MENU_SCAN_START, 0, R.string.menu_scan_start).
+                            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);
+      }
+
+      if (RECORDING_ENABLE) {
+          item = menu.add(0, MENU_RECORD_START, 0, R.string.menu_record_start)
+                              .setIcon(R.drawable.ic_menu_record);
+          if (item != null) {
+             item.setVisible(true);
+             item.setEnabled((!recording) && radioOn);
+          }
+          item = menu.add(0, MENU_RECORD_STOP, 0, R.string.menu_record_stop)
+                              .setIcon(R.drawable.ic_menu_record);
+          if (item != null) {
+             item.setVisible(true);
+             item.setEnabled(recording && radioOn);
+          }
+      }
+      /* Settings can be active */
+      item = menu.add(0, MENU_SETTINGS, 0, R.string.menu_settings).
+                              setIcon(android.R.drawable.ic_menu_preferences);
+
+      item = menu.add(0, MENU_SLEEP, 0, R.string.menu_sleep).
+                              setTitle(R.string.menu_sleep);
+      if (item != null) {
+          item.setVisible((!sleepActive) && radioOn);
+      }
+      item = menu.add(0, MENU_SLEEP_CANCEL, 0, R.string.menu_sleep_cancel).
+                              setTitle(R.string.menu_sleep_cancel);
+      if (item != null) {
+          item.setVisible(sleepActive && radioOn);
+      }
+      mFMStats = SystemProperties.getBoolean(FM_STATS_PROP, false);
+      if(mFMStats) {
+          item = menu.add(0, MENU_STAT_TEST, 0,R.string.menu_stats).
+                             setIcon(android.R.drawable.ic_menu_info_details);
+      }
+      menu.add(0, MENU_STATION_LIST, 0, R.string.menu_all_channels);
+      item = menu.add(0, MENU_TAGS, 0, R.string.menu_display_tags);
+      return true;
+   }
+
+   @Override
+   public boolean onPrepareOptionsMenu(Menu menu) {
+      super.onPrepareOptionsMenu(menu);
+      MenuItem item;
+      boolean radioOn = isFmOn();
+      boolean recording = isRecording();
+      boolean mSpeakerPhoneOn = isSpeakerEnabled();
+      boolean searchActive = isScanActive() || isSeekActive();
+
+      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);
+      }
+      if (RECORDING_ENABLE) {
+         item = menu.findItem(MENU_RECORD_START);
+         if (item != null) {
+            item.setVisible(true);
+            item.setEnabled((!recording) && radioOn && (!isAnalogModeEnabled()));
+         }
+         item = menu.findItem(MENU_RECORD_STOP);
+         if (item != null) {
+             item.setVisible(true);
+             item.setEnabled(recording && radioOn && (!isAnalogModeEnabled()));
+         }
+      }
+
+      boolean sleepActive = isSleepTimerActive();
+      item = menu.findItem(MENU_SLEEP);
+      if (item != null) {
+          item.setVisible((!sleepActive) && radioOn);
+      }
+      item = menu.findItem(MENU_SLEEP_CANCEL);
+      if (item != null) {
+          item.setVisible(sleepActive && 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,true);
+         startActivityForResult(launchPreferencesIntent,
+                                ACTIVITY_RESULT_SETTINGS);
+         return true;
+      case MENU_STAT_TEST:
+          Intent launchFMStatIntent = new Intent().setClass(this,
+                                                            FMStats.class);
+          startActivity(launchFMStatIntent);
+          return true;
+      case MENU_SCAN_START:
+         showDialog(DIALOG_SEARCH);
+         return true;
+      case MENU_SCAN_STOP:
+         cancelSearch();
+         return true;
+      case MENU_RECORD_START:
+         startRecording();
+         return true;
+      case MENU_RECORD_STOP:
+         stopRecording();
+         return true;
+      case MENU_SLEEP:
+         showDialog(DIALOG_SLEEP);
+         return true;
+      case MENU_SLEEP_CANCEL:
+         DebugToasts("Sleep Cancelled", Toast.LENGTH_SHORT);
+         endSleepTimer();
+         return true;
+      case MENU_STATION_LIST:
+          Intent stationListIntent = new Intent().setClass(this,
+                  StationListActivity.class);
+          startActivity(stationListIntent);
+          return true;
+      case MENU_TAGS:
+          Intent launchFMTagsIntent = new Intent().setClass(this,
+                                                            FmTags.class);
+          startActivity(launchFMTagsIntent);
+          return true;
+      default:
+          break;
+      }
+      return super.onOptionsItemSelected(item);
+   }
+
+   private boolean isHdmiOn() {
+     //HDMI and FM concurrecny is not supported.
+          try {
+              String hdmiUserOption = android.provider.Settings.System.getString(
+                                            getContentResolver(), "HDMI_USEROPTION");
+          }catch (Exception ex) {
+          }
+          return false;
+   }
+
+   private void enableSpeaker() {
+    //This method with toggle Speaker phone based on existing state .
+       boolean bSpeakerPhoneOn = isSpeakerEnabled();
+       if(mService != null) {
+           try {
+               if (bSpeakerPhoneOn) {  // as Speaker is already on turn it off.
+                   mService.enableSpeaker(false);
+                   Log.d(LOGTAG, "Speaker phone is  turned off");
+                   mSpeakerButton.setImageResource(R.drawable.btn_earphone);
+               }else { // as Speaker is off turn it on.
+                   mService.enableSpeaker(true);
+                   Log.d(LOGTAG, "Speaker phone is turned on");
+                   mSpeakerButton.setImageResource(R.drawable.btn_speaker);
+               }
+               invalidateOptionsMenu();
+           }catch (RemoteException e) {
+               e.printStackTrace();
+           }
+       }
+   }
+
+   private static final int RECORDTIMER_EXPIRED = 0x1003;
+   private static final int RECORDTIMER_UPDATE = 0x1004;
+
+   private boolean hasRecordTimerExpired() {
+      boolean expired = true;
+      /* If record duration is 'until stopped' then return false and exit */
+      if (mRecordUntilStopped)
+          return false;
+      if (isRecordTimerActive()) {
+         long timeNow = ((SystemClock.elapsedRealtime()));
+         //Log.d(LOGTAG, "hasSleepTimerExpired - " + mSleepAtPhoneTime + " now: "+ timeNow);
+         if ((mRecording == false) || (timeNow < mRecordDuration)) {
+             expired = false;
+         }
+      }
+      return expired;
+   }
+
+   private boolean isRecordTimerActive() {
+      boolean active = false;
+      if (mRecordDuration > 0) {
+          active = true;
+      }
+      return active;
+   }
+
+   private void updateExpiredRecordTime() {
+      int vis = View.VISIBLE;
+      if (mRecordUntilStopped || isRecordTimerActive()) {
+         long timeNow = ((SystemClock.elapsedRealtime()));
+         if (mRecordUntilStopped || (mRecordDuration >= timeNow)) {
+            long seconds = (timeNow - mRecordStartTime) / 1000;
+            String Msg = makeTimeString(seconds);
+            mRecordingMsgTV.setText(Msg);
+         }else {
+            /* Clean up timer */
+            mRecordDuration = 0;
+         }
+      }
+      mRecordingMsgTV.setVisibility(vis);
+   }
+
+   /* Recorder Thread processing */
+   private Runnable doRecordProcessing = new Runnable() {
+      public void run() {
+         boolean recordTimerExpired;
+         if (mRecordUntilStopped) {
+             recordTimerExpired = false;
+         }else {
+             recordTimerExpired = hasRecordTimerExpired();
+         }
+         while ((recordTimerExpired == false) &&
+                  (!Thread.currentThread().isInterrupted())) {
+            try {
+                Thread.sleep(500);
+                Message statusUpdate = new Message();
+                statusUpdate.what = RECORDTIMER_UPDATE;
+                mUIUpdateHandlerHandler.sendMessage(statusUpdate);
+                recordTimerExpired = hasRecordTimerExpired();
+            }catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            }
+            if(true == recordTimerExpired) {
+               Message finished = new Message();
+               finished.what = RECORDTIMER_EXPIRED;
+               mUIUpdateHandlerHandler.sendMessage(finished);
+            }
+         }
+      }
+   };
+
+   private static long mRecordDuration = 0;
+   private static long mRecordStartTime = 0;
+   private static boolean mRecordUntilStopped = false;
+   private Thread mRecordUpdateHandlerThread = null;
+
+   private void initiateRecordDurationTimer(long mins) {
+
+      if(mins == FmSharedPreferences.RECORD_DUR_INDEX_3_VAL) {
+          mRecordUntilStopped = true;
+          mRecordStartTime = SystemClock.elapsedRealtime();
+      }else {
+          mRecordUntilStopped = false;
+          mRecordDuration = (mRecordStartTime = SystemClock.elapsedRealtime())
+                                   +
+                            (mins * 60 * 1000);
+      }
+
+      Log.d(LOGTAG, "Stop Recording in mins: " + mins);
+      initiateRecordThread();
+    }
+    private void initiateRecordThread() {
+      if (mRecordUpdateHandlerThread == null) {
+          mRecordUpdateHandlerThread = new Thread(null, doRecordProcessing,
+                                                "RecordUpdateThread");
+      }
+      /* Launch the dummy thread to simulate the transfer progress */
+      Log.d(LOGTAG, "Thread State: " + mRecordUpdateHandlerThread.getState());
+      if (mRecordUpdateHandlerThread.getState() == Thread.State.TERMINATED) {
+          mRecordUpdateHandlerThread = new Thread(null, doRecordProcessing,
+                                                "RecordUpdateThread");
+      }
+      /* If the thread state is "new" then the thread has not yet started */
+      if (mRecordUpdateHandlerThread.getState() == Thread.State.NEW) {
+          mRecordUpdateHandlerThread.start();
+      }
+   }
+
+   private void audioRoute (int audioDevice) {
+      boolean bStatus;
+      if (mService != null) {
+         try {
+             bStatus = mService.routeAudio(audioDevice);
+         }catch (RemoteException e) {
+             e.printStackTrace();
+         }
+      }
+   }
+
+   @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);
+      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(FmSharedPreferences.DEFAULT_NO_FREQUENCY);
+                  }
+               }
+            }
+         } //if ACTIVITY_RESULT_SETTINGS
+      }//if (resultCode == RESULT_OK)
+   }
+
+   /**
+    * @return true if a wired headset is connected.
+    */
+   boolean isWiredHeadsetAvailable() {
+      boolean bAvailable = false;
+      if(mService != null) {
+         try {
+            bAvailable = mService.isWiredHeadsetAvailable();
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+      Log.e(LOGTAG, "isWiredHeadsetAvailable: " + bAvailable);
+      return bAvailable;
+   }
+
+    /**
+     * @return true if a internal antenna is available.
+     *
+     */
+    boolean isAntennaAvailable() {
+       boolean bAvailable = false;
+       if(mService != null) {
+          try {
+             bAvailable = mService.isAntennaAvailable();
+          }catch (RemoteException e) {
+             e.printStackTrace();
+          }
+       }
+       return bAvailable;
+    }
+
+    boolean isCallActive(){
+        boolean bCallActive = false;
+        if(mService != null) {
+            try {
+                bCallActive = mService.isCallActive();
+            }catch (RemoteException e) {
+                e.printStackTrace();
+            }
+        }
+        return bCallActive;
+    }
+
+   private Dialog createSearchDlg(int id, AlertDialog.Builder dlgBuilder) {
+      String[] items;
+      dlgBuilder.setIcon(R.drawable.ic_btn_search);
+      dlgBuilder.setTitle(getString(R.string.search_dialog_title));
+      /* Pick RBDS or RDS */
+      if(FmSharedPreferences.isRBDSStd()) {
+         items = getResources().getStringArray(R.array.search_category_rbds_entries);
+      }else { // if(FmSharedPreferences.isRDSStd())
+         items = getResources().getStringArray(R.array.search_category_rds_entries);
+      }
+      dlgBuilder.setItems(items, new DialogInterface.OnClickListener() {
+          public void onClick(DialogInterface dialog, int item) {
+             String[] items;
+             String[] values;
+
+             mItemsIndex = item ;
+             /* Pick RBDS or RDS */
+             if(FmSharedPreferences.isRBDSStd()) {
+                items = getResources().
+                              getStringArray(R.array.search_category_rbds_entries);
+                values = getResources().
+                              getStringArray(R.array.search_category_rbds_values);
+             }else { // if(FmSharedPreferences.isRDSStd())
+                items = getResources().
+                              getStringArray(R.array.search_category_rds_entries);
+                values = getResources().
+                              getStringArray(R.array.search_category_rds_values);
+             }
+             if ((items != null) && (values != null) && (item >= 0)) {
+                 if ((item >= 0) && (item <= items.length)
+                       && (item <= items.length)) {
+                    DebugToasts("Search Stations for : " + items[item]
+                                + " (" + values[item] + ")",
+                                Toast.LENGTH_SHORT);
+                    int pty = Integer.parseInt(values[item]);
+                    clearStationList();
+                    initiateSearch(pty);
+                 }
+             }
+             removeDialog(DIALOG_SEARCH);
+          }
+      });
+      return dlgBuilder.create();
+   }
+
+   private Dialog createPresetOptionsDlg(int id, AlertDialog.Builder dlgBuilder) {
+      if(mPresetButtonStation != null) {
+         dlgBuilder.setTitle(mPresetButtonStation.getName());
+         ArrayList<String> arrayList = new ArrayList<String>();
+         //PRESETS_OPTIONS_TUNE=0
+         arrayList.add(getResources().getString(R.string.preset_tune));
+         //PRESETS_OPTIONS_REPLACE=1
+         arrayList.add(getResources().getString(R.string.preset_replace));
+         //PRESETS_OPTIONS_RENAME=2
+         arrayList.add(getResources().getString(R.string.preset_rename));
+         //PRESETS_OPTIONS_DELETE=3
+         arrayList.add(getResources().getString(R.string.preset_delete));
+         String piString = mPresetButtonStation.getPIString();
+         if (!TextUtils.isEmpty(piString)) {
+            //PRESETS_OPTIONS_SEARCHPI=4
+            arrayList.add(getResources().getString(R.string.preset_search, piString));
+         }
+
+         dlgBuilder.setCancelable(true);
+         dlgBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {
+            public void onCancel(DialogInterface dialog) {
+               mPresetButtonStation = null;
+               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(mPresetButtonStation != null) {
+                   switch(item) {
+                   case PRESETS_OPTIONS_TUNE: {
+                         // Tune to the station
+                         tuneRadio(mPresetButtonStation.getFrequency());
+                         mPresetButtonStation = null;
+                         break;
+                      }
+                   case PRESETS_OPTIONS_REPLACE: {
+                         // Replace preset Station with currently tuned station
+                         if(!stationExists(mTunedStation)) {
+                            Log.d(LOGTAG, "station - " + mPresetButtonStation.getName() + " ("
+                               + mPresetButtonStation.getFrequency() + ")");
+                            mPresetButtonStation.Copy(mTunedStation);
+                            mPresetButtonStation = null;
+                            setupPresetLayout();
+                            mPrefs.Save();
+                         }
+                         break;
+                      }
+                   case PRESETS_OPTIONS_RENAME: {
+                         // Rename
+                         showDialog(DIALOG_PRESET_RENAME);
+                         break;
+                      }
+                   case PRESETS_OPTIONS_DELETE: {
+                         // Delete
+                         int curListIndex = FmSharedPreferences.getCurrentListIndex();
+                         FmSharedPreferences.removeStation(curListIndex, mPresetButtonStation);
+                         if (mPresetButtonStation.getFrequency() == mTunedStation.getFrequency()) {
+                             // Restore current tuned station's name as its frequency
+                             mTunedStation.setName("");
+                         }
+                         mPresetButtonStation = null;
+                         setupPresetLayout();
+                         mPrefs.Save();
+                         break;
+                      }
+                   case PRESETS_OPTIONS_SEARCHPI: {
+                         // SearchPI
+                         String piString = mPresetButtonStation.getPIString();
+                         int pi = mPresetButtonStation.getPI();
+                         if ((!TextUtils.isEmpty(piString)) &&  (pi > 0)) {
+                            initiatePISearch(pi);
+                         }
+                         mPresetButtonStation = null;
+                         break;
+                      }
+                   default: {
+                         // Should not happen
+                         mPresetButtonStation = null;
+                         break;
+                      }
+                   }//switch item
+                }//if(mPresetButtonStation != null)
+                removeDialog (DIALOG_PRESET_OPTIONS);
+             }//onClick
+         });
+         return dlgBuilder.create();
+      }
+      return null;
+   }
+
+   private Dialog createSleepDlg(int id, AlertDialog.Builder dlgBuilder) {
+      dlgBuilder.setTitle(R.string.dialog_sleep_title);
+      String[] items = getResources().getStringArray(R.array.sleep_duration_values);
+
+      dlgBuilder.setItems(items, new DialogInterface.OnClickListener() {
+          public void onClick(DialogInterface dialog, int item) {
+              String[] items = getResources().getStringArray(R.array.sleep_duration_values);
+              Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
+              if ((item >= 0) && (item <= items.length)) {
+                 long seconds = (long) (900 * (item + 1));
+                 initiateSleepTimer(seconds);
+              }
+              removeDialog (DIALOG_SLEEP);
+          }
+      });
+      return dlgBuilder.create();
+   }
+
+   private Dialog createProgressDialog(int id) {
+      String msgStr = "";
+      String titleStr = "";
+      double frequency = mTunedStation.getFrequency() / 1000.0;
+      boolean bSearchActive = false;
+
+      if (isSeekActive()) {
+          msgStr = getString(R.string.msg_seeking);
+          bSearchActive = true;
+      }else if (isScanActive()) {
+          String ptyStr = PresetStation.parsePTY(mScanPty);
+          if (!TextUtils.isEmpty(ptyStr)) {
+             msgStr = getString(R.string.msg_scanning_pty, ptyStr);
+          }else {
+             msgStr = getString(R.string.msg_scanning);
+          }
+          titleStr = getString(R.string.msg_search_title, ("" + frequency));
+          bSearchActive=true;
+      }else if (isSearchActive()) {
+         msgStr = getString(R.string.msg_searching);
+         titleStr = getString(R.string.msg_searching_title);
+         bSearchActive = true;
+      }
+      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);
+              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();
+                }
+              });
+              mProgressDialog.setOnKeyListener(new OnKeyListener() {
+                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
+                    Log.d(LOGTAG, "OnKeyListener event received in ProgressDialog" + 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;
+                }
+            });
+          }
+          Message msg = new Message();
+          msg.what = TIMEOUT_PROGRESS_DLG;
+          mSearchProgressHandler.sendMessageDelayed(msg, SHOWBUSY_TIMEOUT);
+      }
+      return mProgressDialog;
+   }
+
+   private void updateSelectPresetListDlg(ListView lv) {
+      if (lv != null) {
+         List<PresetList> presetLists = FmSharedPreferences.getPresetLists();
+         ListIterator<PresetList> presetIter;
+         presetIter = presetLists.listIterator();
+         int numLists = presetLists.size();
+         int curIndex = FmSharedPreferences.getCurrentListIndex();
+         ArrayAdapter<String> typeAdapter = new ArrayAdapter<String>
+                                                (this, android.R.layout.
+                                                simple_list_item_single_choice);
+         for (int stationIter = 0; stationIter < numLists; stationIter++) {
+            PresetList temp = presetIter.next();
+            if (temp != null) {
+               typeAdapter.add(getString(R.string.presetlist_select_name,
+                                           temp.getName()));
+            }
+         }
+         typeAdapter.add(getString(R.string.presetlist_add_new));
+         lv.setAdapter(typeAdapter);
+         lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+         lv.clearChoices();
+         if (curIndex >= numLists) {
+             curIndex = 0;
+         }
+         if (lv.getCount() >= curIndex) {
+            lv.setItemChecked(curIndex, true);
+            lv.setSelection(curIndex);
+         }else {
+            lv.setItemChecked(0, true);
+            lv.setSelection(0);
+         }
+      }
+   }
+
+   private Dialog createPresetRenameDlg(int id, AlertDialog.Builder dlgBuilder) {
+      if(mPresetButtonStation == null) {
+         return null;
+      }
+      LayoutInflater factory = LayoutInflater.from(this);
+      final View textEntryView = factory.inflate(
+                                                R.layout.alert_dialog_text_entry, null);
+      dlgBuilder.setTitle(R.string.dialog_presetlist_rename_title);
+      dlgBuilder.setView(textEntryView);
+      dlgBuilder.setPositiveButton(R.string.alert_dialog_ok,
+                                   new DialogInterface.OnClickListener() {
+                                      public void onClick(DialogInterface dialog, int whichButton) {
+                                         //int curList = FmSharedPreferences.getCurrentListIndex();
+
+                                         EditText mTV = (EditText) textEntryView
+                                         .findViewById(R.id.list_edit);
+                                         CharSequence newName = null;
+                                         if (mTV != null) {
+                                            newName = mTV.getEditableText();
+                                         }
+                                         String nName = String.valueOf(newName);
+                                         mPresetButtonStation.setName(nName);
+                                         mPresetButtonStation=null;
+                                         setupPresetLayout();
+                                         mPrefs.Save();
+                                         removeDialog(DIALOG_PRESET_RENAME);
+                                      }
+                                   });
+      dlgBuilder.setNegativeButton(R.string.alert_dialog_cancel,
+                                   new DialogInterface.OnClickListener() {
+                                      public void onClick(DialogInterface dialog, int whichButton) {
+                                         removeDialog(DIALOG_PRESET_RENAME);
+                                      }
+                                   });
+      return(dlgBuilder.create());
+   }
+
+   private Dialog createCmdTimeoutDlg(int id, AlertDialog.Builder dlgBuilder) {
+      if(mCommandActive > 0) {
+         dlgBuilder.setIcon(R.drawable.alert_dialog_icon)
+                   .setTitle(R.string.fm_command_timeout_title);
+         dlgBuilder.setMessage(R.string.fm_tune_timeout_msg);
+         dlgBuilder.setPositiveButton(R.string.alert_dialog_ok,
+                                      new DialogInterface.OnClickListener() {
+                                         public void onClick(DialogInterface dialog,
+                                                             int whichButton) {
+                                            cleanupTimeoutHandler();
+                                            removeDialog(DIALOG_CMD_TIMEOUT);
+                                         }
+                                      });
+         return(dlgBuilder.create());
+      }else {
+         return(null);
+      }
+   }
+
+   private Dialog createCmdFailedDlg(int id, AlertDialog.Builder dlgBuilder) {
+      dlgBuilder.setIcon(R.drawable.alert_dialog_icon)
+                .setTitle(R.string.fm_command_failed_title);
+      dlgBuilder.setMessage(R.string.fm_cmd_failed_msg);
+
+      dlgBuilder.setPositiveButton(R.string.alert_dialog_ok,
+                                   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);
+                                         mCommandFailed = CMD_NONE;
+                                      }
+                                   });
+
+      return(dlgBuilder.create());
+   }
+
+   private Dialog createCmdFailedDlgCallOn(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_call_on);
+
+       dlgBuilder.setPositiveButton(R.string.alert_dialog_ok,
+                                    new DialogInterface.OnClickListener() {
+                                       public void onClick(DialogInterface dialog,
+                                                           int whichButton) {
+                                          removeDialog(DIALOG_CMD_TIMEOUT);
+                                          mCommandFailed = CMD_NONE;
+                                       }
+                                    });
+
+       return(dlgBuilder.create());
+    }
+   private void RestoreDefaults() {
+      FmSharedPreferences.SetDefaults();
+      mPrefs.Save();
+   }
+
+   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();
+          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();
+          Log.d(LOGTAG, "Tune Down: to " + frequency);
+          tuneRadio(frequency);
+      }
+   };
+
+   private View.OnLongClickListener mForwardLongClickListener =
+      new View.OnLongClickListener() {
+        public boolean onLongClick(View view) {
+          SeekNextStation();
+          return true;
+        }
+   };
+
+   private View.OnLongClickListener mBackLongClickListener =
+      new View.OnLongClickListener() {
+        public boolean onLongClick(View view) {
+          SeekPreviousStation();
+          return true;
+        }
+   };
+
+   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) {
+          mPresetPageNumber++;
+          setupPresetLayout();
+      }
+   };
+
+   private View.OnClickListener mPresetButtonClickListener =
+      new View.OnClickListener() {
+         public void onClick(View view) {
+           PresetStation station = (PresetStation)view.getTag();
+           if (station != null) {
+              Log.d(LOGTAG, "station - " + station.getName() + " ("
+                    + station.getFrequency() + ")");
+              tuneRadio(station.getFrequency());
+              view.startAnimation(mAnimation);
+           }
+      }
+   };
+
+   private View.OnLongClickListener mPresetButtonOnLongClickListener =
+      new View.OnLongClickListener() {
+        public boolean onLongClick(View view) {
+           PresetStation station = (PresetStation)view.getTag();
+           mPresetButtonStation = station;
+           if (station != null) {
+               showDialog(DIALOG_PRESET_OPTIONS);
+           }else {
+               addToPresets();
+               view.startAnimation(mAnimation);
+           }
+         return true;
+      }
+   };
+
+   final 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 mSpeakerClickListener =
+        new View.OnClickListener() {
+          @Override
+          public void onClick(View v) {
+             // TODO Auto-generated method stub
+             enableSpeaker();
+          }
+    };
+
+   private View.OnClickListener mMuteModeClickListener =
+      new View.OnClickListener() {
+        public void onClick(View v) {
+           boolean bStatus = false;
+           if (mService != null) {
+              try {
+               if (true == isMuted()) {
+                   bStatus = mService.unMute();
+               }else {
+                   bStatus = mService.mute();
+               }
+               if (bStatus) {
+                   setMuteModeButtonImage(true);
+                   v.startAnimation(mAnimation);
+               }else {
+                   mCommandFailed = CMD_MUTE;
+                   if(isCallActive()) {
+                      showDialog(DIALOG_CMD_FAILED_CALL_ON);
+                   }else {
+                      showDialog(DIALOG_CMD_FAILED);
+                   }
+               }
+              }catch (RemoteException e) {
+                e.printStackTrace();
+              }
+           }
+      }
+   };
+
+   private View.OnClickListener mRecordButtonListener =
+      new View.OnClickListener() {
+        public void onClick(View v) {
+            if (isRecording()) {
+               stopRecording();
+            }else if(!isAnalogModeEnabled()) {
+               startRecording();
+            }
+            invalidateOptionsMenu();
+        }
+   };
+   private Handler mEnableRadioHandler = new Handler();
+   private Handler mDisableRadioHandler = new Handler();
+   private Runnable mEnableRadioTask = new Runnable() {
+    public void run() {
+       enableRadio();
+       mOnOffButton.setEnabled(true);
+       mOnOffButton.setClickable(true);
+       mOnOffButton.setOnClickListener(mTurnOnOffClickListener);
+    }
+  };
+
+  private Runnable mDisableRadioTask = new Runnable() {
+    public void run() {
+       disableRadio();
+       mOnOffButton.setEnabled(true);
+       mOnOffButton.setClickable(true);
+       mOnOffButton.setOnClickListener(mTurnOnOffClickListener);
+    }
+  };
+  private View.OnClickListener mTurnOnOffClickListener =
+      new View.OnClickListener() {
+        public void onClick(View v) {
+           mOnOffButton.setEnabled(false);
+           mOnOffButton.setClickable(false);
+           mOnOffButton.setOnClickListener(null);
+           if (isFmOn()) {
+              mEnableRadioHandler.removeCallbacks(mEnableRadioTask);
+              mDisableRadioHandler.removeCallbacks(mDisableRadioTask);
+              mDisableRadioHandler.postDelayed(mDisableRadioTask, 0);
+           }else {
+              mDisableRadioHandler.removeCallbacks(mDisableRadioTask);
+              mEnableRadioHandler.removeCallbacks(mEnableRadioTask);
+              mEnableRadioHandler.postDelayed(mEnableRadioTask, 0);
+           }
+           cleanupTimeoutHandler();
+      }
+   };
+
+   private void setTurnOnOffButtonImage() {
+      if (isFmOn() == true) {
+         mOnOffButton.setEnabled(true);
+      }else {
+         mOnOffButton.setEnabled(false);
+      }
+   }
+
+   private void setMuteModeButtonImage(boolean notify) {
+      String fmMutedString;
+      if (isMuted() == true) {
+         mMuteButton.setImageResource(R.drawable.ic_silent_mode);
+         fmMutedString = "FM Radio Muted";
+      }else {
+         /* Find a icon for Stations */
+         mMuteButton.setImageResource(R.drawable.ic_silent_mode_off);
+         fmMutedString = "FM Radio Playing";
+      }
+      if (notify) {
+         //Toast.makeText(this, fmMutedString, Toast.LENGTH_SHORT).show();
+         Log.d(LOGTAG, fmMutedString);
+      }
+   }
+
+   private void enableRadio() {
+      mIsScaning = false;
+      mIsSeeking = false;
+      mIsSearching = false;
+      boolean bStatus = false;
+      if (isHdmiOn()) {
+          showDialog(DIALOG_CMD_FAILED_HDMI_ON);
+      }else {
+          if (mService != null) {
+             try {
+                if((false == mService.isFmOn()) && isAntennaAvailable()) {
+                    bStatus = mService.fmOn();
+                    if(bStatus) {
+                       tuneRadio(FmSharedPreferences.getTunedFrequency());
+                       enableRadioOnOffUI();
+                    }else {
+                       Log.e(LOGTAG, "mService.fmOn failed");
+                       mCommandFailed = CMD_FMON;
+                       if(isCallActive()) {
+                          enableRadioOnOffUI();
+                          showDialog(DIALOG_CMD_FAILED_CALL_ON);
+                       }else {
+                          showDialog(DIALOG_CMD_FAILED);
+                       }
+                    }
+                }else {
+                    enableRadioOnOffUI();
+                }
+             }catch (RemoteException e) {
+                e.printStackTrace();
+             }
+          }
+      }
+   }
+
+   private void disableRadio() {
+      boolean bStatus = false;
+      boolean bSpeakerPhoneOn = isSpeakerEnabled();
+      cancelSearch();
+      endSleepTimer();
+      if(mRecording) {
+         //Stop if there is an ongoing Record
+         stopRecording();
+      }
+      if(mService != null) {
+         try {
+            if(bSpeakerPhoneOn) {
+               mService.enableSpeaker(false);
+            }
+            bStatus = mService.fmOff();
+            enableRadioOnOffUI();
+            if (bStatus == false) {
+                mCommandFailed = CMD_FMOFF;
+                Log.e(LOGTAG, " mService.fmOff failed");
+            }
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+   }
+
+   private void resetRadio() {
+      boolean bSpeakerPhoneOn = isSpeakerEnabled();
+      resetSearch();
+      endSleepTimer();
+      if (mRecording) {
+         //Stop if there is an ongoing Record
+         stopRecording();
+      }
+      if (mService != null) {
+         try {
+            if(bSpeakerPhoneOn) {
+               mService.enableSpeaker(false);
+            }
+            mService.fmRadioReset();
+            enableRadioOnOffUI(false);
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+   }
+   public void clearStationList() {
+      SharedPreferences sp = getSharedPreferences(SCAN_STATION_PREFS_NAME, 0);
+      SharedPreferences.Editor editor = sp.edit();
+      editor.clear();
+      editor.commit();
+   }
+   public static boolean fmConfigure() {
+      boolean bStatus = true;
+      if(mService != null) {
+         try {
+            bStatus = mService.fmReconfigure();
+            if (bStatus == false) {
+               mCommandFailed = CMD_FMCONFIGURE;
+               Log.e(LOGTAG, "mService.fmReconfigure failed");
+            }else {
+            }
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+      return bStatus;
+   }
+   public static void fmAutoAFSwitch() {
+      boolean bStatus = false;
+      if (mService != null) {
+         try {
+            bStatus = mService.enableAutoAF(FmSharedPreferences.getAutoAFSwitch());
+            if (bStatus == false) {
+               mCommandFailed = CMD_SET_AUTOAF;
+               Log.e(LOGTAG, " mService.enableAutoAF failed");
+            }
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+   }
+
+   public static void fmAudioOutputMode() {
+      boolean bStatus = false;
+      if (mService != null) {
+         try {
+            bStatus = mService.enableStereo(FmSharedPreferences.getAudioOutputMode());
+            if (bStatus == false) {
+               mCommandFailed = CMD_SET_AUDIO_MODE;
+               Log.e(LOGTAG, "mService.enableStereo failed");
+            }
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+   }
+
+   private void startRecording() {
+      if(mService != null) {
+         try {
+             mRecording = mService.startRecording();
+         }catch (RemoteException e) {
+             e.printStackTrace();
+         }
+         //Initiate record timer thread here
+         if(mRecording == true) {
+             mRecordingMsgTV.setCompoundDrawablesWithIntrinsicBounds
+                                   (R.drawable.recorder_stop, 0, 0, 0);
+             int durationInMins = FmSharedPreferences.getRecordDuration();
+             Log.e(LOGTAG, "Fected duration: " + durationInMins);
+             initiateRecordDurationTimer( durationInMins );
+         }
+      }
+   }
+
+   private void stopRecording() {
+       mRecording = false;
+       DebugToasts("Stopped Recording", Toast.LENGTH_SHORT);
+       if(null != mRecordUpdateHandlerThread) {
+          mRecordUpdateHandlerThread.interrupt();
+       }
+       if(null != mRecordingMsgTV) {
+          mRecordingMsgTV.setText("");
+          mRecordingMsgTV.setCompoundDrawablesWithIntrinsicBounds
+                           (R.drawable.recorder_start, 0, 0, 0);
+       }
+       if (mService != null) {
+           try {
+              mService.stopRecording();
+           }catch (RemoteException e) {
+              e.printStackTrace();
+           }
+        }
+        mRecordDuration = 0;
+   }
+
+   private boolean isRecording() {
+      mRecording = false;
+      if (mService != null) {
+         try {
+             mRecording = mService.isFmRecordingOn();
+         }catch (RemoteException e) {
+             e.printStackTrace();
+         }
+      }
+      return(mRecording);
+   }
+
+   private boolean isSpeakerEnabled() {
+      boolean speakerEnabled = false;
+      if (mService != null) {
+         try {
+             speakerEnabled = mService.isSpeakerEnabled();
+         }catch (RemoteException e) {
+             e.printStackTrace();
+         }
+      }
+      return(speakerEnabled);
+   }
+
+   private boolean stationExists(PresetStation station ){
+       boolean exists = FmSharedPreferences.sameStationExists(station);
+       if(exists){
+           Toast t = Toast.makeText(this, getString(R.string.station_exists), Toast.LENGTH_SHORT);
+           t.show();
+       }
+       return exists;
+   }
+
+   private void addToPresets() {
+      int currentList = FmSharedPreferences.getCurrentListIndex();
+      PresetStation selectedStation = getCurrentTunedStation();
+      if(!stationExists(selectedStation)) {
+         FmSharedPreferences.addStation(selectedStation.getName(), selectedStation
+                        .getFrequency(), currentList);
+         setupPresetLayout();
+      }
+   }
+
+   private void enableRadioOnOffUI() {
+      boolean bEnable = isFmOn();
+      /* Disable if no antenna/headset is available */
+      if (!isAntennaAvailable()) {
+          bEnable = false;
+      }
+      enableRadioOnOffUI(bEnable);
+   }
+
+   private void enableRadioOnOffUI(boolean bEnable) {
+      if (mMuteButton != null) {
+          mMuteButton.setEnabled(bEnable);
+          setMuteModeButtonImage(false);
+      }
+      if (bEnable) {
+         if (mRadioTextScroller != null) {
+             mRadioTextScroller.startScroll();
+         }
+         if (mERadioTextScroller != null) {
+             mERadioTextScroller.startScroll();
+         }
+         if (mTuneStationFrequencyTV != null) {
+            mTuneStationFrequencyTV.setOnLongClickListener(mFrequencyViewClickListener);
+         }
+         invalidateOptionsMenu();
+         if ((mRecordingMsgTV != null) && !isRecording()) {
+             mRecordingMsgTV.setText("");
+         }
+      }else {
+         if (mRadioTextScroller != null) {
+             mRadioTextScroller.stopScroll();
+         }
+         if (mERadioTextScroller != null) {
+             mERadioTextScroller.stopScroll();
+         }
+      }
+      if (mForwardButton != null) {
+          mForwardButton.setVisibility(((bEnable == true) ? View.VISIBLE
+                                        : View.INVISIBLE));
+      }
+      if (mBackButton != null) {
+         mBackButton.setVisibility(((bEnable == true) ? View.VISIBLE
+                                        : View.INVISIBLE));
+      }
+      if (mTuneStationFrequencyTV != null) {
+         mTuneStationFrequencyTV.setVisibility(((bEnable == true) ? View.VISIBLE
+                                             : View.INVISIBLE));
+      }
+      if (mPicker != null) {
+          mPicker.setVisibility(
+                  bEnable ? View.VISIBLE : View.INVISIBLE );
+      }
+      if (mStationCallSignTV != null) {
+          mStationCallSignTV.setVisibility(((bEnable == true) ? View.VISIBLE
+                                        : View.INVISIBLE));
+      }
+      if (mProgramTypeTV != null) {
+          mProgramTypeTV.setVisibility(((bEnable == true) ? View.VISIBLE
+                                    : View.INVISIBLE));
+      }
+      if (mSleepMsgTV != null) {
+         mSleepMsgTV.setVisibility(((bEnable && isSleepTimerActive()) ? View.VISIBLE
+                                 : View.INVISIBLE));
+      }
+      if (mRecordingMsgTV != null) {
+         mRecordingMsgTV.setVisibility(((bEnable == true) ? View.VISIBLE
+                                     : View.INVISIBLE));
+      }
+      if (mRadioTextTV != null) {
+         mRadioTextTV.setVisibility(((bEnable == true) ? View.VISIBLE
+                                  : View.INVISIBLE));
+      }
+      if(mERadioTextTV != null) {
+         mERadioTextTV.setVisibility(((bEnable == true) ? View.VISIBLE
+                                  : View.INVISIBLE));
+      }
+      if (mProgramServiceTV != null) {
+         mProgramServiceTV.setVisibility(((bEnable == true) ? View.VISIBLE
+                                  : View.INVISIBLE));
+      }
+
+      if (!isAntennaAvailable()) {
+         if (mRadioTextTV != null) {
+            mRadioTextTV.setVisibility(View.VISIBLE);
+            mRadioTextTV.setText(getString(R.string.msg_noantenna));
+            mRadioTextScroller.mOriginalString = getString(R.string.msg_noantenna);
+         }
+         if (mOnOffButton != null) {
+            mOnOffButton.setEnabled(false);
+         }
+      }else if (isCallActive()) {
+         if (mRadioTextTV != null) {
+            mRadioTextTV.setText("");
+            mRadioTextScroller.mOriginalString = "";
+         }
+         if (mERadioTextTV != null) {
+             mERadioTextTV.setText("");
+             mERadioTextScroller.mOriginalString = "";
+         }
+         if (mOnOffButton != null) {
+            mOnOffButton.setEnabled(false);
+         }
+      }else {
+         if (mRadioTextTV != null) {
+             mRadioTextTV.setText("");
+             mRadioTextScroller.mOriginalString = "";
+         }
+         if (mERadioTextTV != null) {
+             mERadioTextTV.setText("");
+             mERadioTextScroller.mOriginalString = "";
+         }
+         if (mOnOffButton != null) {
+             mOnOffButton.setEnabled(true);
+         }
+      }
+
+      if (mStereoTV != null) {
+          mStereoTV.setVisibility(((bEnable == true) ? View.VISIBLE
+                                   : View.INVISIBLE));
+      }
+      for (int nButton = 0; nButton < MAX_PRESETS_PER_PAGE; nButton++) {
+         if (mPresetButtons[nButton] != null) {
+            mPresetButtons[nButton].setEnabled(bEnable);
+         }
+      }
+      if (mPresetListButton != null) {
+         mPresetListButton.setEnabled(bEnable);
+      }
+      if (mPresetPageButton != null) {
+         mPresetPageButton.setEnabled(bEnable &&
+                                   (FmSharedPreferences.getListStationCount() >= MAX_PRESETS_PER_PAGE));
+      }
+      if(mSpeakerButton != null) {
+        mSpeakerButton.setEnabled(bEnable);
+        if (bEnable) {
+            if(isSpeakerEnabled()) {
+               mSpeakerButton.setImageResource(R.drawable.btn_speaker);
+            }else {
+               mSpeakerButton.setImageResource(R.drawable.btn_earphone);
+            }
+        }else{
+            mSpeakerButton.setImageResource(R.drawable.btn_earphone);
+        }
+      }
+   }
+
+   private void resetSearchProgress() {
+      Message msg = new Message();
+      msg.what = END_PROGRESS_DLG;
+      mSearchProgressHandler.sendMessage(msg);
+   }
+
+   private void updateSearchProgress() {
+      boolean searchActive = isScanActive() || isSeekActive() || 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 setupPresetLayout() {
+      int numStations = FmSharedPreferences.getListStationCount();
+      int addedStations = 0;
+
+      /*
+       * Validate mPresetPageNumber (Preset Page Number)
+       */
+      if (mPresetPageNumber > ((numStations) / MAX_PRESETS_PER_PAGE)) {
+         mPresetPageNumber = 0;
+      }
+
+      /*
+       * For every station, save the station as a tag and update the display
+       * on the preset Button.
+       */
+      for (int buttonIndex = 0; (buttonIndex < MAX_PRESETS_PER_PAGE); buttonIndex++) {
+         if (mPresetButtons[buttonIndex] != null) {
+            int stationIdex = (mPresetPageNumber * MAX_PRESETS_PER_PAGE)
+                                + buttonIndex;
+            PresetStation station = FmSharedPreferences.getStationInList(stationIdex);
+            String display = "";
+            if (station != null) {
+               display = station.getName();
+               mPresetButtons[buttonIndex].setText(display);
+               mPresetButtons[buttonIndex].setTag(station);
+               addedStations++;
+            }else {
+               mPresetButtons[buttonIndex].setText(R.string.add_station);
+               mPresetButtons[buttonIndex].setTag(station);
+            }
+         }
+      }
+   }
+
+   private void updateStationInfoToUI() {
+      double frequency = mTunedStation.getFrequency() / 1000.0;
+      mTuneStationFrequencyTV.setText("" + frequency + "MHz");
+      if ((mPicker != null) && mUpdatePickerValue) {
+          mPicker.setValue(((mTunedStation.getFrequency() - mPrefs.getLowerLimit())
+                              / mPrefs.getFrequencyStepSize()));
+      }
+      mStationCallSignTV.setText(mTunedStation.getPIString());
+      mProgramTypeTV.setText(mTunedStation.getPtyString());
+      mRadioTextTV.setText("");
+      mERadioTextTV.setText("");
+      mRadioTextScroller.mOriginalString = "";
+      mRadioTextScroller.mStringlength = 0;
+      mRadioTextScroller.mIteration = 0;
+      mERadioTextScroller.mOriginalString = "";
+      mERadioTextScroller.mStringlength = 0;
+      mERadioTextScroller.mIteration = 0;
+      mProgramServiceTV.setText("");
+      mStereoTV.setText("");
+      setupPresetLayout();
+   }
+
+
+   private boolean isFmOn() {
+      boolean bOn = false;
+      if(mService != null) {
+         try {
+            bOn = mService.isFmOn();
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+      return(bOn);
+   }
+
+   private boolean isAnalogModeEnabled() {
+      boolean aEnabled = false;
+      if (mService != null) {
+          try {
+              aEnabled = mService.isAnalogModeEnabled();
+          }catch (RemoteException e) {
+              e.printStackTrace();
+          }
+      }
+      return (aEnabled);
+   }
+
+   private boolean isMuted() {
+      boolean bMuted = false;
+      if (mService != null) {
+         try {
+            bMuted = mService.isMuted();
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+      return(bMuted);
+   }
+
+   private boolean isScanActive() {
+      return(mIsScaning);
+   }
+
+   private boolean isSeekActive() {
+      return(mIsSeeking);
+   }
+   private boolean isSearchActive() {
+      return(mIsSearching);
+   }
+
+   public static PresetStation getCurrentTunedStation() {
+      return mTunedStation;
+   }
+
+   private void SeekPreviousStation() {
+      Log.d(LOGTAG, "SeekPreviousStation");
+      if (mService != null) {
+         try {
+            if(!isSeekActive()) {
+               mIsSeeking = mService.seek(false);
+               if (mIsSeeking == false) {
+                  mCommandFailed = CMD_SEEK;
+                  Log.e(LOGTAG, "mService.seek failed");
+                  showDialog(DIALOG_CMD_FAILED);
+               }
+            }
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+      updateSearchProgress();
+   }
+
+   private void SeekNextStation() {
+      Log.d(LOGTAG, "SeekNextStation");
+      if(mService != null) {
+         try {
+            if(!isSeekActive()) {
+               mIsSeeking = mService.seek(true);
+               if (mIsSeeking == false) {
+                  mCommandFailed = CMD_SEEK;
+                  Log.e(LOGTAG, "mService.seek failed");
+                  showDialog(DIALOG_CMD_FAILED);
+               }
+            }
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+      updateSearchProgress();
+   }
+
+   /** Scan related */
+   private void initiateSearch(int pty) {
+      synchronized (this) {
+         mIsScaning = true;
+         if(mService != null) {
+            try {
+               mIsScaning = mService.scan(pty);
+               if (mIsScaning == false) {
+                  mCommandFailed = CMD_SCAN;
+                  Log.e(LOGTAG, "mService.scan failed");
+                  showDialog(DIALOG_CMD_FAILED);
+               }else {
+                  mScanPty = pty;
+               }
+            }catch (RemoteException e) {
+               e.printStackTrace();
+            }
+            updateSearchProgress();
+         }
+      }
+   }
+
+   /** SEEK Station with the matching PI */
+   private void initiatePISearch(int pi) {
+      Log.d(LOGTAG, "initiatePISearch");
+      if(mService != null) {
+         try {
+            if(!isSeekActive()) {
+               mIsSeeking = mService.seekPI(pi);
+               if (mIsSeeking == false) {
+                  mCommandFailed = CMD_SEEKPI;
+                  Log.e(LOGTAG, "mService.seekPI failed");
+                  showDialog(DIALOG_CMD_FAILED);
+               }
+            }
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }
+      updateSearchProgress();
+   }
+
+   private void resetSearch() {
+      mIsScaning = false;
+      mIsSeeking = false;
+      mIsSearching = false;
+      resetSearchProgress();
+   }
+
+   private void cancelSearch() {
+      synchronized (this) {
+         if (mService != null) {
+            try {
+               if ((mIsScaning == true)
+                   || (mIsSeeking == true)
+                   || (mIsSearching == true)) {
+                   mService.cancelSearch();
+                   mIsScaning = false;
+                   mIsSeeking = false;
+                   mIsSearching=false;
+               }
+            }catch (RemoteException e) {
+               e.printStackTrace();
+            }
+         }
+      }
+      updateSearchProgress();
+      invalidateOptionsMenu();
+   }
+
+   /** get Strongest Stations */
+   private void initiateSearchList() {
+      synchronized (this) {
+         mIsSearching = false;
+         if (mService != null) {
+            try {
+               mIsSearching = mService.searchStrongStationList(NUM_AUTO_PRESETS_SEARCH);
+               if (mIsSearching == false) {
+                  mCommandFailed = CMD_SEARCHLIST;
+                  Log.e(LOGTAG, "mService.searchStrongStationList failed");
+                  showDialog(DIALOG_CMD_FAILED);
+               }
+            }catch (RemoteException e) {
+               e.printStackTrace();
+            }
+            updateSearchProgress();
+         }
+      }
+   }
+
+   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) {
+                 double frequency = mTunedStation.getFrequency() / 1000.0;
+                 String titleStr = getString(R.string.msg_search_title, ("" + frequency));
+                 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();
+           }
+       }
+   };
+
+   /** Sleep Handling: After the timer expires, the app needs to shut down */
+   private static final int SLEEPTIMER_EXPIRED = 0x1001;
+   private static final int SLEEPTIMER_UPDATE = 0x1002;
+   private Thread mSleepUpdateHandlerThread = null;
+   /*
+    * Phone time when the App has to be shut down, calculated based on what the
+    * user configured
+    */
+   private static long mSleepAtPhoneTime = 0;
+
+   private void initiateSleepTimer(long seconds) {
+      mSleepAtPhoneTime = (SystemClock.elapsedRealtime()) + (seconds * 1000);
+      Log.d(LOGTAG, "Sleep in seconds: " + seconds);
+      initiateSleepThread();
+   }
+   private void initiateSleepThread() {
+      if (mSleepUpdateHandlerThread == null) {
+         mSleepUpdateHandlerThread = new Thread(null, doSleepProcessing,
+                                                "SleepUpdateThread");
+      }
+      /* Launch he dummy thread to simulate the transfer progress */
+      Log.d(LOGTAG, "Thread State: " + mSleepUpdateHandlerThread.getState());
+      if (mSleepUpdateHandlerThread.getState() == Thread.State.TERMINATED) {
+         mSleepUpdateHandlerThread = new Thread(null, doSleepProcessing,
+                                                "SleepUpdateThread");
+      }
+      /* If the thread state is "new" then the thread has not yet started */
+      if (mSleepUpdateHandlerThread.getState() == Thread.State.NEW) {
+         mSleepUpdateHandlerThread.start();
+      }
+   }
+
+   private void endSleepTimer() {
+      mSleepAtPhoneTime = 0;
+      if(null != mSleepUpdateHandlerThread) {
+         mSleepUpdateHandlerThread.interrupt();
+      }
+      if(null != mSleepMsgTV) {
+         mSleepMsgTV.setVisibility(View.INVISIBLE);
+      }
+   }
+
+   private boolean hasSleepTimerExpired() {
+      boolean expired = true;
+      if (isSleepTimerActive()) {
+         long timeNow = ((SystemClock.elapsedRealtime()));
+         if (timeNow < mSleepAtPhoneTime) {
+             expired = false;
+         }
+      }
+      return expired;
+   }
+
+   private boolean isSleepTimerActive() {
+      boolean active = false;
+      if (mSleepAtPhoneTime > 0) {
+          active = true;
+      }
+      return active;
+   }
+
+   private void updateExpiredSleepTime() {
+      int vis = View.INVISIBLE;
+      if (isSleepTimerActive()) {
+         long timeNow = ((SystemClock.elapsedRealtime()));
+         if (mSleepAtPhoneTime >= timeNow) {
+            long seconds = (mSleepAtPhoneTime - timeNow) / 1000;
+            String sleepMsg = makeTimeString(seconds);
+            mSleepMsgTV.setText(sleepMsg);
+            if (seconds < SLEEP_TOGGLE_SECONDS) {
+               int nowVis = mSleepMsgTV.getVisibility();
+               vis = (nowVis == View.INVISIBLE) ? View.VISIBLE
+                     : View.INVISIBLE;
+            }else {
+               vis = View.VISIBLE;
+            }
+         }else {
+            /* Clean up timer */
+            mSleepAtPhoneTime = 0;
+         }
+      }
+      mSleepMsgTV.setVisibility(vis);
+   }
+
+   private Handler mUIUpdateHandlerHandler = new Handler() {
+      public void handleMessage(Message msg) {
+         switch (msg.what) {
+         case SLEEPTIMER_EXPIRED: {
+               mSleepAtPhoneTime = 0;
+               DebugToasts("Turning Off FM Radio", Toast.LENGTH_SHORT);
+               disableRadio();
+               return;
+            }
+         case SLEEPTIMER_UPDATE: {
+               updateExpiredSleepTime();
+               break;
+            }
+         case RECORDTIMER_EXPIRED: {
+               Log.d(LOGTAG, "mUIUpdateHandlerHandler - RECORDTIMER_EXPIRED");
+               mRecordDuration = 0;
+               //Clear the Recorder text
+               mRecordingMsgTV.setText("");
+               if (mRecording != false) {
+                  DebugToasts("Stop Recording", Toast.LENGTH_SHORT);
+                  stopRecording();
+                  invalidateOptionsMenu();
+               }
+              return;
+            }
+         case RECORDTIMER_UPDATE: {
+               Log.d(LOGTAG, "mUIUpdateHandlerHandler - RECORDTIMER_UPDATE");
+               updateExpiredRecordTime();
+               break;
+            }
+         default:
+               break;
+         }
+         super.handleMessage(msg);
+      }
+   };
+
+   /* Thread processing */
+   private Runnable doSleepProcessing = new Runnable() {
+      public void run() {
+         boolean sleepTimerExpired = hasSleepTimerExpired();
+         while ((sleepTimerExpired == false) &&
+                    (!Thread.currentThread().isInterrupted())) {
+            try {
+                Thread.sleep(500);
+                Message statusUpdate = new Message();
+                statusUpdate.what = SLEEPTIMER_UPDATE;
+                mUIUpdateHandlerHandler.sendMessage(statusUpdate);
+                sleepTimerExpired = hasSleepTimerExpired();
+            }catch (Exception ex) {
+                Log.d( LOGTAG, "RunningThread InterruptedException");
+                Thread.currentThread().interrupt();
+            }//try
+         }
+         if(true == sleepTimerExpired) {
+             Message finished = new Message();
+             finished.what = SLEEPTIMER_EXPIRED;
+             mUIUpdateHandlerHandler.sendMessage(finished);
+         }
+      }
+   };
+
+   private static StringBuilder sFormatBuilder = new StringBuilder();
+   private static Formatter sFormatter = new Formatter(sFormatBuilder, Locale
+                                                       .getDefault());
+   private static final Object[] sTimeArgs = new Object[5];
+
+   private String makeTimeString(long secs) {
+      String durationformat = getString(R.string.durationformat);
+
+      /*
+       * Provide multiple arguments so the format can be changed easily by
+       * modifying the xml.
+       */
+      sFormatBuilder.setLength(0);
+
+      final Object[] timeArgs = sTimeArgs;
+      timeArgs[0] = secs / 3600;
+      timeArgs[1] = secs / 60;
+      timeArgs[2] = (secs / 60) % 60;
+      timeArgs[3] = secs;
+      timeArgs[4] = secs % 60;
+
+      return sFormatter.format(durationformat, timeArgs).toString();
+   }
+
+   private void tuneRadio(int frequency){
+      /* Issue the tune command only if tuneCommand is already not active */
+      if((mService != null) && (mCommandActive != CMD_TUNE) && isFmOn()) {
+         boolean bStatus = false;
+         try {
+             bStatus = mService.tune(frequency);
+             if (bStatus) {
+                 postTimeoutHandler(CMD_TUNE);
+             }else {
+               if (isFmOn()) {
+                  mCommandFailed = CMD_TUNE;
+                  Log.e(LOGTAG, "mService.tune failed");
+                  showDialog(DIALOG_CMD_FAILED);
+               }
+             }
+             mTunedStation.setName("");
+             mTunedStation.setPI(0);
+             mTunedStation.setPty(0);
+             updateStationInfoToUI();
+         }catch (RemoteException e) {
+            e.printStackTrace();
+         }
+      }else {
+         Log.e(LOGTAG, "Delayed Tune handler stopped");
+      }
+   }
+
+   /* Start a Command timeout
+   */
+   private synchronized void postTimeoutHandler(int cmd){
+      mCommandActive = cmd;
+      mCommandTimeoutHandler.sendEmptyMessageDelayed(MSG_CMD_TIMEOUT, CMD_TIMEOUT_DELAY_MS);
+   }
+
+   /* Stop the Command timeout
+   */
+   private synchronized void cleanupTimeoutHandler(){
+      mCommandActive = CMD_NONE;
+      mCommandTimeoutHandler.removeMessages(MSG_CMD_TIMEOUT);
+   }
+   /* Command timeout Handler
+      Routine to handle the Command timeouts for FM operations
+      that return asynchronous event callbacks
+   */
+   private Handler mCommandTimeoutHandler = new Handler() {
+      @Override
+      public void handleMessage(Message msg) {
+         switch (msg.what) {
+         case MSG_CMD_TIMEOUT: {
+               if (mCommandActive > 0) {
+                  Log.d(LOGTAG, "mCommandTimeoutHandler: Cmd failed: " + mCommandActive);
+                  mCommandTimeoutHandler.removeMessages(MSG_CMD_TIMEOUT);
+                  showDialog(DIALOG_CMD_TIMEOUT);
+                  return;
+               }
+               break;
+            }//case MSG_CMD_TIMEOUT
+         }//switch
+      }//handleMessage
+   };
+
+   @Override
+   public boolean onKeyDown(int keyCode, KeyEvent event) {
+       Log.d(LOGTAG, "KEY 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 super.onKeyDown(keyCode, event);
+   }
+   private void resetFMStationInfoUI() {
+      mTunedStation.setFrequency(FmSharedPreferences.getTunedFrequency());
+      mTunedStation.setName("");
+      mTunedStation.setPI(0);
+      mTunedStation.setRDSSupported(false);
+      mTunedStation.setPty(0);
+      mRadioTextTV.setText("");
+      mERadioTextTV.setText("");
+      mRadioTextScroller.mOriginalString = "";
+      mProgramServiceTV.setText("");
+      mRadioTextScroller.stopScroll();
+      mERadioTextScroller.mOriginalString = "";
+      mERadioTextScroller.stopScroll();
+      mUpdatePickerValue = true;
+      updateStationInfoToUI();
+   }
+
+   final Runnable mRadioEnabled = new Runnable() {
+      public void run() {
+         /* Update UI to FM On State */
+         enableRadioOnOffUI(true);
+         /* Tune to the last tuned frequency */
+         mUpdatePickerValue = true;
+         tuneRadio(FmSharedPreferences.getTunedFrequency());
+      }
+   };
+
+   final Runnable mRadioDisabled = new Runnable() {
+      public void run() {
+         /* Update UI to FM Off State */
+         cleanupTimeoutHandler();
+         endSleepTimer();
+         stopRecording();
+         cancelSearch();
+         enableRadioOnOffUI(false);
+      }
+   };
+   final Runnable mRadioReset = new Runnable() {
+      public void run() {
+         /* Update UI to FM Reset (Off) State */
+         resetRadio();
+      }
+   };
+
+   final Runnable mUpdateStationInfo = new Runnable() {
+      public void run() {
+         cleanupTimeoutHandler();
+         PresetStation station = new PresetStation("", FmSharedPreferences.getTunedFrequency());
+         if (station != null) {
+             mTunedStation.Copy(station);
+         }
+         updateSearchProgress();
+         resetFMStationInfoUI();
+      }
+   };
+
+   final Runnable mSearchComplete = new Runnable() {
+      public void run() {
+         Log.d(LOGTAG, "mSearchComplete: ");
+         mScanPty=0;
+         mIsScaning = false;
+         mIsSeeking = false;
+         mIsSearching = false;
+         updateSearchProgress();
+         resetFMStationInfoUI();
+         invalidateOptionsMenu();
+      }
+   };
+
+   final Runnable mOnMute = new Runnable() {
+      public void run() {
+         setMuteModeButtonImage(true);
+      }
+   };
+
+   final Runnable mOnStereo = new Runnable() {
+      public void run() {
+         if (FMRADIO_UI_STATION_AUDIO_STEREO == mStereo) {
+             mStereoTV.setText(R.string.audio_type_stereo);
+         }else if (FMRADIO_UI_STATION_AUDIO_MONO == mStereo) {
+             mStereoTV.setText(R.string.audio_type_mono);
+         }else {
+             mStereoTV.setText("");
+         }
+      }
+   };
+
+   final Runnable mUpdateRadioText = new Runnable() {
+      public void run() {
+         String str = "";
+         if ((mService != null) && isFmOn()) {
+            try {
+               /* Get Radio Text and update the display */
+               str = mService.getRadioText();
+
+               /* Update only if all the characters are printable */
+               if (TextUtils.isPrintableAsciiOnly(str)) {
+                  Log.d(LOGTAG, "mUpdateRadioText: Updatable string: [" + str + "]");
+                  mRadioTextTV.setText(str);
+                  mRadioTextScroller.mOriginalString = str;
+               }else if(TextUtils.isEmpty(str)) { /* Rest the string to empty*/
+                  mRadioTextTV.setText("");
+                  mRadioTextScroller.mOriginalString = "";
+               }else {
+                  //Log.d(LOGTAG, "mUpdateRadioText: Leaving old string " + mRadioTextTV.getText());
+               }
+
+               /* Get PTY and PI and update the display */
+               int tempInt = mService.getProgramType();
+               /* Save PTY */
+               mTunedStation.setPty(tempInt);
+               mProgramTypeTV.setText(PresetStation.parsePTY(tempInt));
+               tempInt = mService.getProgramID();
+               mStationCallSignTV.setText(PresetStation.parsePI(tempInt));
+               if (tempInt != 0) {
+                   mTunedStation.setPI(tempInt);
+               }
+               /* For non-Empty, non-Printable string, just leave the
+                  existing old string
+               */
+               mRadioTextScroller.startScroll();
+            }catch (RemoteException e) {
+               e.printStackTrace();
+            }
+         }
+      }
+   };
+
+   final Runnable mRadioChangeFrequency = new Runnable(){
+       public void run() {
+           mUpdatePickerValue = false;
+           tuneRadio(mFrequency);
+       }
+   };
+
+   final Runnable mUpdateExtenRadioText = new Runnable() {
+      public void run() {
+         String str = "";
+         if ((mService != null) && isFmOn()) {
+            try {
+               /* Get Extended Radio Text and update the display */
+               str = mService.getExtenRadioText();
+               if (TextUtils.isEmpty(str)) {
+                   mERadioTextTV.setText("");
+                   mERadioTextScroller.mOriginalString = "";
+               }else {
+                   mERadioTextTV.setText(str);
+                   mERadioTextScroller.mOriginalString = str;
+               }
+               mERadioTextScroller.startScroll();
+            }catch (RemoteException e) {
+               e.printStackTrace();
+            }
+         }
+      }
+   };
+
+   /* Create runnable for posting */
+   final Runnable mUpdateProgramService = new Runnable() {
+      public void run() {
+         String str = "";
+         if (mService != null) {
+            try {
+               /* Get the Station PS and update the display */
+               str = mService.getProgramService();
+               /* Update only if all the characters are printable */
+               //if(isStringPrintable(str))
+               if (TextUtils.isPrintableAsciiOnly(str)) {
+                  Log.d(LOGTAG, "mUpdateProgramService: Updatable string: [" + str + "]");
+                  mProgramServiceTV.setText(str);
+               }else if (TextUtils.isEmpty(str)) { /* Rest the string to empty*/
+                  mProgramServiceTV.setText("");
+               }else {
+                  /* For non-Empty, non-Printable string, just leave the
+                     existing old string
+                  */
+               }
+               /* Get PTY and PI and update the display */
+               int tempInt = mService.getProgramType();
+               /* Save PTY */
+               mTunedStation.setPty(tempInt);
+
+               mProgramTypeTV.setText(PresetStation.parsePTY(tempInt));
+               tempInt =mService.getProgramID();
+               /* Save the program ID */
+               if (tempInt != 0) {
+                   mTunedStation.setPI(tempInt);
+               }
+               mStationCallSignTV.setText(PresetStation.parsePI(tempInt));
+            }catch (RemoteException e) {
+               e.printStackTrace();
+            }
+         }
+      }
+   };
+
+   private void DebugToasts(String str, int duration) {
+      //Toast.makeText(this, str, duration).show();
+      Log.d(LOGTAG, "Debug:" + str);
+   }
+
+   /**
+    * 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 static 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)  {
+            mStringlength = mOriginalString.length();
+            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);
+               }
+               if ((mOriginalString !=null) && (mOriginalString.length() >= mIteration))
+                  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();
+            mStringlength = mOriginalString.length();
+            if (mStringlength > 0) {
+               mStatus = SCROLLER_STARTING;
+               sendEmptyMessageDelayed(SCROLLER_MSG_START, SCROLLER_START_DELAY_MS);
+            }
+         }
+      }
+   }
+
+
+   public static IFMRadioService sService = null;
+   private static HashMap<Context, ServiceBinder> sConnectionMap = new HashMap<Context, ServiceBinder>();
+
+   public static boolean bindToService(Context context) {
+      Log.e(LOGTAG, "bindToService: Context");
+      return bindToService(context, null);
+   }
+
+   public static boolean bindToService(Context context, ServiceConnection callback) {
+      Log.e(LOGTAG, "bindToService: Context with serviceconnection callback");
+      context.startService(new Intent(context, FMRadioService.class));
+      ServiceBinder sb = new ServiceBinder(callback);
+      sConnectionMap.put(context, sb);
+      return context.bindService((new Intent()).setClass(context,
+                                                         FMRadioService.class), sb, 0);
+   }
+
+   public static 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 static class ServiceBinder implements ServiceConnection {
+      ServiceConnection mCallback;
+      ServiceBinder(ServiceConnection callback) {
+         mCallback = callback;
+      }
+
+      public void onServiceConnected(ComponentName className, android.os.IBinder service) {
+         sService = IFMRadioService.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 = IFMRadioService.Stub.asInterface(obj);
+         Log.e(LOGTAG, "ServiceConnection: onServiceConnected: ");
+         if (mService != null) {
+            try {
+               mService.registerCallbacks(mServiceCallbacks);
+               if (SavedDataAndState == null) {
+                  enableRadio();
+               }else if (SavedDataAndState.onOrOff) {
+                  enableRadioOnOffUI(true);
+               }else {
+                  enableRadioOnOffUI(false);
+               }
+            }catch (RemoteException e) {
+               e.printStackTrace();
+            }
+            if (isRecording()) {
+                mRecordingMsgTV.setCompoundDrawablesWithIntrinsicBounds
+                                  (R.drawable.recorder_stop, 0, 0, 0);
+                initiateRecordThread();
+            }else if((mRecordDuration > 0) &&
+                      (mRecordUpdateHandlerThread != null)) {
+                mRecordUpdateHandlerThread.interrupt();
+                if(mRecordingMsgTV != null) {
+                   mRecordingMsgTV.setText("");
+                }
+                mRecordDuration = 0;
+            }
+            return;
+         }else {
+            Log.e(LOGTAG, "IFMRadioService onServiceConnected failed");
+         }
+         if (getIntent().getData() == null) {
+            Intent intent = new Intent(Intent.ACTION_MAIN);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setClass(FMRadio.this, FMRadio.class);
+            startActivity(intent);
+         }
+         finish();
+      }
+      public void onServiceDisconnected(ComponentName classname) {
+      }
+   };
+
+   private IFMRadioServiceCallbacks.Stub  mServiceCallbacks =
+    new IFMRadioServiceCallbacks.Stub() {
+      public void onEnabled() {
+         Log.d(LOGTAG, "mServiceCallbacks.onEnabled :");
+         mHandler.post(mRadioEnabled);
+      }
+      public void onDisabled() {
+         Log.d(LOGTAG, "mServiceCallbacks.onDisabled :");
+         mHandler.post(mRadioDisabled);
+      }
+      public void onRadioReset() {
+         Log.d(LOGTAG, "mServiceCallbacks.onRadioReset :");
+         mHandler.post(mRadioReset);
+      }
+      public void onTuneStatusChanged()  {
+         Log.d(LOGTAG, "mServiceCallbacks.onTuneStatusChanged: ");
+         if (mIsScaning) {
+             Log.d(LOGTAG, "isScanning....................");
+             SharedPreferences sp = getSharedPreferences(SCAN_STATION_PREFS_NAME, 0);
+             SharedPreferences.Editor editor = sp.edit();
+             int station_number = sp.getInt(NUM_OF_STATIONS, 0);
+             station_number++;
+             editor.putInt(NUM_OF_STATIONS, station_number);
+             editor.putString(STATION_NAME + station_number, station_number + "");
+             editor.putInt(STATION_FREQUENCY + station_number,
+                                   FmSharedPreferences.getTunedFrequency());
+             editor.commit();
+         }
+         cleanupTimeoutHandler();
+         mHandler.post(mUpdateStationInfo);
+      }
+
+      public void onProgramServiceChanged() {
+         Log.d(LOGTAG, "mServiceCallbacks.onProgramServiceChanged :");
+         mHandler.post(mUpdateProgramService);
+      }
+      public void onRadioTextChanged()  {
+         Log.d(LOGTAG, "mServiceCallbacks.onRadioTextChanged :");
+         mHandler.post(mUpdateRadioText);
+      }
+      public void onExtenRadioTextChanged() {
+         mHandler.post(mUpdateExtenRadioText);
+      }
+      public void onAlternateFrequencyChanged() {
+         Log.d(LOGTAG, "mServiceCallbacks.onAlternateFrequencyChanged :");
+      }
+      public void onSignalStrengthChanged() {
+         Log.d(LOGTAG, "mServiceCallbacks.onSignalStrengthChanged :");
+      }
+      public void onSearchComplete() {
+         Log.d(LOGTAG, "mServiceCallbacks.onSearchComplete :");
+         mHandler.post(mSearchComplete);
+      }
+      public void onSearchListComplete() {
+         Log.d(LOGTAG, "mServiceCallbacks.onSearchListComplete :");
+      }
+      public void onMute(boolean bMuted) {
+         Log.d(LOGTAG, "mServiceCallbacks.onMute :" + bMuted);
+         mHandler.post(mOnMute);
+      }
+      public void onAudioUpdate(boolean bStereo) {
+         if((bStereo) && (FmSharedPreferences.getAudioOutputMode())) {
+            mStereo = FMRADIO_UI_STATION_AUDIO_STEREO;
+         }else {
+            mStereo = FMRADIO_UI_STATION_AUDIO_MONO;
+         }
+         Log.d(LOGTAG, "mServiceCallbacks.onAudioUpdate :" + mStereo);
+         mHandler.post(mOnStereo);
+      }
+      public void onStationRDSSupported(boolean bRDSSupported) {
+         Log.d(LOGTAG, "mServiceCallbacks.onStationRDSSupported :" + bRDSSupported);
+         /*
+         * Depending on the signal strength etc, RDS Lock Sync/Supported may toggle,
+         * Since if a station Supports RDS, it will not change its support intermittently
+         * just save the status and ignore any "unsupported" state.
+         */
+         if (bRDSSupported) {
+             mTunedStation.setRDSSupported(true);
+         }
+      }
+      public void onRecordingStopped() {
+         Log.d(LOGTAG, "mServiceCallbacks.onRecordingStopped:");
+         stopRecording();
+      }
+   };
+}
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
new file mode 100644
index 0000000..5d971cf
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -0,0 +1,3009 @@
+/*
+ * 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 java.io.File;
+import java.util.*;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+
+import android.app.AlarmManager;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+import android.media.AudioManager;
+import android.media.AudioManager.OnAudioFocusChangeListener;
+import android.media.AudioSystem;
+import android.media.MediaRecorder;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.PowerManager;
+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.widget.Toast;
+import android.view.KeyEvent;
+import android.os.SystemProperties;
+
+import qcom.fmradio.FmReceiver;
+import qcom.fmradio.FmRxEvCallbacksAdaptor;
+import qcom.fmradio.FmRxRdsData;
+import qcom.fmradio.FmConfig;
+import android.net.Uri;
+import android.content.res.Resources;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import android.provider.MediaStore;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.database.Cursor;
+import com.caf.utils.A2dpDeviceStatus;
+import android.media.AudioManager;
+import android.content.ComponentName;
+import android.os.StatFs;
+import android.os.SystemClock;
+
+/**
+ * Provides "background" FM Radio (that uses the hardware) capabilities,
+ * allowing the user to switch between activities without stopping playback.
+ */
+public class FMRadioService extends Service
+{
+
+   public static final int RADIO_AUDIO_DEVICE_WIRED_HEADSET = 0;
+   public static final int RADIO_AUDIO_DEVICE_SPEAKER = 1;
+
+   private static final int FMRADIOSERVICE_STATUS = 101;
+   private static final String FMRADIO_DEVICE_FD_STRING = "/dev/radio0";
+   private static final String LOGTAG = "FMService";//FMRadio.LOGTAG;
+
+   private FmReceiver mReceiver;
+   private BroadcastReceiver mHeadsetReceiver = null;
+   private BroadcastReceiver mSdcardUnmountReceiver = null;
+   private BroadcastReceiver mMusicCommandListener = null;
+   private BroadcastReceiver mSleepExpiredListener = null;
+   private BroadcastReceiver mRecordTimeoutListener = null;
+   private BroadcastReceiver mDelayedServiceStopListener = null;
+   private boolean mOverA2DP = false;
+   private BroadcastReceiver mFmMediaButtonListener;
+   private IFMRadioServiceCallbacks mCallbacks;
+   private static FmSharedPreferences mPrefs;
+   private boolean mHeadsetPlugged = false;
+   private boolean mInternalAntennaAvailable = false;
+   private WakeLock mWakeLock;
+   private int mServiceStartId = -1;
+   private boolean mServiceInUse = false;
+   private static boolean mMuted = false;
+   private static boolean mResumeAfterCall = false;
+   private static String mAudioDevice="headset";
+   MediaRecorder mRecorder = null;
+   MediaRecorder mA2dp = null;
+   private boolean mFMOn = false;
+   private boolean mFmRecordingOn = false;
+   private boolean mSpeakerPhoneOn = false;
+   private int mCallStatus = 0;
+   private BroadcastReceiver mScreenOnOffReceiver = null;
+   final Handler mHandler = new Handler();
+   private boolean misAnalogModeSupported = false;
+   private boolean misAnalogPathEnabled = false;
+   private boolean mA2dpDisconnected = false;
+   //PhoneStateListener instances corresponding to each
+
+   private FmRxRdsData mFMRxRDSData=null;
+   // interval after which we stop the service when idle
+   private static final int IDLE_DELAY = 60000;
+   private File mA2DPSampleFile = null;
+   //Track FM playback for reenter App usecases
+   private boolean mPlaybackInProgress = false;
+   private boolean mStoppedOnFocusLoss = false;
+   private File mSampleFile = null;
+   long mSampleStart = 0;
+   // Messages handled in FM Service
+   private static final int FM_STOP =1;
+   private static final int RESET_NOTCH_FILTER =2;
+   private static final int STOPSERVICE_ONSLEEP = 3;
+   private static final int STOPRECORD_ONTIMEOUT = 4;
+   private static final int FOCUSCHANGE = 5;
+   //Track notch filter settings
+   private boolean mNotchFilterSet = false;
+   public static final int STOP_SERVICE = 0;
+   public static final int STOP_RECORD = 1;
+   // A2dp Device Status will be queried through this class
+   A2dpDeviceStatus mA2dpDeviceState = null;
+   private boolean mA2dpDeviceSupportInHal = false;
+   //on shutdown not to send start Intent to AudioManager
+   private boolean mAppShutdown = false;
+   private boolean mSingleRecordingInstanceSupported = false;
+   private AudioManager mAudioManager;
+   public static final long UNAVAILABLE = -1L;
+   public static final long PREPARING = -2L;
+   public static final long UNKNOWN_SIZE = -3L;
+   public static final long LOW_STORAGE_THRESHOLD = 50000000;
+   private long mStorageSpace;
+   private static final String IOBUSY_UNVOTE = "com.android.server.CpuGovernorService.action.IOBUSY_UNVOTE";
+   private static final String SLEEP_EXPIRED_ACTION = "com.caf.fmradio.SLEEP_EXPIRED";
+   private static final String RECORD_EXPIRED_ACTION = "com.caf.fmradio.RECORD_TIMEOUT";
+   private static final String SERVICE_DELAYED_STOP_ACTION = "com.caf.fmradio.SERVICE_STOP";
+
+   public FMRadioService() {
+   }
+
+   @Override
+   public void onCreate() {
+      super.onCreate();
+
+      mPrefs = new FmSharedPreferences(this);
+      mCallbacks = null;
+      TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
+      tmgr.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE |
+                                       PhoneStateListener.LISTEN_DATA_ACTIVITY);
+      PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
+      mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getName());
+      mWakeLock.setReferenceCounted(false);
+      misAnalogModeSupported  = SystemProperties.getBoolean("ro.fm.analogpath.supported",false);
+      /* Register for Screen On/off broadcast notifications */
+      mA2dpDeviceState = new A2dpDeviceStatus(getApplicationContext());
+      registerScreenOnOffListener();
+      registerHeadsetListener();
+      registerSleepExpired();
+      registerRecordTimeout();
+      registerDelayedServiceStop();
+      registerExternalStorageListener();
+      // registering media button receiver seperately as we need to set
+      // different priority for receiving media events
+      registerFmMediaButtonReceiver();
+      if ( false == SystemProperties.getBoolean("ro.fm.mulinst.recording.support",true)) {
+           mSingleRecordingInstanceSupported = true;
+      }
+
+      // Register for pause commands from other apps to stop FM
+      registerMusicServiceCommandReceiver();
+
+      // 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.
+      setAlarmDelayedServiceStop();
+      /* Query to check is a2dp supported in Hal */
+      AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+      String valueStr = audioManager.getParameters("isA2dpDeviceSupported");
+      mA2dpDeviceSupportInHal = valueStr.contains("=true");
+      Log.d(LOGTAG, " is A2DP device Supported In HAL"+mA2dpDeviceSupportInHal);
+   }
+
+   @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);
+      cancelAlarms();
+      //release the audio focus listener
+      AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+      if (isMuted()) {
+          mMuted = false;
+          audioManager.setStreamMute(AudioManager.STREAM_MUSIC,false);
+      }
+      audioManager.abandonAudioFocus(mAudioFocusListener);
+      /* Remove the Screen On/off listener */
+      if (mScreenOnOffReceiver != null) {
+          unregisterReceiver(mScreenOnOffReceiver);
+          mScreenOnOffReceiver = null;
+      }
+      /* Unregister the headset Broadcase receiver */
+      if (mHeadsetReceiver != null) {
+          unregisterReceiver(mHeadsetReceiver);
+          mHeadsetReceiver = null;
+      }
+      if( mSdcardUnmountReceiver != null ) {
+          unregisterReceiver(mSdcardUnmountReceiver);
+          mSdcardUnmountReceiver = null;
+      }
+      if( mMusicCommandListener != null ) {
+          unregisterReceiver(mMusicCommandListener);
+          mMusicCommandListener = null;
+      }
+      if( mFmMediaButtonListener != null ) {
+          unregisterReceiver(mFmMediaButtonListener);
+          mFmMediaButtonListener = null;
+      }
+      if (mSleepExpiredListener != null ) {
+          unregisterReceiver(mSleepExpiredListener);
+          mSleepExpiredListener = null;
+      }
+      if (mRecordTimeoutListener != null) {
+          unregisterReceiver(mRecordTimeoutListener);
+          mRecordTimeoutListener = null;
+      }
+      if (mDelayedServiceStopListener != null) {
+          unregisterReceiver(mDelayedServiceStopListener);
+          mDelayedServiceStopListener = null;
+      }
+      /* Since the service is closing, disable the receiver */
+      fmOff();
+
+      TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
+      tmgr.listen(mPhoneStateListener, 0);
+
+      Log.d(LOGTAG, "onDestroy: unbindFromService completed");
+
+      //unregisterReceiver(mIntentReceiver);
+      mWakeLock.release();
+      super.onDestroy();
+   }
+
+/**
+      * Registers an intent to listen for ACTION_MEDIA_UNMOUNTED notifications.
+      * The intent will call closeExternalStorageFiles() if the external media
+      * is going to be ejected, so applications can clean up.
+      */
+     public void registerExternalStorageListener() {
+         if (mSdcardUnmountReceiver == null) {
+             mSdcardUnmountReceiver = new BroadcastReceiver() {
+                 @Override
+                 public void onReceive(Context context, Intent intent) {
+                     String action = intent.getAction();
+                     if ((action.equals(Intent.ACTION_MEDIA_UNMOUNTED))
+                           || (action.equals(Intent.ACTION_MEDIA_EJECT))) {
+                         Log.d(LOGTAG, "ACTION_MEDIA_UNMOUNTED Intent received");
+                         if (mFmRecordingOn == true) {
+                             try {
+                                  stopRecording();
+                             } catch (Exception e) {
+                                  e.printStackTrace();
+                             }
+                         }
+                     }
+                 }
+             };
+             IntentFilter iFilter = new IntentFilter();
+             iFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
+             iFilter.addAction(Intent.ACTION_MEDIA_EJECT);
+             iFilter.addDataScheme("file");
+             registerReceiver(mSdcardUnmountReceiver, iFilter);
+         }
+     }
+
+
+     /**
+     * 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, "mReceiver: 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);
+                       // if headset is plugged out it is required to disable
+                       // in minimal duration to avoid race conditions with
+                       // audio policy manager switch audio to speaker.
+                       mHandler.removeCallbacks(mHeadsetPluginHandler);
+                       mHandler.post(mHeadsetPluginHandler);
+                    } else if(mA2dpDeviceState.isA2dpStateChange(action) ) {
+                        boolean  bA2dpConnected =
+                        mA2dpDeviceState.isConnected(intent);
+                        if (!bA2dpConnected) {
+                            Log.d(LOGTAG, "A2DP device is dis-connected!");
+                            mA2dpDisconnected = true;
+                        } else {
+                            mA2dpDisconnected = false;
+                        }
+                        if (isAnalogModeEnabled()) {
+                            Log.d(LOGTAG, "FM Audio Path is Analog Mode: FM Over BT not allowed");
+                            return ;
+                        }
+                       //when playback is overA2Dp and A2dp disconnected
+                       //when playback is not overA2DP and A2DP Connected
+                       // In above two cases we need to Stop and Start FM which
+                       // will take care of audio routing
+                       if( (isFmOn()) &&
+                           (true == ((bA2dpConnected)^(mOverA2DP))) &&
+                           (false == mStoppedOnFocusLoss) &&
+                           (!isSpeakerEnabled())) {
+                           stopFM();
+                           startFM();
+                       }
+                    } else if (action.equals("HDMI_CONNECTED")) {
+                        //FM should be off when HDMI is connected.
+                        fmOff();
+                        try
+                        {
+                            /* Notify the UI/Activity, only if the service is "bound"
+                               by an activity and if Callbacks are registered
+                             */
+                            if((mServiceInUse) && (mCallbacks != null) )
+                            {
+                                mCallbacks.onDisabled();
+                            }
+                        } catch (RemoteException e)
+                        {
+                            e.printStackTrace();
+                        }
+                    } else if( action.equals(Intent.ACTION_SHUTDOWN)) {
+                        mAppShutdown = true;
+                    }
+
+                }
+            };
+            IntentFilter iFilter = new IntentFilter();
+            iFilter.addAction(Intent.ACTION_HEADSET_PLUG);
+            iFilter.addAction(mA2dpDeviceState.getActionSinkStateChangedString());
+            iFilter.addAction("HDMI_CONNECTED");
+            iFilter.addAction(Intent.ACTION_SHUTDOWN);
+            iFilter.addCategory(Intent.CATEGORY_DEFAULT);
+            registerReceiver(mHeadsetReceiver, iFilter);
+        }
+    }
+
+    public void registerFmMediaButtonReceiver() {
+        if (mFmMediaButtonListener == null) {
+            mFmMediaButtonListener = new BroadcastReceiver() {
+                 public void onReceive(Context context, Intent intent) {
+                     Log.d(LOGTAG, "FMMediaButtonIntentReceiver.FM_MEDIA_BUTTON");
+                     Log.d(LOGTAG, "KeyEvent = " +intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT));
+                     String action = intent.getAction();
+                     if (action.equals(FMMediaButtonIntentReceiver.FM_MEDIA_BUTTON)) {
+                         KeyEvent event = (KeyEvent)
+                                     intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+                         int keycode = event.getKeyCode();
+                         switch (keycode) {
+                             case KeyEvent.KEYCODE_HEADSETHOOK :
+                                 if (isFmOn()){
+                                     //FM should be off when Headset hook pressed.
+                                     fmOff();
+                                     if (isOrderedBroadcast()) {
+                                        abortBroadcast();
+                                     }
+                                     try {
+                                         /* Notify the UI/Activity, only if the service is "bound"
+                                            by an activity and if Callbacks are registered
+                                          */
+                                         if ((mServiceInUse) && (mCallbacks != null) ) {
+                                            mCallbacks.onDisabled();
+                                         }
+                                     } catch (RemoteException e) {
+                                         e.printStackTrace();
+                                     }
+                                 } else if( mServiceInUse ) {
+                                     fmOn();
+                                     if (isOrderedBroadcast()) {
+                                        abortBroadcast();
+                                     }
+                                     try {
+                                         /* Notify the UI/Activity, only if the service is "bound"
+                                            by an activity and if Callbacks are registered
+                                          */
+                                         if (mCallbacks != null ) {
+                                             mCallbacks.onEnabled();
+                                         }
+                                     } catch (RemoteException e) {
+                                         e.printStackTrace();
+                                     }
+                                 }
+                                 break;
+                             case KeyEvent.KEYCODE_MEDIA_PAUSE :
+                                 if (isFmOn()){
+                                     //FM should be off when Headset hook pressed.
+                                     fmOff();
+                                     if (isOrderedBroadcast()) {
+                                        abortBroadcast();
+                                     }
+                                     try {
+                                         /* Notify the UI/Activity, only if the service is "bound"
+                                            by an activity and if Callbacks are registered
+                                          */
+                                         if ((mServiceInUse) && (mCallbacks != null) ) {
+                                            mCallbacks.onDisabled();
+                                         }
+                                     } catch (RemoteException e) {
+                                         e.printStackTrace();
+                                     }
+                                 }
+                                 break;
+                             case KeyEvent.KEYCODE_MEDIA_PLAY:
+                                 if (mServiceInUse ) {
+                                     fmOn();
+                                     if (isOrderedBroadcast()) {
+                                         abortBroadcast();
+                                     }
+                                     try {
+                                          /* Notify the UI/Activity, only if the service is "bound"
+                                             by an activity and if Callbacks are registered
+                                           */
+                                          if (mCallbacks != null ) {
+                                               mCallbacks.onEnabled();
+                                          }
+                                     } catch (RemoteException e) {
+                                          e.printStackTrace();
+                                     }
+                                 }
+                                 break;
+                         } // end of switch
+                     } // end of FMMediaButtonIntentReceiver.FM_MEDIA_BUTTON
+                 } // end of onReceive
+            };
+            IntentFilter iFilter = new IntentFilter();
+            iFilter.addAction(FMMediaButtonIntentReceiver.FM_MEDIA_BUTTON);
+            registerReceiver(mFmMediaButtonListener, iFilter);
+         }
+     }
+
+    public void registerMusicServiceCommandReceiver() {
+        if (mMusicCommandListener == null) {
+            mMusicCommandListener = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    String action = intent.getAction();
+
+                    if (action.equals("com.android.music.musicservicecommand")) {
+                        String cmd = intent.getStringExtra("command");
+                        Log.d(LOGTAG, "Music Service command : "+cmd+ " received");
+                        if (cmd != null && cmd.equals("pause")) {
+                            if (mA2dpDisconnected) {
+                                Log.d(LOGTAG, "not to pause,this is a2dp disconnected's pause");
+                                mA2dpDisconnected = false;
+                                return;
+                            }
+                            if(isFmOn()){
+                                fmOff();
+                                if (isOrderedBroadcast()) {
+                                    abortBroadcast();
+                                }
+                                try {
+                                    /* Notify the UI/Activity, only if the service is "bound"
+                                       by an activity and if Callbacks are registered
+                                    */
+                                    if((mServiceInUse) && (mCallbacks != null) ){
+                                        mCallbacks.onDisabled();
+                                    }
+                                } catch (RemoteException e) {
+                                    e.printStackTrace();
+                                }
+                            }
+                        }
+                    }
+                }
+            };
+            IntentFilter commandFilter = new IntentFilter();
+            commandFilter.addAction("com.android.music.musicservicecommand");
+            registerReceiver(mMusicCommandListener, commandFilter);
+        }
+    }
+    public void registerSleepExpired() {
+        if (mSleepExpiredListener == null) {
+            mSleepExpiredListener = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    Log.d(LOGTAG, "registerSleepExpired");
+                    mWakeLock.acquire(10 * 1000);
+                    fmOff();
+                }
+            };
+            IntentFilter intentFilter = new IntentFilter(SLEEP_EXPIRED_ACTION);
+            registerReceiver(mSleepExpiredListener, intentFilter);
+        }
+    }
+    public void registerRecordTimeout() {
+        if (mRecordTimeoutListener == null) {
+            mRecordTimeoutListener = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    Log.d(LOGTAG, "registerRecordTimeout");
+                    mWakeLock.acquire(5 * 1000);
+                    stopRecording();
+                }
+            };
+            IntentFilter intentFilter = new IntentFilter(RECORD_EXPIRED_ACTION);
+            registerReceiver(mRecordTimeoutListener, intentFilter);
+        }
+    }
+    public void registerDelayedServiceStop() {
+        if (mDelayedServiceStopListener == null) {
+            mDelayedServiceStopListener = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    Log.d(LOGTAG, "registerDelayedServiceStop");
+                    mWakeLock.acquire(5 * 1000);
+                    if (isFmOn() || mServiceInUse) {
+                        return;
+                    }
+                    stopSelf(mServiceStartId);
+                }
+            };
+            IntentFilter intentFilter = new IntentFilter(SERVICE_DELAYED_STOP_ACTION);
+            registerReceiver(mDelayedServiceStopListener, intentFilter);
+        }
+    }
+
+
+
+    final Runnable    mHeadsetPluginHandler = new Runnable() {
+        public void run() {
+            /* Update the UI based on the state change of the headset/antenna*/
+            if(!isAntennaAvailable())
+            {
+                /* Disable FM and let the UI know */
+                fmOff();
+                try
+                {
+                    /* Notify the UI/Activity, only if the service is "bound"
+                  by an activity and if Callbacks are registered
+                     */
+                    if((mServiceInUse) && (mCallbacks != null) )
+                    {
+                        mCallbacks.onDisabled();
+                    }
+                } catch (RemoteException e)
+                {
+                    e.printStackTrace();
+                }
+            }
+            else
+            {
+                /* headset is plugged back in,
+               So turn on FM if:
+               - FM is not already ON.
+               - If the FM UI/Activity is in the foreground
+                 (the service is "bound" by an activity
+                  and if Callbacks are registered)
+                 */
+                if ((!isFmOn()) && (mServiceInUse)
+                        && (mCallbacks != null))
+                {
+                    if( true != fmOn() ) {
+                        return;
+                    }
+                    try
+                    {
+                        mCallbacks.onEnabled();
+                    } catch (RemoteException e)
+                    {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+    };
+
+
+   @Override
+   public IBinder onBind(Intent intent) {
+      mDelayedStopHandler.removeCallbacksAndMessages(null);
+      cancelAlarms();
+      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);
+      cancelAlarms();
+      mServiceInUse = true;
+      /* Application/UI is attached, so get out of lower power mode */
+      setLowPowerMode(false);
+      if((mPlaybackInProgress == false) && isWiredHeadsetAvailable())
+         startFM();
+      Log.d(LOGTAG, "onRebind");
+   }
+
+   @Override
+   public void onStart(Intent intent, int startId) {
+      Log.d(LOGTAG, "onStart");
+      mServiceStartId = startId;
+      // 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);
+      cancelAlarms();
+      setAlarmDelayedServiceStop();
+   }
+
+   @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;
+      }
+      gotoIdleState();
+      return true;
+   }
+
+   private void startFM(){
+       Log.d(LOGTAG, "In startFM");
+       if(true == mAppShutdown) { // not to send intent to AudioManager in Shutdown
+           return;
+       }
+       if (isCallActive()) { // when Call is active never let audio playback
+           mResumeAfterCall = true;
+           return;
+       }
+       mResumeAfterCall = false;
+       if ( true == mPlaybackInProgress ) // no need to resend event
+           return;
+       AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+       audioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
+              AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+       Log.d(LOGTAG,"FM registering for registerMediaButtonEventReceiver");
+       mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+       ComponentName fmRadio = new ComponentName(this.getPackageName(),
+                                  FMMediaButtonIntentReceiver.class.getName());
+       mAudioManager.registerMediaButtonEventReceiver(fmRadio);
+       mStoppedOnFocusLoss = false;
+
+       if (!mA2dpDeviceSupportInHal &&  (true == mA2dpDeviceState.isDeviceAvailable()) &&
+            (!isSpeakerEnabled()) && !isAnalogModeEnabled()
+            && (true == startA2dpPlayback())) {
+            mOverA2DP=true;
+       } else {
+           Log.d(LOGTAG, "FMRadio: Requesting to start FM");
+           //reason for resending the Speaker option is we are sending
+           //ACTION_FM=1 to AudioManager, the previous state of Speaker we set
+           //need not be retained by the Audio Manager.
+           if (isSpeakerEnabled()) {
+                   mSpeakerPhoneOn = true;
+                   AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_SPEAKER);
+           }
+           AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
+                               AudioSystem.DEVICE_STATE_AVAILABLE, "");
+       }
+       mPlaybackInProgress = true;
+   }
+
+   private void stopFM(){
+       Log.d(LOGTAG, "In stopFM");
+       if (mOverA2DP==true){
+           mOverA2DP=false;
+           stopA2dpPlayback();
+       }else{
+           Log.d(LOGTAG, "FMRadio: Requesting to stop FM");
+           AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
+                                     AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
+       }
+       mPlaybackInProgress = false;
+   }
+
+   private void resetFM(){
+       Log.d(LOGTAG, "resetFM");
+       if (mOverA2DP==true){
+           mOverA2DP=false;
+           resetA2dpPlayback();
+       }else{
+           Log.d(LOGTAG, "FMRadio: Requesting to stop FM");
+           AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
+                                     AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
+       }
+       mPlaybackInProgress = false;
+   }
+
+   public boolean startRecording() {
+        Log.d(LOGTAG, "In startRecording of Recorder");
+    if( (true == mSingleRecordingInstanceSupported) &&
+        (true == mOverA2DP )) {
+                Toast.makeText( this,
+                                "playback on BT in progress,can't record now",
+                                Toast.LENGTH_SHORT).show();
+                return false;
+       }
+        stopRecording();
+
+        if (!updateAndShowStorageHint())
+            return false;
+        long maxFileSize = mStorageSpace - LOW_STORAGE_THRESHOLD;
+        mRecorder = new MediaRecorder();
+        try {
+              mRecorder.setMaxFileSize(maxFileSize);
+        } catch (RuntimeException exception) {
+
+        }
+
+        mSampleFile = null;
+        File sampleDir = Environment.getExternalStorageDirectory();
+        if (!sampleDir.canWrite()) // Workaround for broken sdcard support on
+                                    // the device.
+            sampleDir = new File("/sdcard/sdcard");
+        try {
+            mSampleFile = File
+                    .createTempFile("FMRecording", ".3gpp", sampleDir);
+        } catch (IOException e) {
+            Log.e(LOGTAG, "Not able to access SD Card");
+            Toast.makeText(this, "Not able to access SD Card", Toast.LENGTH_SHORT).show();
+            return false;
+        }
+        if (mRecorder == null) {
+           Toast.makeText(this,"MediaRecorder failed to create an instance",
+                            Toast.LENGTH_SHORT).show();
+           return false;
+        }
+
+        try {
+        mRecorder.setAudioSource(MediaRecorder.AudioSource.FM_RX);
+        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
+        } catch (RuntimeException exception) {
+            mRecorder.reset();
+            mRecorder.release();
+            mRecorder = null;
+            return false;
+        }
+        mRecorder.setOutputFile(mSampleFile.getAbsolutePath());
+        try {
+            mRecorder.prepare();
+            mRecorder.start();
+        } catch (IOException e) {
+            mRecorder.reset();
+            mRecorder.release();
+            mRecorder = null;
+            return false;
+        } catch (RuntimeException e) {
+            mRecorder.reset();
+            mRecorder.release();
+            mRecorder = null;
+            return false;
+        }
+        mFmRecordingOn = true;
+        mRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
+             public void onInfo(MediaRecorder mr, int what, int extra) {
+                 if ((what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) ||
+                     (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED)) {
+                     if (mFmRecordingOn) {
+                         Log.d(LOGTAG, "Maximum file size/duration reached, stopping the recording");
+                         stopRecording();
+                     }
+                     // Show the toast.
+                     Toast.makeText(FMRadioService.this, R.string.FMRecording_reach_size_limit,
+                               Toast.LENGTH_LONG).show();
+                 }
+             }
+             // from MediaRecorder.OnErrorListener
+             public void onError(MediaRecorder mr, int what, int extra) {
+                 Log.e(LOGTAG, "MediaRecorder error. what=" + what + ". extra=" + extra);
+                 if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
+                     // We may have run out of space on the sdcard.
+                     if (mFmRecordingOn) {
+                         stopRecording();
+                     }
+                     updateAndShowStorageHint();
+                 }
+             }
+        });
+
+        mSampleStart = System.currentTimeMillis();
+        return true;
+  }
+
+   public boolean startA2dpPlayback() {
+        Log.d(LOGTAG, "In startA2dpPlayback");
+    if( (true == mSingleRecordingInstanceSupported) &&
+        (true == mFmRecordingOn )) {
+                Toast.makeText(this,
+                               "Recording already in progress,can't play on BT",
+                               Toast.LENGTH_SHORT).show();
+                return false;
+       }
+        if(mOverA2DP)
+           stopA2dpPlayback();
+        mA2dp = new MediaRecorder();
+        if (mA2dp == null) {
+           Toast.makeText(this,"A2dpPlayback failed to create an instance",
+                            Toast.LENGTH_SHORT).show();
+           return false;
+        }
+        try {
+            mA2dp.setAudioSource(MediaRecorder.AudioSource.FM_RX_A2DP);
+            mA2dp.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
+            mA2dp.setAudioEncoder(MediaRecorder.OutputFormat.DEFAULT);
+            File sampleDir = new File(getFilesDir().getAbsolutePath());
+            try {
+                mA2DPSampleFile = File
+                    .createTempFile("FMRecording", ".3gpp", sampleDir);
+            } catch (IOException e) {
+                Log.e(LOGTAG, "Not able to access Phone's internal memory");
+                Toast.makeText(this, "Not able to access Phone's internal memory",
+                                Toast.LENGTH_SHORT).show();
+                return false;
+            }
+            mA2dp.setOutputFile(mA2DPSampleFile.getAbsolutePath());
+            mA2dp.prepare();
+            mA2dp.start();
+        } catch (Exception exception) {
+            mA2dp.reset();
+            mA2dp.release();
+            mA2dp = null;
+            return false;
+        }
+        return true;
+ }
+
+   public void stopA2dpPlayback() {
+       if (mA2dp == null)
+           return;
+       if(mA2DPSampleFile != null)
+       {
+          try {
+              mA2DPSampleFile.delete();
+          } catch (Exception e) {
+              Log.e(LOGTAG, "Not able to delete file");
+          }
+       }
+       try {
+           mA2dp.stop();
+           mA2dp.reset();
+           mA2dp.release();
+           mA2dp = null;
+       } catch (Exception exception ) {
+           Log.e( LOGTAG, "Stop failed with exception"+ exception);
+       }
+       return;
+   }
+
+   private void resetA2dpPlayback() {
+       if (mA2dp == null)
+           return;
+       if(mA2DPSampleFile != null)
+       {
+          try {
+              mA2DPSampleFile.delete();
+          } catch (Exception e) {
+              Log.e(LOGTAG, "Not able to delete file");
+          }
+       }
+       try {
+           // Send Intent for IOBUSY VOTE, because MediaRecorder.stop
+           // gets Activity context which might not be always available
+           // and would thus fail to send the intent.
+           Intent ioBusyUnVoteIntent = new Intent(IOBUSY_UNVOTE);
+           // Remove vote for io_is_busy to be turned off.
+           ioBusyUnVoteIntent.putExtra("com.android.server.CpuGovernorService.voteType", 0);
+           sendBroadcast(ioBusyUnVoteIntent);
+
+           mA2dp.stop();
+
+           mA2dp.reset();
+           mA2dp.release();
+           mA2dp = null;
+       } catch (Exception exception ) {
+           Log.e( LOGTAG, "Stop failed with exception"+ exception);
+       }
+       return;
+   }
+
+   private void resetRecording() {
+
+       Log.v(LOGTAG, "resetRecording()");
+
+       mFmRecordingOn = false;
+       if (mRecorder == null)
+           return;
+
+       // Send Intent for IOBUSY VOTE, because MediaRecorder.stop
+       // gets Activity context which might not be always available
+       // and would thus fail to send the intent.
+       Intent ioBusyUnVoteIntent = new Intent(IOBUSY_UNVOTE);
+       // Remove vote for io_is_busy to be turned off.
+       ioBusyUnVoteIntent.putExtra("com.android.server.CpuGovernorService.voteType", 0);
+       sendBroadcast(ioBusyUnVoteIntent);
+
+       mRecorder.stop();
+
+       mRecorder.reset();
+       mRecorder.release();
+       mRecorder = null;
+       int sampleLength = (int)((System.currentTimeMillis() - mSampleStart)/1000 );
+       if (sampleLength == 0)
+           return;
+       String state = Environment.getExternalStorageState();
+       Log.d(LOGTAG, "storage state is " + state);
+
+       if (Environment.MEDIA_MOUNTED.equals(state)) {
+           this.addToMediaDB(mSampleFile);
+       }
+       else{
+           Log.e(LOGTAG, "SD card must have removed during recording. ");
+           Toast.makeText(this, "Recording aborted", Toast.LENGTH_SHORT).show();
+       }
+       return;
+   }
+
+   public void stopRecording() {
+       mFmRecordingOn = false;
+       if (mRecorder == null)
+           return;
+       try {
+             mRecorder.stop();
+             mRecorder.reset();
+             mRecorder.release();
+             mRecorder = null;
+       } catch(Exception e) {
+             e.printStackTrace();
+       }
+       int sampleLength = (int)((System.currentTimeMillis() - mSampleStart)/1000 );
+       if (sampleLength == 0)
+           return;
+       String state = Environment.getExternalStorageState();
+       Log.d(LOGTAG, "storage state is " + state);
+
+       if (Environment.MEDIA_MOUNTED.equals(state)) {
+          try {
+               this.addToMediaDB(mSampleFile);
+          }
+          catch(Exception e) {
+               e.printStackTrace();
+          }
+       }
+       else{
+           Log.e(LOGTAG, "SD card must have removed during recording. ");
+           Toast.makeText(this, "Recording aborted", Toast.LENGTH_SHORT).show();
+       }
+       try
+       {
+           if((mServiceInUse) && (mCallbacks != null) ) {
+               mCallbacks.onRecordingStopped();
+           }
+       } catch (RemoteException e)
+       {
+           e.printStackTrace();
+       }
+       return;
+   }
+
+   /*
+    * Adds file and returns content uri.
+    */
+   private Uri addToMediaDB(File file) {
+       Log.d(LOGTAG, "In addToMediaDB");
+       Resources res = getResources();
+       ContentValues cv = new ContentValues();
+       long current = System.currentTimeMillis();
+       long modDate = file.lastModified();
+       Date date = new Date(current);
+       SimpleDateFormat formatter = new SimpleDateFormat(
+               res.getString(R.string.audio_db_title_format));
+       String title = formatter.format(date);
+
+       // Lets label the recorded audio file as NON-MUSIC so that the file
+       // won't be displayed automatically, except for in the playlist.
+       cv.put(MediaStore.Audio.Media.IS_MUSIC, "1");
+
+       cv.put(MediaStore.Audio.Media.TITLE, title);
+       cv.put(MediaStore.Audio.Media.DATA, file.getAbsolutePath());
+       cv.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
+       cv.put(MediaStore.Audio.Media.DATE_MODIFIED, (int) (modDate / 1000));
+       cv.put(MediaStore.Audio.Media.MIME_TYPE, "AUDIO_AAC_MP4");
+       cv.put(MediaStore.Audio.Media.ARTIST,
+               res.getString(R.string.audio_db_artist_name));
+       cv.put(MediaStore.Audio.Media.ALBUM,
+               res.getString(R.string.audio_db_album_name));
+       Log.d(LOGTAG, "Inserting audio record: " + cv.toString());
+       ContentResolver resolver = getContentResolver();
+       Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
+       Log.d(LOGTAG, "ContentURI: " + base);
+       Uri result = resolver.insert(base, cv);
+       if (result == null) {
+           Toast.makeText(this, "Unable to save recorded audio", Toast.LENGTH_SHORT).show();
+           return null;
+       }
+       if (getPlaylistId(res) == -1) {
+           createPlaylist(res, resolver);
+       }
+       int audioId = Integer.valueOf(result.getLastPathSegment());
+       addToPlaylist(resolver, audioId, getPlaylistId(res));
+
+       // Notify those applications such as Music listening to the
+       // scanner events that a recorded audio file just created.
+       sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
+       return result;
+   }
+
+   private int getPlaylistId(Resources res) {
+       Uri uri = MediaStore.Audio.Playlists.getContentUri("external");
+       final String[] ids = new String[] { MediaStore.Audio.Playlists._ID };
+       final String where = MediaStore.Audio.Playlists.NAME + "=?";
+       final String[] args = new String[] { res.getString(R.string.audio_db_playlist_name) };
+       Cursor cursor = query(uri, ids, where, args, null);
+       if (cursor == null) {
+           Log.v(LOGTAG, "query returns null");
+       }
+       int id = -1;
+       if (cursor != null) {
+           cursor.moveToFirst();
+           if (!cursor.isAfterLast()) {
+               id = cursor.getInt(0);
+           }
+           cursor.close();
+       }
+       return id;
+   }
+
+   private Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+       try {
+           ContentResolver resolver = getContentResolver();
+           if (resolver == null) {
+               return null;
+           }
+           return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
+        } catch (UnsupportedOperationException ex) {
+           return null;
+       }
+   }
+
+   private Uri createPlaylist(Resources res, ContentResolver resolver) {
+       ContentValues cv = new ContentValues();
+       cv.put(MediaStore.Audio.Playlists.NAME, res.getString(R.string.audio_db_playlist_name));
+       Uri uri = resolver.insert(MediaStore.Audio.Playlists.getContentUri("external"), cv);
+       if (uri == null) {
+           Toast.makeText(this, "Unable to save recorded audio", Toast.LENGTH_SHORT).show();
+       }
+       return uri;
+   }
+
+   private void addToPlaylist(ContentResolver resolver, int audioId, long playlistId) {
+       String[] cols = new String[] {
+               "count(*)"
+       };
+       Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
+       Cursor cur = resolver.query(uri, cols, null, null, null);
+       final int base;
+       if (cur != null) {
+            cur.moveToFirst();
+            base = cur.getInt(0);
+            cur.close();
+       }
+       else {
+            base = 0;
+       }
+       ContentValues values = new ContentValues();
+       values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(base + audioId));
+       values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, audioId);
+       resolver.insert(uri, values);
+   }
+   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);
+       mCallStatus = state;
+
+       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;
+               }
+           }
+           boolean bTempSpeaker = mSpeakerPhoneOn; //need to restore SpeakerPhone
+           boolean bTempMute = mMuted;// need to restore Mute status
+           int bTempCall = mCallStatus;//need to restore call status
+           if (fmOff()) {
+               if((mServiceInUse) && (mCallbacks != null)) {
+                   try {
+                        mCallbacks.onDisabled();
+                   } catch (RemoteException e) {
+                        e.printStackTrace();
+                   }
+               }
+               mResumeAfterCall = true;
+               mSpeakerPhoneOn = bTempSpeaker;
+               mCallStatus = bTempCall;
+               mMuted = bTempMute;
+           } else if (!mResumeAfterCall) {
+               mResumeAfterCall = false;
+               mSpeakerPhoneOn = bTempSpeaker;
+               mCallStatus = bTempCall;
+               mMuted = bTempMute;
+           }
+       }
+       else if (state == TelephonyManager.CALL_STATE_IDLE) {
+          // start playing again
+          if (mResumeAfterCall)
+          {
+             // resume playback only if FM Radio was playing
+             // when the call was answered
+              if (isAntennaAvailable() && (!isFmOn()) && mServiceInUse)
+              {
+                   Log.d(LOGTAG, "Resuming after call:");
+                   if(true != fmOn()) {
+                       return;
+                   }
+                   mResumeAfterCall = false;
+                   if(mCallbacks != null) {
+                      try {
+                           mCallbacks.onEnabled();
+                      } catch (RemoteException e) {
+                           e.printStackTrace();
+                      }
+                   }
+              }
+          }
+       }//idle
+   }
+
+    /* 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 );
+      }
+
+      @Override
+      public void onDataActivity (int direction) {
+          Log.d(LOGTAG, "onDataActivity - " + direction );
+          if (direction == TelephonyManager.DATA_ACTIVITY_NONE ||
+              direction == TelephonyManager.DATA_ACTIVITY_DORMANT) {
+                 if (mReceiver != null) {
+                       Message msg = mDelayedStopHandler.obtainMessage(RESET_NOTCH_FILTER);
+                       mDelayedStopHandler.sendMessageDelayed(msg, 10000);
+                 }
+         } else {
+               if (mReceiver != null) {
+                   if( true == mNotchFilterSet )
+                   {
+                       mDelayedStopHandler.removeMessages(RESET_NOTCH_FILTER);
+                   }
+                   else
+                   {
+                       mReceiver.setNotchFilter(true);
+                       mNotchFilterSet = true;
+                   }
+               }
+         }
+      }
+ };
+
+   private Handler mDelayedStopHandler = new Handler() {
+      @Override
+      public void handleMessage(Message msg) {
+          switch (msg.what) {
+          case FM_STOP:
+              // Check again to make sure nothing is playing right now
+              if (isFmOn() || mServiceInUse)
+              {
+                   return;
+              }
+              Log.d(LOGTAG, "mDelayedStopHandler: stopSelf");
+              stopSelf(mServiceStartId);
+              break;
+          case RESET_NOTCH_FILTER:
+              if (mReceiver != null) {
+                  mReceiver.setNotchFilter(false);
+                  mNotchFilterSet = false;
+              }
+              break;
+          case STOPSERVICE_ONSLEEP:
+              fmOff();
+              break;
+          case STOPRECORD_ONTIMEOUT:
+              stopRecording();
+              break;
+          case FOCUSCHANGE:
+              if( false == isFmOn() ) {
+                  Log.v(LOGTAG, "FM is not running, not handling change");
+                  return;
+              }
+              switch (msg.arg1) {
+                  case AudioManager.AUDIOFOCUS_LOSS:
+                      Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_LOSS");
+                      //intentional fall through.
+                  case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+                      Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_LOSS_TRANSIENT");
+                      if (mSpeakerPhoneOn) {
+                          mSpeakerPhoneOn = false;
+                          if (isAnalogModeSupported()) {
+                              setAudioPath(true);
+                          }
+                          AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_NONE);
+                      }
+                      if(true == isFmRecordingOn())
+                          stopRecording();
+                      if(true == mPlaybackInProgress) {
+                          if (mMuted)
+                              unMute();
+                          stopFM();
+                      }
+                      mStoppedOnFocusLoss = true;
+                      break;
+                  case AudioManager.AUDIOFOCUS_GAIN:
+                      Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_GAIN");
+                      if(false == mPlaybackInProgress)
+                          startFM();
+                      mStoppedOnFocusLoss = false;
+                      break;
+                  case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+                  default:
+                      Log.e(LOGTAG, "Unknown audio focus change code"+msg.arg1);
+              }
+              break;
+          }
+      }
+   };
+
+
+     /**
+     * Registers an intent to listen for
+     * ACTION_SCREEN_ON/ACTION_SCREEN_OFF notifications. This intent
+     * is called to know iwhen the screen is turned on/off.
+     */
+    public void registerScreenOnOffListener() {
+        if (mScreenOnOffReceiver == null) {
+            mScreenOnOffReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    String action = intent.getAction();
+                    if (action.equals(Intent.ACTION_SCREEN_ON)) {
+                       Log.d(LOGTAG, "ACTION_SCREEN_ON Intent received");
+                       //Screen turned on, set FM module into normal power mode
+                       mHandler.post(mScreenOnHandler);
+                    }
+                    else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+                       Log.d(LOGTAG, "ACTION_SCREEN_OFF Intent received");
+                       //Screen turned on, set FM module into low power mode
+                       mHandler.post(mScreenOffHandler);
+                    }
+                }
+            };
+            IntentFilter iFilter = new IntentFilter();
+            iFilter.addAction(Intent.ACTION_SCREEN_ON);
+            iFilter.addAction(Intent.ACTION_SCREEN_OFF);
+            registerReceiver(mScreenOnOffReceiver, iFilter);
+        }
+    }
+
+    /* Handle all the Screen On actions:
+       Set FM Power mode to Normal
+     */
+    final Runnable    mScreenOnHandler = new Runnable() {
+       public void run() {
+          setLowPowerMode(false);
+       }
+    };
+    /* Handle all the Screen Off actions:
+       Set FM Power mode to Low Power
+       This will reduce all the interrupts coming up from the SoC, saving power
+     */
+    final Runnable    mScreenOffHandler = new Runnable() {
+       public void run() {
+          setLowPowerMode(true);
+       }
+    };
+
+   /* Show the FM Notification */
+   public void startNotification() {
+      RemoteViews views = new RemoteViews(getPackageName(), R.layout.statusbar);
+      views.setImageViewResource(R.id.icon, R.drawable.stat_notify_fm);
+      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.stat_notify_fm;
+      status.contentIntent = PendingIntent.getActivity(this, 0,
+                                                       new Intent("com.caf.fmradio.FMRADIO_ACTIVITY"), 0);
+      startForeground(FMRADIOSERVICE_STATUS, status);
+      //NotificationManager nm = (NotificationManager)
+      //                         getSystemService(Context.NOTIFICATION_SERVICE);
+      //nm.notify(FMRADIOSERVICE_STATUS, status);
+      //setForeground(true);
+      mFMOn = true;
+   }
+
+   private void stop() {
+      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);
+      }
+      gotoIdleState();
+      mFMOn = false;
+   }
+
+   private void gotoIdleState() {
+      mDelayedStopHandler.removeCallbacksAndMessages(null);
+      cancelAlarms();
+      setAlarmDelayedServiceStop();
+      stopForeground(true);
+   }
+
+   /** Read's the internal Antenna available state from the FM
+    *  Device.
+    */
+   public void readInternalAntennaAvailable()
+   {
+      mInternalAntennaAvailable  = false;
+      if (mReceiver != null)
+      {
+         mInternalAntennaAvailable = mReceiver.getInternalAntenna();
+         Log.d(LOGTAG, "getInternalAntenna: " + mInternalAntennaAvailable);
+      }
+   }
+
+   /*
+    * 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 IFMRadioService.Stub
+   {
+      WeakReference<FMRadioService> mService;
+
+      ServiceStub(FMRadioService service)
+      {
+         mService = new WeakReference<FMRadioService>(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 true;
+      }
+
+      public boolean isFmOn()
+      {
+         return(mService.get().isFmOn());
+      }
+
+      public boolean isAnalogModeEnabled()
+      {
+         return(mService.get().isAnalogModeEnabled());
+      }
+
+      public boolean isFmRecordingOn()
+      {
+         return(mService.get().isFmRecordingOn());
+      }
+
+      public boolean isSpeakerEnabled()
+      {
+         return(mService.get().isSpeakerEnabled());
+      }
+
+      public boolean fmReconfigure()
+      {
+         return(mService.get().fmReconfigure());
+      }
+
+      public void registerCallbacks(IFMRadioServiceCallbacks cb) throws RemoteException
+      {
+         mService.get().registerCallbacks(cb);
+      }
+
+      public void unregisterCallbacks() throws RemoteException
+      {
+         mService.get().unregisterCallbacks();
+      }
+
+      public boolean routeAudio(int device)
+      {
+         return(mService.get().routeAudio(device));
+      }
+
+      public boolean mute()
+      {
+         return(mService.get().mute());
+      }
+
+      public boolean unMute()
+      {
+         return(mService.get().unMute());
+      }
+
+      public boolean isMuted()
+      {
+         return(mService.get().isMuted());
+      }
+
+      public boolean startRecording()
+      {
+         return(mService.get().startRecording());
+      }
+
+      public void stopRecording()
+      {
+         mService.get().stopRecording();
+      }
+
+      public boolean tune(int frequency)
+      {
+         return(mService.get().tune(frequency));
+      }
+
+      public boolean seek(boolean up)
+      {
+         return(mService.get().seek(up));
+      }
+
+      public void enableSpeaker(boolean speakerOn)
+      {
+          mService.get().enableSpeaker(speakerOn);
+      }
+
+      public boolean scan(int pty)
+      {
+         return(mService.get().scan(pty));
+      }
+
+      public boolean seekPI(int piCode)
+      {
+         return(mService.get().seekPI(piCode));
+      }
+      public boolean searchStrongStationList(int numStations)
+      {
+         return(mService.get().searchStrongStationList(numStations));
+      }
+
+      public boolean cancelSearch()
+      {
+         return(mService.get().cancelSearch());
+      }
+
+      public String getProgramService()
+      {
+         return(mService.get().getProgramService());
+      }
+      public String getRadioText()
+      {
+         return(mService.get().getRadioText());
+      }
+      public String getExtenRadioText()
+      {
+         return(mService.get().getExtenRadioText());
+      }
+      public int getProgramType()
+      {
+         return(mService.get().getProgramType());
+      }
+      public int getProgramID()
+      {
+         return(mService.get().getProgramID());
+      }
+      public int[] getSearchList()
+      {
+         return(mService.get().getSearchList());
+      }
+
+      public boolean setLowPowerMode(boolean enable)
+      {
+         return(mService.get().setLowPowerMode(enable));
+      }
+
+      public int getPowerMode()
+      {
+         return(mService.get().getPowerMode());
+      }
+      public boolean enableAutoAF(boolean bEnable)
+      {
+         return(mService.get().enableAutoAF(bEnable));
+      }
+      public boolean enableStereo(boolean bEnable)
+      {
+         return(mService.get().enableStereo(bEnable));
+      }
+      public boolean isAntennaAvailable()
+      {
+         return(mService.get().isAntennaAvailable());
+      }
+      public boolean isWiredHeadsetAvailable()
+      {
+         return(mService.get().isWiredHeadsetAvailable());
+      }
+      public boolean isCallActive()
+      {
+          return(mService.get().isCallActive());
+      }
+      public int getRssi()
+      {
+          return (mService.get().getRssi());
+      }
+      public int getIoC()
+      {
+          return (mService.get().getIoC());
+      }
+      public int getMpxDcc()
+      {
+          return (mService.get().getMpxDcc());
+      }
+      public int getIntDet()
+      {
+          return (mService.get().getIntDet());
+      }
+      public void setHiLoInj(int inj)
+      {
+          mService.get().setHiLoInj(inj);
+      }
+      public void delayedStop(long duration, int nType)
+      {
+          mService.get().delayedStop(duration, nType);
+      }
+      public void cancelDelayedStop(int nType)
+      {
+          mService.get().cancelDelayedStop(nType);
+      }
+      public void requestFocus()
+      {
+          mService.get().requestFocus();
+      }
+      public int getSINR()
+      {
+          return (mService.get().getSINR());
+      }
+      public boolean setSinrSamplesCnt(int samplesCnt)
+      {
+          return (mService.get().setSinrSamplesCnt(samplesCnt));
+      }
+      public boolean setSinrTh(int sinr)
+      {
+          return (mService.get().setSinrTh(sinr));
+      }
+      public boolean setIntfDetLowTh(int intfLowTh)
+      {
+          return (mService.get().setIntfDetLowTh(intfLowTh));
+      }
+      public boolean setIntfDetHighTh(int intfHighTh)
+      {
+          return (mService.get().setIntfDetHighTh(intfHighTh));
+      }
+   }
+   private final IBinder mBinder = new ServiceStub(this);
+
+   private boolean setAudioPath(boolean analogMode) {
+
+        if (mReceiver == null) {
+              return false;
+        }
+        if (isAnalogModeEnabled() == analogMode) {
+                Log.d(LOGTAG,"Analog Path already is set to "+analogMode);
+                return false;
+        }
+        if (!isAnalogModeSupported()) {
+                Log.d(LOGTAG,"Analog Path is not supported ");
+                return false;
+        }
+        if (SystemProperties.getBoolean("hw.fm.digitalpath",false)) {
+                return false;
+        }
+
+        boolean state = mReceiver.setAnalogMode(analogMode);
+        if (false == state) {
+            Log.d(LOGTAG, "Error in toggling analog/digital path " + analogMode);
+            return false;
+        }
+        misAnalogPathEnabled = analogMode;
+        return true;
+   }
+  /*
+   * Turn ON FM: Powers up FM hardware, and initializes the FM module
+   *                                                                                 .
+   * @return true if fm Enable api was invoked successfully, false if the api failed.
+   */
+   private boolean fmOn() {
+      boolean bStatus=false;
+      mWakeLock.acquire(10*1000);
+      if ( TelephonyManager.CALL_STATE_IDLE != getCallState() ) {
+         return bStatus;
+      }
+
+      if(mReceiver == null)
+      {
+         try {
+            mReceiver = new FmReceiver(FMRADIO_DEVICE_FD_STRING, fmCallbacks);
+         }
+         catch (InstantiationException e)
+         {
+            throw new RuntimeException("FmReceiver service not available!");
+         }
+      }
+
+      if (mReceiver != null)
+      {
+         if (isFmOn())
+         {
+            /* FM Is already on,*/
+            bStatus = true;
+            Log.d(LOGTAG, "mReceiver.already enabled");
+         }
+         else
+         {
+            // 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());
+            bStatus = mReceiver.enable(FmSharedPreferences.getFMConfiguration());
+            if (isSpeakerEnabled()) {
+                setAudioPath(false);
+            } else {
+                setAudioPath(true);
+            }
+            Log.d(LOGTAG, "mReceiver.enable done, Status :" +  bStatus);
+         }
+
+         if (bStatus == true)
+         {
+            /* Put the hardware into normal mode */
+            bStatus = setLowPowerMode(false);
+            Log.d(LOGTAG, "setLowPowerMode done, Status :" +  bStatus);
+
+
+            AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+            if( (audioManager != null) &&(false == mPlaybackInProgress) )
+            {
+               Log.d(LOGTAG, "mAudioManager.setFmRadioOn = true \n" );
+               //audioManager.setParameters("FMRadioOn="+mAudioDevice);
+               int state =  getCallState();
+               if ( TelephonyManager.CALL_STATE_IDLE != getCallState() )
+               {
+                 fmActionOnCallState(state);
+               } else {
+                   startFM(); // enable FM Audio only when Call is IDLE
+               }
+               Log.d(LOGTAG, "mAudioManager.setFmRadioOn done \n" );
+            }
+            if (mReceiver != null) {
+                bStatus = mReceiver.registerRdsGroupProcessing(FmReceiver.FM_RX_RDS_GRP_RT_EBL|
+                                                           FmReceiver.FM_RX_RDS_GRP_PS_EBL|
+                                                           FmReceiver.FM_RX_RDS_GRP_AF_EBL|
+                                                           FmReceiver.FM_RX_RDS_GRP_PS_SIMPLE_EBL);
+                Log.d(LOGTAG, "registerRdsGroupProcessing done, Status :" +  bStatus);
+            }
+            bStatus = enableAutoAF(FmSharedPreferences.getAutoAFSwitch());
+            Log.d(LOGTAG, "enableAutoAF done, Status :" +  bStatus);
+
+            /* There is no internal Antenna*/
+            bStatus = mReceiver.setInternalAntenna(false);
+            Log.d(LOGTAG, "setInternalAntenna done, Status :" +  bStatus);
+
+            /* Read back to verify the internal Antenna mode*/
+            readInternalAntennaAvailable();
+
+            startNotification();
+            bStatus = true;
+         }
+         else
+         {
+            mReceiver = null; // as enable failed no need to disable
+                              // failure of enable can be because handle
+                              // already open which gets effected if
+                              // we disable
+            stop();
+         }
+      }
+      return(bStatus);
+   }
+
+  /*
+   * Turn OFF FM Operations: This disables all the current FM operations             .
+   */
+   private void fmOperationsOff() {
+      if ( mSpeakerPhoneOn)
+      {
+          mSpeakerPhoneOn = false;
+          AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_NONE);
+      }
+      if (isFmRecordingOn())
+      {
+          stopRecording();
+      }
+      AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+      if(audioManager != null)
+      {
+         Log.d(LOGTAG, "audioManager.setFmRadioOn = false \n" );
+         unMute();
+         stopFM();
+         //audioManager.setParameters("FMRadioOn=false");
+         Log.d(LOGTAG, "audioManager.setFmRadioOn false done \n" );
+      }
+
+      if (isAnalogModeEnabled()) {
+              SystemProperties.set("hw.fm.isAnalog","false");
+              misAnalogPathEnabled = false;
+      }
+   }
+
+  /*
+   * Reset (OFF) FM Operations: This resets all the current FM operations             .
+   */
+   private void fmOperationsReset() {
+      if ( mSpeakerPhoneOn)
+      {
+          mSpeakerPhoneOn = false;
+          AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_NONE);
+      }
+
+      if (isFmRecordingOn())
+      {
+          resetRecording();
+      }
+
+      AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+      if(audioManager != null)
+      {
+         Log.d(LOGTAG, "audioManager.setFmRadioOn = false \n" );
+         unMute();
+         resetFM();
+         //audioManager.setParameters("FMRadioOn=false");
+         Log.d(LOGTAG, "audioManager.setFmRadioOn false done \n" );
+      }
+
+      if (isAnalogModeEnabled()) {
+              SystemProperties.set("hw.fm.isAnalog","false");
+              misAnalogPathEnabled = false;
+      }
+   }
+
+  /*
+   * 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;
+
+      fmOperationsOff();
+
+      // This will disable the FM radio device
+      if (mReceiver != null)
+      {
+         bStatus = mReceiver.disable();
+         mReceiver = null;
+      }
+      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.v(LOGTAG, "fmRadioReset");
+
+      fmOperationsReset();
+
+      // This will reset the FM radio receiver
+      if (mReceiver != null)
+      {
+         bStatus = mReceiver.reset();
+         mReceiver = null;
+      }
+      stop();
+      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;
+   }
+
+   /* Returns true if Analog Path is enabled */
+   public boolean isAnalogModeEnabled() {
+         return misAnalogPathEnabled;
+   }
+
+   public boolean isAnalogModeSupported() {
+        return misAnalogModeSupported;
+   }
+
+   public boolean isFmRecordingOn() {
+      return mFmRecordingOn;
+   }
+
+   public boolean isSpeakerEnabled() {
+      return mSpeakerPhoneOn;
+   }
+   public boolean isExternalStorageAvailable() {
+     boolean mStorageAvail = false;
+     String state = Environment.getExternalStorageState();
+
+     if(Environment.MEDIA_MOUNTED.equals(state)){
+         Log.d(LOGTAG, "device available");
+         mStorageAvail = true;
+     }
+     return mStorageAvail;
+   }
+   public void enableSpeaker(boolean speakerOn) {
+       if(isCallActive())
+           return ;
+       mSpeakerPhoneOn = speakerOn;
+       boolean analogmode = isAnalogModeSupported();
+       if (false == speakerOn) {
+           if (analogmode) {
+                if (isFmRecordingOn())
+                    stopRecording();
+                stopFM();
+               AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_NONE);
+               if (mMuted) {
+                   setAudioPath(true);
+               } else {
+                   mute();
+                   setAudioPath(true);
+                   unMute();
+               }
+           } else {
+               AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_NONE);
+           }
+           if (analogmode)
+                startFM();
+       }
+
+
+       //Need to turn off BT path when Speaker is set on vice versa.
+       if( !mA2dpDeviceSupportInHal && !analogmode && true == mA2dpDeviceState.isDeviceAvailable()) {
+           if( ((true == mOverA2DP) && (true == speakerOn)) ||
+               ((false == mOverA2DP) && (false == speakerOn)) ) {
+              //disable A2DP playback for speaker option
+               stopFM();
+               startFM();
+           }
+       }
+       if (speakerOn) {
+           if (analogmode) {
+                 stopFM();
+                 if (mMuted) {
+                     setAudioPath(false);
+                 } else {
+                     mute();
+                     setAudioPath(false);
+                     unMute();
+                 }
+           }
+           AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_SPEAKER);
+           if (analogmode)
+                startFM();
+       }
+
+   }
+  /*
+   *  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 (mReceiver != 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 = mReceiver.configure(config);
+      }
+      return(bStatus);
+   }
+
+   /*
+    * Register UI/Activity Callbacks
+    */
+   public void registerCallbacks(IFMRadioServiceCallbacks cb)
+   {
+      mCallbacks = cb;
+   }
+
+   /*
+    *  unRegister UI/Activity Callbacks
+    */
+   public void unregisterCallbacks()
+   {
+      mCallbacks=null;
+   }
+
+   /*
+   *  Route Audio to headset or speaker phone
+   *  @return true if routeAudio call succeeded, false if the route call failed.
+   */
+   public boolean routeAudio(int audioDevice) {
+      boolean bStatus=false;
+      AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+
+      //Log.d(LOGTAG, "routeAudio: " + audioDevice);
+
+      switch (audioDevice) {
+
+        case RADIO_AUDIO_DEVICE_WIRED_HEADSET:
+            mAudioDevice = "headset";
+            break;
+
+        case RADIO_AUDIO_DEVICE_SPEAKER:
+            mAudioDevice = "speaker";
+            break;
+
+        default:
+            mAudioDevice = "headset";
+            break;
+      }
+
+      if (mReceiver != null)
+      {
+      //audioManager.setParameters("FMRadioOn=false");
+      //Log.d(LOGTAG, "mAudioManager.setFmRadioOn =" + mAudioDevice );
+      //audioManager.setParameters("FMRadioOn="+mAudioDevice);
+      //Log.d(LOGTAG, "mAudioManager.setFmRadioOn done \n");
+       }
+
+       return bStatus;
+   }
+
+  /*
+   *  Mute FM Hardware (SoC)
+   * @return true if set mute mode api was invoked successfully, false if the api failed.
+   */
+   public boolean mute() {
+      boolean bCommandSent=true;
+      if(isMuted())
+          return bCommandSent;
+      if(isCallActive())
+         return false;
+      AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+      Log.d(LOGTAG, "mute:");
+      if (audioManager != null)
+      {
+         mMuted = true;
+         audioManager.setStreamMute(AudioManager.STREAM_MUSIC,true);
+      }
+      return bCommandSent;
+   }
+
+   /*
+   *  UnMute FM Hardware (SoC)
+   * @return true if set mute mode api was invoked successfully, false if the api failed.
+   */
+   public boolean unMute() {
+      boolean bCommandSent=true;
+      if(!isMuted())
+          return bCommandSent;
+      if(isCallActive())
+         return false;
+      Log.d(LOGTAG, "unMute:");
+      AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+      if (audioManager != null)
+      {
+         mMuted = false;
+         audioManager.setStreamMute(AudioManager.STREAM_MUSIC,false);
+         if (mResumeAfterCall)
+         {
+             //We are unmuting FM in a voice call. Need to enable FM audio routing.
+             startFM();
+         }
+      }
+      return bCommandSent;
+   }
+
+   /* Returns whether FM Hardware(Soc) Audio is Muted.
+    *
+    * @return true if FM Audio is muted, false if not muted.
+    *
+    */
+   public boolean isMuted() {
+      return mMuted;
+   }
+
+   /* 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, "tuneRadio:  " + doubleFrequency);
+      if (mReceiver != null)
+      {
+         mReceiver.setStation(frequency);
+         bCommandSent = true;
+      }
+      return bCommandSent;
+   }
+
+   /* Seeks (Search for strong station) to the station in the direction specified
+    * relative to the tuned station.
+    * boolean up: true - Search in the forward direction.
+    *             false - Search in the backward direction.
+    * @return true if Seek command was invoked successfully, false if not muted.
+    *  Note: 1. Callback FmRxEvSearchComplete will be called when the Search
+    *        is complete
+    *        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 seek(boolean up)
+   {
+      boolean bCommandSent=false;
+      if (mReceiver != null)
+      {
+         if (up == true)
+         {
+            Log.d(LOGTAG, "seek:  Up");
+            mReceiver.searchStations(FmReceiver.FM_RX_SRCH_MODE_SEEK,
+                                             FmReceiver.FM_RX_DWELL_PERIOD_1S,
+                                             FmReceiver.FM_RX_SEARCHDIR_UP);
+         }
+         else
+         {
+            Log.d(LOGTAG, "seek:  Down");
+            mReceiver.searchStations(FmReceiver.FM_RX_SRCH_MODE_SEEK,
+                                             FmReceiver.FM_RX_DWELL_PERIOD_1S,
+                                             FmReceiver.FM_RX_SEARCHDIR_DOWN);
+         }
+         bCommandSent = true;
+      }
+      return bCommandSent;
+   }
+
+   /* Scan (Search for station with a "preview" of "n" seconds)
+    * FM Stations. It always scans in the forward direction relative to the
+    * current tuned station.
+    * int pty: 0 or a reserved PTY value- Perform a "strong" station search of all stations.
+    *          Valid/Known PTY - perform RDS Scan for that pty.
+    *
+    * @return true if Scan command was invoked successfully, false if not muted.
+    *  Note: 1. Callback FmRxEvRadioTuneStatus will be called when tuned to various stations
+    *           during the Scan.
+    *        2. Callback FmRxEvSearchComplete will be called when the Search
+    *        is complete
+    *        3. 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 scan(int pty)
+   {
+      boolean bCommandSent=false;
+      if (mReceiver != null)
+      {
+         Log.d(LOGTAG, "scan:  PTY: " + pty);
+         if(FmSharedPreferences.isRBDSStd())
+         {
+            /* RBDS : Validate PTY value?? */
+            if( ((pty  > 0) && (pty  <= 23)) || ((pty  >= 29) && (pty  <= 31)) )
+            {
+               bCommandSent = mReceiver.searchStations(FmReceiver.FM_RX_SRCHRDS_MODE_SCAN_PTY,
+                                                       FmReceiver.FM_RX_DWELL_PERIOD_2S,
+                                                       FmReceiver.FM_RX_SEARCHDIR_UP,
+                                                       pty,
+                                                       0);
+            }
+            else
+            {
+               bCommandSent = mReceiver.searchStations(FmReceiver.FM_RX_SRCH_MODE_SCAN,
+                                                FmReceiver.FM_RX_DWELL_PERIOD_2S,
+                                                FmReceiver.FM_RX_SEARCHDIR_UP);
+            }
+         }
+         else
+         {
+            /* RDS : Validate PTY value?? */
+            if( (pty  > 0) && (pty  <= 31) )
+            {
+               bCommandSent = mReceiver.searchStations(FmReceiver.FM_RX_SRCHRDS_MODE_SCAN_PTY,
+                                                          FmReceiver.FM_RX_DWELL_PERIOD_2S,
+                                                          FmReceiver.FM_RX_SEARCHDIR_UP,
+                                                          pty,
+                                                          0);
+            }
+            else
+            {
+               bCommandSent = mReceiver.searchStations(FmReceiver.FM_RX_SRCH_MODE_SCAN,
+                                                FmReceiver.FM_RX_DWELL_PERIOD_2S,
+                                                FmReceiver.FM_RX_SEARCHDIR_UP);
+            }
+         }
+      }
+      return bCommandSent;
+   }
+
+   /* Search for the 'numStations' number of strong FM Stations.
+    *
+    * 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 searchStrongStationList(int numStations)
+   {
+      boolean bCommandSent=false;
+      if (mReceiver != null)
+      {
+         Log.d(LOGTAG, "searchStrongStationList:  numStations: " + numStations);
+         bCommandSent = mReceiver.searchStationList(FmReceiver.FM_RX_SRCHLIST_MODE_STRONG,
+                                                    FmReceiver.FM_RX_SEARCHDIR_UP,
+                                                    numStations,
+                                                    0);
+      }
+      return bCommandSent;
+   }
+
+   /* Search for the FM Station that matches the RDS PI (Program Identifier) code.
+    * It always scans in the forward direction relative to the current tuned station.
+    * int piCode: PI Code of the station to search.
+    *
+    * @return true if Search command was invoked successfully, false if not muted.
+    *  Note: 1. Callback FmRxEvSearchComplete will be called when the Search
+    *        is complete
+    *        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 seekPI(int piCode)
+   {
+      boolean bCommandSent=false;
+      if (mReceiver != null)
+      {
+         Log.d(LOGTAG, "seekPI:  piCode: " + piCode);
+         bCommandSent = mReceiver.searchStations(FmReceiver.FM_RX_SRCHRDS_MODE_SEEK_PI,
+                                                            FmReceiver.FM_RX_DWELL_PERIOD_1S,
+                                                            FmReceiver.FM_RX_SEARCHDIR_UP,
+                                                            0,
+                                                            piCode
+                                                            );
+      }
+      return bCommandSent;
+   }
+
+
+  /* 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 bCommandSent=false;
+      if (mReceiver != null)
+      {
+         Log.d(LOGTAG, "cancelSearch");
+         bCommandSent = mReceiver.cancelSearch();
+      }
+      return bCommandSent;
+   }
+
+   /* Retrieves the RDS Program Service (PS) String.
+    *
+    * @return String - RDS PS String.
+    *  Note: 1. This is a synchronous call that should typically called when
+    *           Callback FmRxEvRdsPsInfo is invoked.
+    *        2. Since PS contains multiple fields, this Service reads all the fields and "caches"
+    *        the values and provides this helper routine for the Activity to get only the information it needs.
+    *        3. The "cached" data fields are always "cleared" when the tune status changes.
+    */
+   public String getProgramService() {
+      String str = "";
+      if (mFMRxRDSData != null)
+      {
+         str = mFMRxRDSData.getPrgmServices();
+         if(str == null)
+         {
+            str= "";
+         }
+      }
+      Log.d(LOGTAG, "Program Service: [" + str + "]");
+      return str;
+   }
+
+   /* Retrieves the RDS Radio Text (RT) String.
+    *
+    * @return String - RDS RT String.
+    *  Note: 1. This is a synchronous call that should typically called when
+    *           Callback FmRxEvRdsRtInfo is invoked.
+    *        2. Since RT contains multiple fields, this Service reads all the fields and "caches"
+    *        the values and provides this helper routine for the Activity to get only the information it needs.
+    *        3. The "cached" data fields are always "cleared" when the tune status changes.
+    */
+   public String getRadioText() {
+      String str = "";
+      if (mFMRxRDSData != null)
+      {
+         str = mFMRxRDSData.getRadioText();
+         if(str == null)
+         {
+            str= "";
+         }
+      }
+      Log.d(LOGTAG, "Radio Text: [" + str + "]");
+      return str;
+   }
+
+   public String getExtenRadioText() {
+      String str = "";
+      if (mFMRxRDSData != null)
+      {
+         str = mFMRxRDSData.getERadioText();
+         if(str == null)
+         {
+            str= "";
+         }
+      }
+      Log.d(LOGTAG, "eRadio Text:[" + str +"]");
+      return str;
+   }
+   /* Retrieves the RDS Program Type (PTY) code.
+    *
+    * @return int - RDS PTY code.
+    *  Note: 1. This is a synchronous call that should typically called when
+    *           Callback FmRxEvRdsRtInfo and or FmRxEvRdsPsInfo is invoked.
+    *        2. Since RT/PS contains multiple fields, this Service reads all the fields and "caches"
+    *        the values and provides this helper routine for the Activity to get only the information it needs.
+    *        3. The "cached" data fields are always "cleared" when the tune status changes.
+    */
+   public int getProgramType() {
+      int pty = -1;
+      if (mFMRxRDSData != null)
+      {
+         pty = mFMRxRDSData.getPrgmType();
+      }
+      Log.d(LOGTAG, "PTY: [" + pty + "]");
+      return pty;
+   }
+
+   /* Retrieves the RDS Program Identifier (PI).
+    *
+    * @return int - RDS PI code.
+    *  Note: 1. This is a synchronous call that should typically called when
+    *           Callback FmRxEvRdsRtInfo and or FmRxEvRdsPsInfo is invoked.
+    *        2. Since RT/PS contains multiple fields, this Service reads all the fields and "caches"
+    *        the values and provides this helper routine for the Activity to get only the information it needs.
+    *        3. The "cached" data fields are always "cleared" when the tune status changes.
+    */
+   public int getProgramID() {
+      int pi = -1;
+      if (mFMRxRDSData != null)
+      {
+         pi = mFMRxRDSData.getPrgmId();
+      }
+      Log.d(LOGTAG, "PI: [" + pi + "]");
+      return pi;
+   }
+
+
+   /* 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 (mReceiver != null)
+      {
+         Log.d(LOGTAG, "setLowPowerMode: " + bLowPower);
+         if(bLowPower)
+         {
+            bCommandSent = mReceiver.setPowerMode(FmReceiver.FM_RX_LOW_POWER_MODE);
+         }
+         else
+         {
+            bCommandSent = mReceiver.setPowerMode(FmReceiver.FM_RX_NORMAL_POWER_MODE);
+         }
+      }
+      return bCommandSent;
+   }
+
+   /* Get the FM Power Mode on the FM hardware SoC.
+    *
+    * @return the device power mode.
+    */
+   public int getPowerMode()
+   {
+      int powerMode=FmReceiver.FM_RX_NORMAL_POWER_MODE;
+      if (mReceiver != null)
+      {
+         powerMode = mReceiver.getPowerMode();
+         Log.d(LOGTAG, "getLowPowerMode: " + powerMode);
+      }
+      return powerMode;
+   }
+
+  /* Set the FM module to auto switch to an Alternate Frequency for the
+   * station if one the signal strength of that frequency is stronger than the
+   * current tuned frequency.
+   *
+   * boolean bEnable: true: Auto switch to stronger alternate frequency.
+   *                  false: Do not switch to alternate frequency.
+   *
+   * @return true if set Auto AF mode api was invoked successfully, false if the api failed.
+   *  Note: Callback FmRxEvRadioTuneStatus will be called when tune
+   *        is complete to a different frequency.
+   */
+   public boolean enableAutoAF(boolean bEnable)
+   {
+      boolean bCommandSent=false;
+      if (mReceiver != null)
+      {
+         Log.d(LOGTAG, "enableAutoAF: " + bEnable);
+         bCommandSent = mReceiver.enableAFjump(bEnable);
+      }
+      return bCommandSent;
+   }
+
+   /* Set the FM module to Stereo Mode or always force it to Mono Mode.
+    * Note: The stereo mode will be available only when the station is broadcasting
+    * in Stereo mode.
+    *
+    * boolean bEnable: true: Enable Stereo Mode.
+    *                  false: Always stay in Mono Mode.
+    *
+    * @return true if set Stereo mode api was invoked successfully, false if the api failed.
+    */
+   public boolean enableStereo(boolean bEnable)
+   {
+      boolean bCommandSent=false;
+      if (mReceiver != null)
+      {
+         Log.d(LOGTAG, "enableStereo: " + bEnable);
+         bCommandSent = mReceiver.setStereoMode(bEnable);
+      }
+      return bCommandSent;
+   }
+
+   /** Determines if an internal Antenna is available.
+    *  Returns the cached value initialized on FMOn.
+    *
+    * @return true if internal antenna is available or wired
+    *         headset is plugged in, false if internal antenna is
+    *         not available and wired headset is not plugged in.
+    */
+   public boolean isAntennaAvailable()
+   {
+      boolean bAvailable = false;
+      if ((mInternalAntennaAvailable) || (mHeadsetPlugged) )
+      {
+         bAvailable = true;
+      }
+      return bAvailable;
+   }
+
+   public static long getAvailableSpace() {
+       String state = Environment.getExternalStorageState();
+       Log.d(LOGTAG, "External storage state=" + state);
+       if (Environment.MEDIA_CHECKING.equals(state)) {
+           return PREPARING;
+       }
+       if (!Environment.MEDIA_MOUNTED.equals(state)) {
+           return UNAVAILABLE;
+       }
+
+       try {
+            File sampleDir = Environment.getExternalStorageDirectory();
+            StatFs stat = new StatFs(sampleDir.getAbsolutePath());
+            return stat.getAvailableBlocks() * (long) stat.getBlockSize();
+       } catch (Exception e) {
+            Log.i(LOGTAG, "Fail to access external storage", e);
+       }
+       return UNKNOWN_SIZE;
+  }
+
+   private boolean updateAndShowStorageHint() {
+       mStorageSpace = getAvailableSpace();
+       return showStorageHint();
+   }
+
+   private boolean showStorageHint() {
+       String errorMessage = null;
+       if (mStorageSpace == UNAVAILABLE) {
+           errorMessage = getString(R.string.no_storage);
+       } else if (mStorageSpace == PREPARING) {
+           errorMessage = getString(R.string.preparing_sd);
+       } else if (mStorageSpace == UNKNOWN_SIZE) {
+           errorMessage = getString(R.string.access_sd_fail);
+       } else if (mStorageSpace < LOW_STORAGE_THRESHOLD) {
+           errorMessage = getString(R.string.spaceIsLow_content);
+       }
+
+       if (errorMessage != null) {
+           Toast.makeText(this, errorMessage,
+                    Toast.LENGTH_LONG).show();
+           return false;
+       }
+       return true;
+   }
+
+   /** Determines if a Wired headset is plugged in. Returns the
+    *  cached value initialized on broadcast receiver
+    *  initialization.
+    *
+    * @return true if wired headset is plugged in, false if wired
+    *         headset is not plugged in.
+    */
+   public boolean isWiredHeadsetAvailable()
+   {
+      return (mHeadsetPlugged);
+   }
+   public boolean isCallActive()
+   {
+       //Non-zero: Call state is RINGING or OFFHOOK on the available subscriptions
+       //zero: Call state is IDLE on all the available subscriptions
+       if(0 != getCallState()) return true;
+       return false;
+   }
+   public int getCallState()
+   {
+       return mCallStatus;
+   }
+
+   public void clearStationInfo() {
+       if(mFMRxRDSData != null) {
+          mFMRxRDSData.setRadioText("");
+          mFMRxRDSData.setPrgmId(0);
+          mFMRxRDSData.setPrgmType(0);
+          mFMRxRDSData.setPrgmServices("");
+          mFMRxRDSData.setERadioText("");
+          mFMRxRDSData.setTagValue("", 1);
+          mFMRxRDSData.setTagValue("", 2);
+          mFMRxRDSData.setTagCode((byte)0, 1);
+          mFMRxRDSData.setTagCode((byte)0, 2);
+          Log.d(LOGTAG, "clear tags data");
+          FmSharedPreferences.clearTags();
+       }
+   }
+
+   /* Receiver callbacks back from the FM Stack */
+   FmRxEvCallbacksAdaptor fmCallbacks = new FmRxEvCallbacksAdaptor()
+   {
+      public void FmRxEvEnableReceiver() {
+         Log.d(LOGTAG, "FmRxEvEnableReceiver");
+         mReceiver.setRawRdsGrpMask();
+      }
+      public void FmRxEvDisableReceiver()
+      {
+         Log.d(LOGTAG, "FmRxEvDisableReceiver");
+         mFMOn = false;
+         FmSharedPreferences.clearTags();
+      }
+      public void FmRxEvRadioReset()
+      {
+         Log.d(LOGTAG, "FmRxEvRadioReset");
+         if(isFmOn()) {
+             // Received radio reset event while FM is ON
+             Log.d(LOGTAG, "FM Radio reset");
+             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 FmRxEvConfigReceiver()
+      {
+         Log.d(LOGTAG, "FmRxEvConfigReceiver");
+      }
+      public void FmRxEvMuteModeSet()
+      {
+         Log.d(LOGTAG, "FmRxEvMuteModeSet");
+      }
+      public void FmRxEvStereoModeSet()
+      {
+         Log.d(LOGTAG, "FmRxEvStereoModeSet");
+      }
+      public void FmRxEvRadioStationSet()
+      {
+         Log.d(LOGTAG, "FmRxEvRadioStationSet");
+      }
+      public void FmRxEvPowerModeSet()
+      {
+         Log.d(LOGTAG, "FmRxEvPowerModeSet");
+      }
+      public void FmRxEvSetSignalThreshold()
+      {
+         Log.d(LOGTAG, "FmRxEvSetSignalThreshold");
+      }
+
+      public void FmRxEvRadioTuneStatus(int frequency)
+      {
+         Log.d(LOGTAG, "FmRxEvRadioTuneStatus: Tuned Frequency: " +frequency);
+         try
+         {
+            FmSharedPreferences.setTunedFrequency(frequency);
+            mPrefs.Save();
+            //Log.d(LOGTAG, "Call mCallbacks.onTuneStatusChanged");
+            /* Since the Tuned Status changed, clear out the RDSData cached */
+            if(mReceiver != null) {
+               clearStationInfo();
+            }
+            if(mCallbacks != null)
+            {
+               mCallbacks.onTuneStatusChanged();
+            }
+            /* Update the frequency in the StatusBar's Notification */
+            startNotification();
+
+         }
+         catch (RemoteException e)
+         {
+            e.printStackTrace();
+         }
+      }
+
+      public void FmRxEvStationParameters()
+      {
+         Log.d(LOGTAG, "FmRxEvStationParameters");
+      }
+
+      public void FmRxEvRdsLockStatus(boolean bRDSSupported)
+      {
+         Log.d(LOGTAG, "FmRxEvRdsLockStatus: " + bRDSSupported);
+         try
+         {
+            if(mCallbacks != null)
+            {
+               mCallbacks.onStationRDSSupported(bRDSSupported);
+            }
+         }
+         catch (RemoteException e)
+         {
+            e.printStackTrace();
+         }
+      }
+
+      public void FmRxEvStereoStatus(boolean stereo)
+      {
+         Log.d(LOGTAG, "FmRxEvStereoStatus: " + stereo);
+         try
+         {
+            if(mCallbacks != null)
+            {
+               mCallbacks.onAudioUpdate(stereo);
+            }
+         }
+         catch (RemoteException e)
+         {
+            e.printStackTrace();
+         }
+      }
+      public void FmRxEvServiceAvailable(boolean signal)
+      {
+         Log.d(LOGTAG, "FmRxEvServiceAvailable");
+         if(signal) {
+             Log.d(LOGTAG, "FmRxEvServiceAvailable: Tuned frequency is above signal threshold level");
+         }
+         else {
+             Log.d(LOGTAG, "FmRxEvServiceAvailable: Tuned frequency is below signal threshold level");
+         }
+      }
+      public void FmRxEvGetSignalThreshold()
+      {
+         Log.d(LOGTAG, "FmRxEvGetSignalThreshold");
+      }
+      public void FmRxEvSearchInProgress()
+      {
+         Log.d(LOGTAG, "FmRxEvSearchInProgress");
+      }
+      public void FmRxEvSearchRdsInProgress()
+      {
+         Log.d(LOGTAG, "FmRxEvSearchRdsInProgress");
+      }
+      public void FmRxEvSearchListInProgress()
+      {
+         Log.d(LOGTAG, "FmRxEvSearchListInProgress");
+      }
+      public void FmRxEvSearchComplete(int frequency)
+       {
+         Log.d(LOGTAG, "FmRxEvSearchComplete: Tuned Frequency: " +frequency);
+         try
+         {
+            FmSharedPreferences.setTunedFrequency(frequency);
+            //Log.d(LOGTAG, "Call mCallbacks.onSearchComplete");
+            /* Since the Tuned Status changed, clear out the RDSData cached */
+            if(mReceiver != null) {
+               clearStationInfo();
+            }
+            if(mCallbacks != null)
+            {
+               mCallbacks.onSearchComplete();
+            }
+            /* Update the frequency in the StatusBar's Notification */
+            startNotification();
+         }
+         catch (RemoteException e)
+         {
+            e.printStackTrace();
+         }
+      }
+
+      public void FmRxEvSearchRdsComplete()
+      {
+         Log.d(LOGTAG, "FmRxEvSearchRdsComplete");
+      }
+
+      public void FmRxEvSearchListComplete()
+      {
+         Log.d(LOGTAG, "FmRxEvSearchListComplete");
+         try
+         {
+            if(mCallbacks != null)
+            {
+               mCallbacks.onSearchListComplete();
+            }
+         } catch (RemoteException e)
+         {
+            e.printStackTrace();
+         }
+      }
+
+      public void FmRxEvSearchCancelled()
+      {
+         Log.d(LOGTAG, "FmRxEvSearchCancelled: Cancelled the on-going search operation.");
+      }
+      public void FmRxEvRdsGroupData()
+      {
+         Log.d(LOGTAG, "FmRxEvRdsGroupData");
+      }
+
+      public void FmRxEvRdsPsInfo() {
+         Log.d(LOGTAG, "FmRxEvRdsPsInfo: ");
+         try
+         {
+            if(mReceiver != null)
+            {
+               mFMRxRDSData = mReceiver.getPSInfo();
+               if(mFMRxRDSData != null)
+               {
+                  Log.d(LOGTAG, "PI: [" + mFMRxRDSData.getPrgmId() + "]");
+                  Log.d(LOGTAG, "PTY: [" + mFMRxRDSData.getPrgmType() + "]");
+                  Log.d(LOGTAG, "PS: [" + mFMRxRDSData.getPrgmServices() + "]");
+               }
+               if(mCallbacks != null)
+               {
+                  mCallbacks.onProgramServiceChanged();
+               }
+            }
+         } catch (RemoteException e)
+         {
+            e.printStackTrace();
+         }
+      }
+
+      public void FmRxEvRdsRtInfo() {
+         Log.d(LOGTAG, "FmRxEvRdsRtInfo");
+         try
+         {
+            //Log.d(LOGTAG, "Call mCallbacks.onRadioTextChanged");
+            if(mReceiver != null)
+            {
+               mFMRxRDSData = mReceiver.getRTInfo();
+               if(mFMRxRDSData != null)
+               {
+                  Log.d(LOGTAG, "PI: [" + mFMRxRDSData.getPrgmId() + "]");
+                  Log.d(LOGTAG, "PTY: [" + mFMRxRDSData.getPrgmType() + "]");
+                  Log.d(LOGTAG, "RT: [" + mFMRxRDSData.getRadioText() + "]");
+               }
+               if(mCallbacks != null)
+               {
+                  mCallbacks.onRadioTextChanged();
+               }
+            }
+         } catch (RemoteException e)
+         {
+            e.printStackTrace();
+         }
+
+      }
+
+      public void FmRxEvRdsAfInfo()
+      {
+         Log.d(LOGTAG, "FmRxEvRdsAfInfo");
+         mReceiver.getAFInfo();
+      }
+      public void FmRxEvRTPlus()
+      {
+         int tag_nums;
+         Log.d(LOGTAG, "FmRxEvRTPlusInfo");
+         if (mReceiver != null) {
+             mFMRxRDSData = mReceiver.getRTPlusInfo();
+             tag_nums = mFMRxRDSData.getTagNums();
+             if (tag_nums >= 1) {
+                 Log.d(LOGTAG, "tag1 is: " + mFMRxRDSData.getTagCode(1) + "value: "
+                        + mFMRxRDSData.getTagValue(1));
+                 FmSharedPreferences.addTags(mFMRxRDSData.getTagCode(1), mFMRxRDSData.getTagValue(1));
+             }
+             if(tag_nums == 2) {
+                Log.d(LOGTAG, "tag2 is: " + mFMRxRDSData.getTagCode(2) + "value: "
+                      + mFMRxRDSData.getTagValue(2));
+                 FmSharedPreferences.addTags(mFMRxRDSData.getTagCode(2), mFMRxRDSData.getTagValue(2));
+             }
+         }
+      }
+      public void FmRxEvERTInfo()
+      {
+         Log.d(LOGTAG, "FmRxEvERTInfo");
+         try {
+             if (mReceiver != null) {
+                mFMRxRDSData = mReceiver.getERTInfo();
+                if(mCallbacks != null)
+                   mCallbacks.onExtenRadioTextChanged();
+             }
+         } catch (RemoteException e) {
+             e.printStackTrace();
+         }
+      }
+      public void FmRxEvRdsPiMatchAvailable()
+      {
+         Log.d(LOGTAG, "FmRxEvRdsPiMatchAvailable");
+      }
+      public void FmRxEvRdsGroupOptionsSet()
+      {
+         Log.d(LOGTAG, "FmRxEvRdsGroupOptionsSet");
+      }
+      public void FmRxEvRdsProcRegDone()
+      {
+         Log.d(LOGTAG, "FmRxEvRdsProcRegDone");
+      }
+      public void FmRxEvRdsPiMatchRegDone()
+      {
+         Log.d(LOGTAG, "FmRxEvRdsPiMatchRegDone");
+      }
+   };
+
+
+   /*
+    *  Read the Tuned Frequency from the FM module.
+    */
+   private String getTunedFrequencyString() {
+
+      double frequency = FmSharedPreferences.getTunedFrequency() / 1000.0;
+      String frequencyString = getString(R.string.stat_notif_frequency, (""+frequency));
+      return frequencyString;
+   }
+   public int getRssi() {
+      if (mReceiver != null)
+          return mReceiver.getRssi();
+      else
+          return Integer.MAX_VALUE;
+   }
+   public int getIoC() {
+      if (mReceiver != null)
+          return mReceiver.getIoverc();
+      else
+          return Integer.MAX_VALUE;
+   }
+   public int getIntDet() {
+      if (mReceiver != null)
+          return mReceiver.getIntDet();
+      else
+          return Integer.MAX_VALUE;
+   }
+   public int getMpxDcc() {
+      if (mReceiver != null)
+          return mReceiver.getMpxDcc();
+      else
+          return Integer.MAX_VALUE;
+   }
+   public void setHiLoInj(int inj) {
+      if (mReceiver != null)
+          mReceiver.setHiLoInj(inj);
+   }
+   public int getSINR() {
+      if (mReceiver != null)
+          return mReceiver.getSINR();
+      else
+          return Integer.MAX_VALUE;
+   }
+   public boolean setSinrSamplesCnt(int samplesCnt) {
+      if(mReceiver != null)
+         return mReceiver.setSINRsamples(samplesCnt);
+      else
+         return false;
+   }
+   public boolean setSinrTh(int sinr) {
+      if(mReceiver != null)
+         return mReceiver.setSINRThreshold(sinr);
+      else
+         return false;
+   }
+   public boolean setIntfDetLowTh(int intfLowTh) {
+      if(mReceiver != null)
+         return mReceiver.setOnChannelThreshold(intfLowTh);
+      else
+         return false;
+   }
+   public boolean setIntfDetHighTh(int intfHighTh) {
+      if(mReceiver != null)
+         return mReceiver.setOffChannelThreshold(intfHighTh);
+      else
+         return false;
+   }
+
+   private void setAlarmSleepExpired (long duration) {
+       Intent i = new Intent(SLEEP_EXPIRED_ACTION);
+       AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+       PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
+       Log.d(LOGTAG, "delayedStop called" + SystemClock.elapsedRealtime() + duration);
+       am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + duration, pi);
+   }
+   private void cancelAlarmSleepExpired() {
+       Intent i = new Intent(SLEEP_EXPIRED_ACTION);
+       AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+       PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
+       am.cancel(pi);
+   }
+   private void setAlarmRecordTimeout(long duration) {
+       Intent i = new Intent(RECORD_EXPIRED_ACTION);
+       AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+       PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
+       Log.d(LOGTAG, "delayedStop called" + SystemClock.elapsedRealtime() + duration);
+       am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + duration, pi);
+   }
+   private void cancelAlarmRecordTimeout() {
+       Intent i = new Intent(RECORD_EXPIRED_ACTION);
+       AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+       PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
+       am.cancel(pi);
+   }
+   private void setAlarmDelayedServiceStop() {
+       Intent i = new Intent(SERVICE_DELAYED_STOP_ACTION);
+       AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+       PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
+       am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + IDLE_DELAY, pi);
+   }
+   private void cancelAlarmDealyedServiceStop() {
+       Intent i = new Intent(SERVICE_DELAYED_STOP_ACTION);
+       AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+       PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
+       am.cancel(pi);
+   }
+   private void cancelAlarms() {
+       cancelAlarmSleepExpired();
+       cancelAlarmRecordTimeout();
+       cancelAlarmDealyedServiceStop();
+   }
+   //handling the sleep and record stop when FM App not in focus
+   private void delayedStop(long duration, int nType) {
+       int whatId = (nType == STOP_SERVICE) ? STOPSERVICE_ONSLEEP: STOPRECORD_ONTIMEOUT;
+       if (nType == STOP_SERVICE)
+           setAlarmSleepExpired(duration);
+       else
+           setAlarmRecordTimeout(duration);
+   }
+   private void cancelDelayedStop(int nType) {
+       int whatId = (nType == STOP_SERVICE) ? STOPSERVICE_ONSLEEP: STOPRECORD_ONTIMEOUT;
+       if (nType == STOP_SERVICE)
+           cancelAlarmSleepExpired();
+       else
+           cancelAlarmRecordTimeout();
+   }
+   private void requestFocus() {
+      if( (false == mPlaybackInProgress) &&
+          (true  == mStoppedOnFocusLoss) ) {
+           // adding code for audio focus gain.
+           AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+           audioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
+                  AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+           startFM();
+           mStoppedOnFocusLoss = false;
+       }
+   }
+   private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() {
+       public void onAudioFocusChange(int focusChange) {
+           mDelayedStopHandler.obtainMessage(FOCUSCHANGE, focusChange, 0).sendToTarget();
+       }
+   };
+}
diff --git a/fmapp2/src/com/caf/fmradio/FMStats.java b/fmapp2/src/com/caf/fmradio/FMStats.java
new file mode 100644
index 0000000..2afb301
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/FMStats.java
@@ -0,0 +1,1346 @@
+/*
+ * Copyright (c) 2011-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.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ProgressBar;
+import android.widget.Spinner;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+import android.widget.TextView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import qcom.fmradio.FmReceiver;
+import android.os.SystemProperties;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.HashMap;
+import android.os.SystemProperties;
+
+
+public class FMStats extends Activity  {
+
+    EditText txtbox1;
+    TextView tv1;
+    Button SetButton;
+    Button RunButton;
+    ProgressBar  pbar;
+    TableLayout tLayout;
+
+    private FmReceiver mReceiver;
+
+    /*Data structure for band*/
+    private class Band {
+
+        public int lFreq;
+        public int hFreq;
+        public int Spacing;
+    }
+    /* Data structure for Result*/
+    private class Result {
+
+      private String mFreq;
+      private String mRSSI;
+      private String mIoC;
+      private String mIntDet;
+      private String mMpxDcc;
+      private String mSINR;
+
+
+      public void setFreq(String aFreq) {
+         this.mFreq = aFreq;
+      }
+
+      public String getFreq() {
+         return mFreq;
+      }
+
+      public void setRSSI(String aRSSI) {
+         this.mRSSI = aRSSI;
+      }
+
+      public String getRSSI() {
+         return mRSSI;
+      }
+
+      public void setIoC(String aIoC) {
+         this.mIoC = aIoC;
+      }
+
+      public String getIoC() {
+         return mIoC;
+      }
+
+      public void setIntDet(String aIntDet) {
+         this.mIntDet = aIntDet;
+      }
+
+      public String getIntDet() {
+         return mIntDet;
+      }
+
+      public void setMpxDcc(String aMpxDcc) {
+         this.mMpxDcc = aMpxDcc;
+      }
+
+      public String getMpxDcc() {
+         return mMpxDcc;
+      }
+      public void setSINR(String aSINR) {
+         this.mSINR = aSINR;
+      }
+
+      public String getSINR() {
+         return mSINR;
+      }
+
+    };
+
+    /*constant column header*/
+    Result mColumnHeader = new Result();
+
+    boolean mTestRunning = false;
+    FmRfItemSelectedListener mSpinFmRfListener = new FmRfItemSelectedListener();
+    RfCfgItemSelectedListener mSpinRfCfgListener = new RfCfgItemSelectedListener();
+    CfgRfItemSelectedListener1 mSpinCfgRfListener1 = null;
+    CfgRfItemSelectedListener2 mSpinCfgRfListener2 = null;
+
+
+    int  mTestSelected = 0;
+    boolean mIsSearching = false;
+    private static String LOGTAG = "FMStats";
+    private static IFMRadioService mService = null;
+    private Thread mMultiUpdateThread =null;
+    private static final int STATUS_UPDATE =1;
+    private static final int STATUS_DONE =2;
+    private static final int STOP_ROW_ID =200;
+    private static final int NEW_ROW_ID = 300;
+    private int mStopIds = STOP_ROW_ID;
+    private int mNewRowIds = NEW_ROW_ID;
+    private static final int SCAN_DWELL_PERIOD = 1;
+
+    private static final int CUR_FREQ_TEST =0;
+    private static final int CUR_MULTI_TEST = 1;
+    private static final int SEARCH_TEST =2;
+    private static final int SWEEP_TEST =3;
+    private Band mBand =null;
+    private Band mSync = null;
+    int Lo = 1, Auto = 0;
+
+    private FileOutputStream mFileCursor =null;
+    private String mCurrentFileName = null;
+
+    Spinner spinOptionFmRf;
+    ArrayAdapter<CharSequence> adaptCfgRf;
+    ArrayAdapter<CharSequence> adaptRfCfg;
+    ArrayAdapter<CharSequence> adaptFmRf;
+
+    private static boolean mIsTransportSMD = false;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        this.setContentView(R.layout.fmstats);
+
+        spinOptionFmRf = (Spinner) findViewById(R.id.spinner);
+        adaptFmRf = ArrayAdapter.createFromResource(
+            this, R.array.stats_options, android.R.layout.simple_spinner_item);
+        adaptFmRf.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        if (spinOptionFmRf != null) {
+           spinOptionFmRf.setAdapter(adaptFmRf);
+           spinOptionFmRf.setOnItemSelectedListener(mSpinFmRfListener);
+        }
+
+        checkTransportLayer();
+        if (!isTransportLayerSMD()) {
+            mSpinCfgRfListener1 = new CfgRfItemSelectedListener1();
+            adaptCfgRf = ArrayAdapter.createFromResource(
+                           this, R.array.cfg_rf1,
+                           android.R.layout.simple_spinner_item);
+        } else {
+            mSpinCfgRfListener2 = new CfgRfItemSelectedListener2();
+            adaptCfgRf = ArrayAdapter.createFromResource(
+                           this, R.array.cfg_rf2,
+                           android.R.layout.simple_spinner_item);
+        }
+        adaptRfCfg = ArrayAdapter.createFromResource(
+            this, R.array.rf_cfg, android.R.layout.simple_spinner_item);
+
+        tLayout = (TableLayout) findViewById(R.id.maintable);
+
+        if(mReceiver == null)
+            mReceiver = new FmReceiver();
+
+        long  curTime = System.currentTimeMillis();
+        mCurrentFileName = "FMStats_".concat(Long.toString(curTime).concat(".txt"));
+        Log.e(LOGTAG,"Filename is "+mCurrentFileName);
+        try {
+            mFileCursor = openFileOutput(mCurrentFileName, Context.MODE_PRIVATE);
+            if(null != mFileCursor) {
+               Log.e(LOGTAG, "location of the file is"+getFilesDir());
+            }
+        } catch (IOException e) {
+             e.printStackTrace();
+            Log.e(LOGTAG,"Couldn't create the file to writeLog");
+            mCurrentFileName = null;
+        }
+
+        if (false == bindToService(this, osc))
+        {
+           Log.d(LOGTAG, "onCreate: Failed to Start Service");
+        }
+        else
+        {
+           Log.d(LOGTAG, "onCreate: Start Service completed successfully");
+        }
+
+	/*Initialize the column header with
+	constant values*/
+	mColumnHeader.setFreq("Freq");
+	mColumnHeader.setRSSI("RMSSI");
+	mColumnHeader.setIoC("IoC");
+        mColumnHeader.setSINR("SINR");
+	mColumnHeader.setMpxDcc("Offset");
+	mColumnHeader.setIntDet("IntDet");
+    }
+
+    public void onDestroy() {
+        if(null != mFileCursor ) {
+	    try {
+		mFileCursor.close();
+            } catch (IOException e) {
+
+                e.printStackTrace();
+            }
+        }
+	/*Stop the thread by interrupting it*/
+	if(mMultiUpdateThread != null) {
+		mMultiUpdateThread.interrupt();
+		mMultiUpdateThread = null;
+	}
+	/*Stop the search/scan if there is an ongoing*/
+        if(SEARCH_TEST == mTestSelected)
+        {
+		Log.d(LOGTAG, "Stop Search\n");
+		try {
+                    mService.cancelSearch();
+                } catch (RemoteException e) {
+                     e.printStackTrace();
+                }
+        }
+
+        unbindFromService(this);
+        Log.d(LOGTAG, "onDestroy: unbindFromService completed");
+        mReceiver = null;
+        mService = null;
+        super.onDestroy();
+    }
+
+    private View.OnClickListener mOnRunListener = new View.OnClickListener() {
+       public void onClick(View v) {
+          if(false == mTestRunning)
+          {
+              clearPreviousTestResults();
+              mTestRunning = true;
+              runCurrentTest();
+          }
+          else
+          {
+              mTestRunning = false;
+              /*Set it back to ready to Run*/
+              SetButtonState(true);
+		/*Stop the thread by interrupting it*/
+	      if(mMultiUpdateThread != null) {
+	            mMultiUpdateThread.interrupt();
+		    mMultiUpdateThread = null;
+	      }
+
+              if(SEARCH_TEST == mTestSelected )
+              {
+                 try {
+                      mService.cancelSearch();
+                 } catch (RemoteException e) {
+                      e.printStackTrace();
+                 }
+              }
+          }
+       }
+    };
+
+   private void clearPreviousTestResults()
+   {
+       TableLayout tl = (TableLayout) findViewById(R.id.maintable);
+       if (tl != null) {
+          tl.removeAllViewsInLayout();
+       }
+       mNewRowIds = NEW_ROW_ID;
+   }
+
+
+    private void SetButtonState(boolean state)
+    {
+        // Get the TableRow
+        Button RunButton = (Button)findViewById(R.id.Runbutton);
+        ProgressBar  pbar = (ProgressBar) findViewById(R.id.progressbar);
+        /*Update the state of the button based on
+        state*/
+        if( state )
+        {
+            if (RunButton != null) {
+               RunButton.setText(R.string.test_run);
+            }
+            if (pbar != null) {
+               pbar.setVisibility(View.INVISIBLE);
+            }
+        }
+        else
+        {
+            if (RunButton != null) {
+               RunButton.setText("Stop Test");
+            }
+            if (pbar != null) {
+               pbar.setVisibility(View.VISIBLE);
+            }
+        }
+    }
+
+    private void chooseFMRFoption(){
+        String[] szTestInformation = getResources().getStringArray(
+                        R.array.stats_options);
+        final StringBuilder szbTestHeader = new StringBuilder();
+        szbTestHeader.append("running test:").append(szTestInformation[mTestSelected]);
+        String szTestHeader = new String(szbTestHeader);
+        switch(mTestSelected){
+            case 1:
+                RunButton = (Button)findViewById(R.id.Runbutton);
+                if (RunButton != null) {
+                   RunButton.setVisibility(View.INVISIBLE);
+                }
+                pbar = (ProgressBar) findViewById(R.id.progressbar);
+                if (pbar != null) {
+                   pbar.setVisibility(View.INVISIBLE);
+                }
+                adaptCfgRf.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+                spinOptionFmRf.setAdapter(adaptCfgRf);
+                if(isTransportLayerSMD())
+                   spinOptionFmRf.setOnItemSelectedListener(mSpinCfgRfListener2);
+                else
+                   spinOptionFmRf.setOnItemSelectedListener(mSpinCfgRfListener1);
+                break;
+            case 2:
+                txtbox1 = (EditText) findViewById(R.id.txtbox1);
+                tv1 = (TextView) findViewById(R.id.label);
+                if (txtbox1 != null) {
+                   txtbox1.setVisibility(View.INVISIBLE);
+                }
+                if (tv1 != null) {
+                   tv1.setVisibility(View.INVISIBLE);
+                }
+                Button SetButton = (Button)findViewById(R.id.Setbutton);
+                if (SetButton != null) {
+                   SetButton.setVisibility(View.INVISIBLE);
+                }
+                adaptRfCfg.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+                spinOptionFmRf.setAdapter(adaptRfCfg);
+                spinOptionFmRf.setOnItemSelectedListener(mSpinRfCfgListener);
+                break;
+        }
+    }
+
+    private View.OnClickListener mOnSetRmssitListener = new View.OnClickListener() {
+       public void onClick(View v) {
+          String a;
+          a =  txtbox1.getText().toString();
+          try {
+               int rdel = Integer.parseInt(a);
+               Log.d(LOGTAG, "Value of RMSSI DELTA is : " + rdel);
+               mReceiver.setRmssiDel(rdel);
+          } catch (NumberFormatException e) {
+               Log.e(LOGTAG, "Value entered is not in correct format: " + a);
+               txtbox1.setText("");
+          } catch (NullPointerException e) {
+               e.printStackTrace();
+          }
+       }
+    };
+
+    private View.OnClickListener mOnSetSigThListener = new View.OnClickListener() {
+       public void onClick(View v) {
+          String a;
+          a =  txtbox1.getText().toString();
+          try {
+              int rdel = Integer.parseInt(a);
+              Log.d(LOGTAG, "Value of Signal Th. is : " + rdel);
+              mReceiver.setSignalThreshold(rdel);
+          } catch (NumberFormatException e) {
+              Log.e(LOGTAG, "Value entered is not in correct format: " + a);
+              txtbox1.setText("");
+          } catch (NullPointerException e) {
+              e.printStackTrace();
+          }
+      }
+    };
+
+    private View.OnClickListener mOnSetSinrSmplCntListener  = new View.OnClickListener() {
+       public void onClick(View v) {
+          String a;
+          a =  txtbox1.getText().toString();
+          try {
+              int rdel = Integer.parseInt(a);
+              Log.d(LOGTAG, "Value of Sinr Samples count is : " + rdel);
+              if(mService != null) {
+                 try {
+                     mService.setSinrSamplesCnt(rdel);
+                 } catch (RemoteException e) {
+                     e.printStackTrace();
+                 }
+              }
+          } catch (NumberFormatException e) {
+              Log.e(LOGTAG, "Value entered is not in correct format: " + a);
+              txtbox1.setText("");
+          }
+      }
+    };
+    private View.OnClickListener mOnSetSinrThListener = new View.OnClickListener() {
+       public void onClick(View v) {
+          String a;
+          a =  txtbox1.getText().toString();
+          try {
+              int rdel = Integer.parseInt(a);
+              Log.d(LOGTAG, "Value of Sinr Th is : " + rdel);
+              if(mService != null) {
+                 try {
+                     mService.setSinrTh(rdel);
+                 } catch (RemoteException e) {
+                     e.printStackTrace();
+                 }
+              }
+          } catch (NumberFormatException e) {
+              Log.e(LOGTAG, "Value entered is not in correct format: " + a);
+              txtbox1.setText("");
+          }
+      }
+    };
+    private View.OnClickListener mOnSetIntfLowThListener = new View.OnClickListener() {
+       public void onClick(View v) {
+          String a;
+          a =  txtbox1.getText().toString();
+          try {
+              int rdel = Integer.parseInt(a);
+              Log.d(LOGTAG, "Value of Intf Det Low Th is : " + rdel);
+              if(mService != null) {
+                 try {
+                     mService.setIntfDetLowTh(rdel);
+                 } catch (RemoteException e) {
+                     e.printStackTrace();
+                 }
+              }
+          } catch (NumberFormatException e) {
+              Log.e(LOGTAG, "Value entered is not in correct format: " + a);
+              txtbox1.setText("");
+          }
+      }
+    };
+    private View.OnClickListener mOnSetIntfHighThListener = new View.OnClickListener() {
+       public void onClick(View v) {
+          String a;
+          a =  txtbox1.getText().toString();
+          try {
+              int rdel = Integer.parseInt(a);
+              Log.d(LOGTAG, "Value of Intf Det Low Th is : " + rdel);
+              if(mService != null) {
+                 try {
+                     mService.setIntfDetHighTh(rdel);
+                 } catch (RemoteException e) {
+                     e.printStackTrace();
+                 }
+              }
+          } catch (NumberFormatException e) {
+              Log.e(LOGTAG, "Value entered is not in correct format : " + a);
+              txtbox1.setText("");
+          }
+       }
+    };
+
+    public class CfgRfItemSelectedListener1 implements OnItemSelectedListener {
+        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+            Log.d("Table","onItemSelected is hit with " + pos);
+            txtbox1 = (EditText) findViewById(R.id.txtbox1);
+            tv1 = (TextView) findViewById(R.id.label);
+            Button SetButton = (Button)findViewById(R.id.Setbutton);
+            tLayout.setVisibility(View.INVISIBLE);
+            switch(pos)
+            {
+                case 0:
+                    if (txtbox1 != null) {
+                       txtbox1.setText(R.string.type_rd);
+                       txtbox1.setVisibility(View.VISIBLE);
+                    }
+                    if (tv1 != null) {
+                       tv1.setText(R.string.enter_rssi);
+                       tv1.setVisibility(View.VISIBLE);
+                    }
+                    if (SetButton != null) {
+                       SetButton.setText(R.string.set_rmmsi_delta);
+                       SetButton.setVisibility(View.VISIBLE);
+                       SetButton.setOnClickListener(mOnSetRmssitListener);
+                    }
+                    break;
+                case 1:
+                    if (txtbox1 != null) {
+                       txtbox1.setText(R.string.type_rd);
+                       txtbox1.setVisibility(View.VISIBLE);
+                    }
+                    if (tv1 != null) {
+                       tv1.setText(R.string.enter_sigth);
+                       tv1.setVisibility(View.VISIBLE);
+                    }
+                    if (SetButton != null) {
+                       SetButton.setText(R.string.set_sigth);
+                       SetButton.setVisibility(View.VISIBLE);
+                       SetButton.setOnClickListener(mOnSetSigThListener);
+                    }
+                    break;
+                case 2:
+                    tLayout.removeAllViewsInLayout();
+                    mNewRowIds = NEW_ROW_ID;
+                    tLayout.setVisibility(View.VISIBLE);
+                    if (txtbox1 != null) {
+                       txtbox1.setVisibility(View.INVISIBLE);
+                    }
+                    if (tv1 != null) {
+                       tv1.setVisibility(View.INVISIBLE);
+                    }
+                    if (SetButton != null) {
+                       SetButton.setVisibility(View.INVISIBLE);
+                    }
+                    adaptRfCfg.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+                    spinOptionFmRf.setAdapter(adaptRfCfg);
+                    spinOptionFmRf.setOnItemSelectedListener(mSpinRfCfgListener);
+                    break;
+            }
+        }
+
+        public void onNothingSelected(AdapterView<?> parent) {
+            // Do Nothing
+        }
+    }
+
+    public class CfgRfItemSelectedListener2 implements OnItemSelectedListener {
+        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+            Log.d("Table","onItemSelected is hit with " + pos);
+            txtbox1 = (EditText) findViewById(R.id.txtbox1);
+            tv1 = (TextView) findViewById(R.id.label);
+            Button SetButton = (Button)findViewById(R.id.Setbutton);
+            tLayout.setVisibility(View.INVISIBLE);
+            switch(pos)
+            {
+                case 0:
+                    if (txtbox1 != null) {
+                       txtbox1.setText(R.string.type_rd);
+                       txtbox1.setVisibility(View.VISIBLE);
+                    }
+                    if (tv1 != null) {
+                       tv1.setText(R.string.enter_SinrSmplsCnt);
+                       tv1.setVisibility(View.VISIBLE);
+                    }
+                    if (SetButton != null) {
+                       SetButton.setText(R.string.set_SinrSmplsCnt);
+                       SetButton.setVisibility(View.VISIBLE);
+                       SetButton.setOnClickListener(mOnSetSinrSmplCntListener);
+                    }
+                    break;
+                case 1:
+                    if (txtbox1 != null) {
+                       txtbox1.setText(R.string.type_rd);
+                       txtbox1.setVisibility(View.VISIBLE);
+                    }
+                    if (tv1 != null) {
+                       tv1.setText(R.string.enter_SinrTh);
+                       tv1.setVisibility(View.VISIBLE);
+                    }
+                    if (SetButton != null) {
+                       SetButton.setText(R.string.set_SinrTh);
+                       SetButton.setVisibility(View.VISIBLE);
+                       SetButton.setOnClickListener(mOnSetSinrThListener);
+                    }
+                    break;
+                case 2:
+                    if (txtbox1 != null) {
+                       txtbox1.setText(R.string.type_rd);
+                       txtbox1.setVisibility(View.VISIBLE);
+                    }
+                    if (tv1 != null) {
+                       tv1.setText(R.string.enter_IntfLowTh);
+                       tv1.setVisibility(View.VISIBLE);
+                    }
+                    if (SetButton != null) {
+                       SetButton.setText(R.string.set_IntfLowTh);
+                       SetButton.setVisibility(View.VISIBLE);
+                       SetButton.setOnClickListener(mOnSetIntfLowThListener);
+                    }
+                    break;
+                case 3:
+                    if (txtbox1 != null) {
+                       txtbox1.setText(R.string.type_rd);
+                       txtbox1.setVisibility(View.VISIBLE);
+                    }
+                    if (tv1 != null) {
+                       tv1.setText(R.string.enter_IntfHighTh);
+                       tv1.setVisibility(View.VISIBLE);
+                    }
+                    if (SetButton != null) {
+                       SetButton.setText(R.string.set_IntfHighTh);
+                       SetButton.setVisibility(View.VISIBLE);
+                       SetButton.setOnClickListener(mOnSetIntfHighThListener);
+                    }
+                    break;
+                case 4:
+                    tLayout.removeAllViewsInLayout();
+                    mNewRowIds = NEW_ROW_ID;
+                    tLayout.setVisibility(View.VISIBLE);
+                    if (txtbox1 != null) {
+                       txtbox1.setVisibility(View.INVISIBLE);
+                    }
+                    if (tv1 != null) {
+                       tv1.setVisibility(View.INVISIBLE);
+                    }
+                    if (SetButton != null) {
+                       SetButton.setVisibility(View.INVISIBLE);
+                    }
+                    adaptRfCfg.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+                    spinOptionFmRf.setAdapter(adaptRfCfg);
+                    spinOptionFmRf.setOnItemSelectedListener(mSpinRfCfgListener);
+                    break;
+            }
+        }
+        public void onNothingSelected(AdapterView<?> parent) {
+            // Do Nothing
+        }
+    }
+
+    public class RfCfgItemSelectedListener implements OnItemSelectedListener {
+        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+            Log.d("Table","onItemSelected is hit with "+pos);
+            tLayout.setVisibility(View.INVISIBLE);
+            if (mTestRunning)
+                stopCurTest();
+            switch(pos)
+            {
+                case 0:
+                case 1:
+                case 2:
+                case 3:
+                    mTestSelected = pos;
+                    tLayout.removeAllViewsInLayout();
+                    mNewRowIds = NEW_ROW_ID;
+                    tLayout.setVisibility(View.VISIBLE);
+                    RunButton = (Button)findViewById(R.id.Runbutton);
+                    if (RunButton != null) {
+                       RunButton.setText(R.string.test_run);
+                       RunButton.setVisibility(View.VISIBLE);
+                       RunButton.setOnClickListener(mOnRunListener);
+                    }
+                    break;
+                case 4:
+                    RunButton = (Button)findViewById(R.id.Runbutton);
+                    if (RunButton != null) {
+                       RunButton.setVisibility(View.INVISIBLE);
+                    }
+                    pbar = (ProgressBar) findViewById(R.id.progressbar);
+                    if (pbar != null) {
+                       pbar.setVisibility(View.INVISIBLE);
+                    }
+                    adaptCfgRf.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+                    spinOptionFmRf.setAdapter(adaptCfgRf);
+                    if(isTransportLayerSMD())
+                       spinOptionFmRf.setOnItemSelectedListener(mSpinCfgRfListener2);
+                    else
+                       spinOptionFmRf.setOnItemSelectedListener(mSpinCfgRfListener1);
+                    break;
+            }
+        }
+
+        public void onNothingSelected(AdapterView<?> parent) {
+            // Do Nothing
+        }
+    }
+    public class FmRfItemSelectedListener implements OnItemSelectedListener {
+        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+            Log.d("Table","onItemSelected is hit with "+pos);
+            mTestSelected = pos;
+            tLayout.setVisibility(View.INVISIBLE);
+            chooseFMRFoption();
+
+        }
+
+        public void onNothingSelected(AdapterView<?> parent) {
+            // Do Nothing
+        }
+    }
+    private void checkTransportLayer() {
+        String transportLayer = "";
+
+        transportLayer = SystemProperties.get("ro.qualcomm.bt.hci_transport");
+        if(transportLayer.equals("smd"))
+           mIsTransportSMD = true;
+    }
+    private boolean isTransportLayerSMD() {
+        return mIsTransportSMD;
+    }
+    private void createResult(Result aRes) {
+        // Get the TableLayout
+        TableLayout tl = (TableLayout) findViewById(R.id.maintable);
+        if (tl == null) {
+           return;
+        }
+
+         /* Create a new row to be added. */
+        mNewRowIds++;
+        TableRow tr2 = new TableRow(getApplicationContext());
+        int width = getWindowManager().getDefaultDisplay().getWidth();
+        tr2.setLayoutParams(new LayoutParams(
+                     LayoutParams.FILL_PARENT,
+                     LayoutParams.WRAP_CONTENT));
+        tr2.setId(mNewRowIds);
+        /* Create a Button to be the row-content. */
+        TextView colFreq = new TextView(getApplicationContext());
+        colFreq.setText(aRes.getFreq());
+        colFreq.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25);
+        colFreq.setWidth(width/4);
+                /* Add Button to row. */
+        tr2.addView(colFreq);
+
+        TextView colRMSSI = new TextView(getApplicationContext());
+        colRMSSI.setText(aRes.getRSSI());
+        colRMSSI.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25);
+        colRMSSI.setWidth(width/4);
+        tr2.addView(colRMSSI);
+
+        TextView colIoC = new TextView(getApplicationContext());
+        colIoC.setText(aRes.getIoC());
+        colIoC.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25);
+        colIoC.setWidth(width/4);
+        tr2.addView(colIoC);
+        if(isTransportLayerSMD())
+        {
+             TextView colSINR = new TextView(getApplicationContext());
+             colSINR.setText(aRes.getSINR());
+             colSINR.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25);
+             colSINR.setWidth(width/4);
+             tr2.addView(colSINR);
+        } else
+        {
+             TextView colMpxDcc = new TextView(getApplicationContext());
+             colMpxDcc.setText(aRes.getMpxDcc());
+             colMpxDcc.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25);
+             colMpxDcc.setWidth(width/4);
+             tr2.addView(colMpxDcc);
+        }
+          /* Add row to TableLayout. */
+          /* Add row to TableLayout. */
+        tl.addView(tr2,new TableLayout.LayoutParams(
+             LayoutParams.FILL_PARENT,
+             LayoutParams.WRAP_CONTENT));
+        if(null != mFileCursor)
+        {
+           try {
+                 StringBuilder tempStr = new StringBuilder();
+                 tempStr.append(String.format("%10s", aRes.getFreq()));
+                 tempStr.append(String.format("%10s", aRes.getRSSI()));
+                 tempStr.append(String.format("%10s", aRes.getIoC()));
+                 tempStr.append(String.format("%10s", aRes.getIntDet()));
+                 if(isTransportLayerSMD())
+                 {
+                    tempStr.append(String.format("%10s", aRes.getSINR()));
+                 } else
+                 {
+                    tempStr.append(String.format("%10s", aRes.getMpxDcc()));
+                 }
+                 tempStr.append("\r\n");
+                 String testStr = new String(tempStr);
+                 mFileCursor.write(testStr.getBytes());
+           } catch(IOException ioe) {
+                 ioe.printStackTrace();
+           }
+        }
+    }
+
+
+    private void runCurrentTest(){
+        Log.d(LOGTAG, "The test being run is" +mTestSelected);
+
+        //get test summary
+        String[] szTestInformation = getResources().getStringArray(
+                        R.array.rf_cfg);
+        final StringBuilder szbTestHeader = new StringBuilder();
+        szbTestHeader.append("running test:").append(szTestInformation[mTestSelected]);
+        szbTestHeader.append("\r\n");
+        String szTestHeader = new String(szbTestHeader);
+        if(null != mFileCursor )
+        {
+            try {
+                mFileCursor.write(szTestHeader.getBytes());
+            } catch (IOException ioe) {
+                ioe.printStackTrace();
+            }
+        }
+        switch(mTestSelected){
+            case CUR_FREQ_TEST:
+                Log.d(LOGTAG,"Current Freq test is going to run");
+                int freq = FmSharedPreferences.getTunedFrequency();
+                Result res = GetFMStatsForFreq(freq);
+                createResult(mColumnHeader);
+                if(res != null)
+                   createResult(res);
+                 mTestRunning = false;
+                break;
+            case CUR_MULTI_TEST:
+                /*Set it to ready to Stop*/
+                SetButtonState(false);
+                createResult(mColumnHeader);
+
+                if (mMultiUpdateThread == null)
+                {
+                   mMultiUpdateThread = new Thread(null, getMultipleResults,
+                                                          "MultiResultsThread");
+                }
+                /* Launch dummy thread to simulate the transfer progress */
+                Log.d(LOGTAG, "Thread State: " + mMultiUpdateThread.getState());
+                if (mMultiUpdateThread.getState() == Thread.State.TERMINATED)
+                {
+                    mMultiUpdateThread = new Thread(null, getMultipleResults,
+                                                          "MultiResultsThread");
+                }
+                /* If the thread state is "new" then the thread has not yet started */
+                if (mMultiUpdateThread.getState() == Thread.State.NEW)
+                {
+                    mMultiUpdateThread.start();
+                }
+                // returns and UI in different thread.
+                break;
+            case SEARCH_TEST:
+                try {
+                    Log.d(LOGTAG, "start scanning\n");
+                    if(isTransportLayerSMD()) {
+                         Log.d(LOGTAG,"Scanning with 0 scan time");
+                         if (mReceiver != null)
+                              mIsSearching = mReceiver.searchStations(FmReceiver.FM_RX_SRCH_MODE_SCAN,
+                                             SCAN_DWELL_PERIOD, FmReceiver.FM_RX_SEARCHDIR_UP);
+                    } else {
+                        mIsSearching = mService.scan(0);
+                    }
+                } catch (RemoteException e) {
+
+                    e.printStackTrace();
+                }
+
+                if(mIsSearching)
+                {
+                    /*Set it to Ready to Stop*/
+                    SetButtonState(false);
+                    createResult(mColumnHeader);
+                    Log.d(LOGTAG, "Created the results and cancel UI\n");
+                }
+                else
+                {
+                    mTestRunning = false;
+                }
+                break;
+            case SWEEP_TEST:
+                int Spacing = FmSharedPreferences.getChSpacing();
+                int lowerFreq = FmSharedPreferences.getLowerLimit();
+                int higherFreq = FmSharedPreferences.getUpperLimit();
+                try {
+                    Log.d(LOGTAG, "Going to set low side injection\n");
+                    mService.setHiLoInj(Lo);
+                } catch (RemoteException e) {
+
+                    e.printStackTrace();
+                }
+                /* Set it to Ready to stop*/
+                SetButtonState(false);
+                createResult(mColumnHeader);
+                getFMStatsInBand(lowerFreq,higherFreq,Spacing);
+                break;
+        }
+    }
+
+    /* Thread processing */
+    private Runnable getMultipleResults = new Runnable() {
+       public void run() {
+            /*Collect the data for the current frequency
+            20 times*/
+            int freq = FmSharedPreferences.getTunedFrequency();
+
+            for (int i = 0; i < 20; i++)
+            {
+                try
+                {
+                    Thread.sleep(500);
+                    Message updateUI = new Message();
+                    updateUI.what = STATUS_UPDATE;
+                    updateUI.obj = (Object)GetFMStatsForFreq(freq);
+                    if (updateUI.obj == null)
+                        break;
+                    mUIUpdateHandlerHandler.sendMessage(updateUI);
+		} catch (InterruptedException e)
+		{
+			/*break the loop*/
+			break;
+		}
+            }
+            mTestRunning = false;
+            Message updateStop = new Message();
+            updateStop.what = STATUS_DONE;
+            mUIUpdateHandlerHandler.sendMessage(updateStop);
+       }
+    };
+
+    private void getFMStatsInBand(int lFreq, int hFreq, int Spacing)
+    {
+        if( null == mBand) {
+            mBand = new Band();
+        }
+        mBand.lFreq = lFreq;
+        mBand.hFreq = hFreq;
+        if(Spacing == 0)
+        {
+            mBand.Spacing = 200; // 200KHz
+        }
+        else if( Spacing == 1)
+        {
+            mBand.Spacing = 100; // 100KHz
+        }
+        else
+        {
+            mBand.Spacing = 50;
+        }
+
+        if (mMultiUpdateThread == null)
+        {
+           mMultiUpdateThread = new Thread(null, getSweepResults,
+                                                  "MultiResultsThread");
+        }
+        /* Launch he dummy thread to simulate the transfer progress */
+        Log.d(LOGTAG, "Thread State: " + mMultiUpdateThread.getState());
+        if (mMultiUpdateThread.getState() == Thread.State.TERMINATED)
+        {
+            mMultiUpdateThread = new Thread(null, getSweepResults,
+                                                  "MultiResultsThread");
+        }
+        /* If the thread state is "new" then the thread has not yet started */
+        if (mMultiUpdateThread.getState() == Thread.State.NEW)
+        {
+            mMultiUpdateThread.start();
+        }
+    }
+
+    /* Thread processing */
+    private Runnable getSweepResults = new Runnable() {
+       public void run() {
+            for (int i = mBand.lFreq; (i <= mBand.hFreq) && (mService != null);
+                                                            i += mBand.Spacing)
+            {
+                 try {
+                      if (!mService.tune(i)) {
+                          Log.e(LOGTAG, "tune failed");
+                          break;
+                      }
+                      mSync = new Band();
+                      synchronized(mSync) {
+                         mSync.wait(); //wait till notified
+                      }
+                      mSync = null;
+                      Message updateUI = new Message();
+                      updateUI.what = STATUS_UPDATE;
+                      updateUI.obj = (Object)GetFMStatsForFreq(i);
+                      if (updateUI.obj == null) {
+                          break;
+                      } else {
+                          mUIUpdateHandlerHandler.sendMessage(updateUI);
+                          Log.d(LOGTAG,"highFerq is "+mBand.hFreq);
+                      }
+                 }
+                 catch (RemoteException e) {
+		      Log.e(LOGTAG, "SweepResults:Tune failed\n");
+		 }
+
+                catch (InterruptedException e) {
+			/*Stop the thrad*/
+		       break;
+                }
+            }
+            mTestRunning = false;
+            Message updateStop = new Message();
+            updateStop.what = STATUS_DONE;
+            try {
+                 Log.d(LOGTAG, "Going to set auto hi-lo injection\n");
+                 mService.setHiLoInj(Auto);
+            } catch (RemoteException e) {
+                 e.printStackTrace();
+            }
+            mUIUpdateHandlerHandler.sendMessage(updateStop);
+       }
+    };
+
+    private Result GetFMStatsForFreq(int freq)
+    {
+        Result result = new Result();
+        Log.d(LOGTAG,"freq is "+freq);
+        result.setFreq(Integer.toString(freq));
+        byte nRssi = 0;
+        int nIoC = 0;
+        int dummy = 0;
+        int nIntDet = 0;
+        int nMpxDcc = 0;
+        byte nSINR = 0;
+        if((null != mService)) {
+           try {
+               dummy = mService.getRssi();
+               if (dummy != Integer.MAX_VALUE) {
+                   nRssi = (byte)dummy;
+                   result.setRSSI(Byte.toString(nRssi));
+               } else {
+                   return null;
+               }
+           } catch (RemoteException e) {
+               e.printStackTrace();
+           }
+
+           try {
+               nIoC = mService.getIoC();
+               if (nIoC != Integer.MAX_VALUE)
+                   result.setIoC(Integer.toString(nIoC));
+               else
+                   return null;
+           } catch (RemoteException e) {
+               e.printStackTrace();
+           }
+
+           if(isTransportLayerSMD()) {
+              try {
+                  dummy = mService.getSINR();
+                  if (dummy != Integer.MAX_VALUE) {
+                      nSINR = (byte)dummy;
+                      result.setSINR(Integer.toString(nSINR));
+                  } else {
+                      return null;
+                  }
+              } catch (RemoteException e) {
+                  e.printStackTrace();
+              }
+           } else {
+              try {
+                  nMpxDcc = mService.getMpxDcc();
+                  if (nMpxDcc != Integer.MAX_VALUE)
+                      result.setMpxDcc(Integer.toString(nMpxDcc));
+                  else
+                      return null;
+              } catch (RemoteException e) {
+                  e.printStackTrace();
+              }
+           }
+
+           try {
+               nIntDet = mService.getIntDet();
+               if (nIntDet != Integer.MAX_VALUE)
+                   result.setIntDet(Integer.toString(nIntDet));
+               else
+                   return null;
+           } catch (RemoteException e) {
+               e.printStackTrace();
+           }
+        } else {
+           return null;
+        }
+        return result;
+   }
+
+
+    private Handler mUIUpdateHandlerHandler = new Handler() {
+            public void handleMessage(Message msg) {
+               switch (msg.what)
+               {
+               case STATUS_UPDATE:
+                    Result myRes = (Result) msg.obj;
+                    Log.d(LOGTAG,"Status update is" +myRes.mFreq);
+                    createResult(myRes);
+                    break;
+               case STATUS_DONE:
+                    SetButtonState(true);
+                    break;
+               }
+            }
+    };
+
+    public static IFMRadioService sService = null;
+    private static HashMap<Context, ServiceBinder> sConnectionMap = new HashMap<Context, ServiceBinder>();
+
+    public static boolean bindToService(Context context) {
+       Log.e(LOGTAG, "bindToService: Context");
+       return bindToService(context, null);
+    }
+
+    public static boolean bindToService(Context context, ServiceConnection callback) {
+       Log.e(LOGTAG, "bindToService: Context with serviceconnection callback");
+       context.startService(new Intent(context, FMRadioService.class));
+       ServiceBinder sb = new ServiceBinder(callback);
+       sConnectionMap.put(context, sb);
+       return context.bindService((new Intent()).setClass(context,
+                                                          FMRadioService.class), sb, 0);
+    }
+
+    public static 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 static class ServiceBinder implements ServiceConnection
+    {
+       ServiceConnection mCallback;
+       ServiceBinder(ServiceConnection callback) {
+          mCallback = callback;
+       }
+
+       public void onServiceConnected(ComponentName className, android.os.IBinder service) {
+          sService = IFMRadioService.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 = IFMRadioService.Stub.asInterface(obj);
+             Log.e(LOGTAG, "ServiceConnection: onServiceConnected: ");
+             if (mService != null)
+             {
+                try
+                {
+                   mService.registerCallbacks(mServiceCallbacks);
+
+                } catch (RemoteException e)
+                {
+                   e.printStackTrace();
+                }
+                return;
+             } else
+             {
+                Log.e(LOGTAG, "IFMRadioService onServiceConnected failed");
+             }
+             finish();
+          }
+          public void onServiceDisconnected(ComponentName classname) {
+          }
+       };
+
+
+       private IFMRadioServiceCallbacks.Stub  mServiceCallbacks = new IFMRadioServiceCallbacks.Stub()
+       {
+          public void onEnabled()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onEnabled :");
+          }
+
+          public void onDisabled()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onDisabled :");
+             stopCurTest();
+          }
+
+          public void onRadioReset()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onRadioReset :");
+          }
+
+          public void onTuneStatusChanged()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onTuneStatusChanged :");
+             if (mTestRunning)
+                 mHandler.post(mTuneComplete);
+          }
+
+          public void onProgramServiceChanged()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onProgramServiceChanged :");
+          }
+
+          public void onRadioTextChanged()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onRadioTextChanged :");
+          }
+          public void onExtenRadioTextChanged()
+          {
+             Log.d(LOGTAG, "Extended Radio Text changed:");
+          }
+          public void onAlternateFrequencyChanged()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onAlternateFrequencyChanged :");
+          }
+
+          public void onSignalStrengthChanged()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onSignalStrengthChanged :");
+          }
+
+          public void onSearchComplete()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onSearchComplete :");
+             /*Stop the update*/
+             mTestRunning = false;
+             Message updateStop = new Message();
+             updateStop.what = STATUS_DONE;
+             mUIUpdateHandlerHandler.sendMessage(updateStop);
+          }
+          public void onSearchListComplete()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onSearchListComplete :");
+
+          }
+
+          public void onMute(boolean bMuted)
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onMute :" + bMuted);
+          }
+
+          public void onAudioUpdate(boolean bStereo)
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onAudioUpdate :" + bStereo);
+          }
+
+          public void onStationRDSSupported(boolean bRDSSupported)
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onStationRDSSupported :" + bRDSSupported);
+          }
+          public void onRecordingStopped()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onDisabled :");
+          }
+          public void onFinishActivity()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onFinishActivity:");
+          }
+      };
+      /* Radio Vars */
+     final Handler mHandler = new Handler();
+
+     final Runnable mTuneComplete = new Runnable(){
+         public void run(){
+             if((null != mMultiUpdateThread) &&(null != mSync))
+             {
+                 synchronized(mSync){
+                     mSync.notify();
+                 }
+             }
+            if((mTestSelected == SEARCH_TEST) && (mService != null)) {
+                /* On every Tune Complete generate the result for the current
+                Frequency*/
+                Message updateUI = new Message();
+                updateUI.what = STATUS_UPDATE;
+                int freq = FmSharedPreferences.getTunedFrequency();
+                updateUI.obj = (Object)GetFMStatsForFreq(freq);
+                if (updateUI.obj == null)
+                    updateUI.what = STATUS_DONE;
+                mUIUpdateHandlerHandler.sendMessage(updateUI);
+            }
+         }
+     };
+
+     private void stopCurTest() {
+         if (mTestRunning) {
+             switch(mTestSelected) {
+             case CUR_FREQ_TEST:
+                  break;
+             case SWEEP_TEST:
+             case CUR_MULTI_TEST:
+                  if (mMultiUpdateThread != null)
+                      mMultiUpdateThread.interrupt();
+                  break;
+             case SEARCH_TEST:
+                  mHandler.removeCallbacks(mTuneComplete);
+                  if (mService != null) {
+                      try {
+                           Message updateStop = new Message();
+                           updateStop.what = STATUS_DONE;
+                           mUIUpdateHandlerHandler.sendMessage(updateStop);
+                           mService.cancelSearch();
+                      } catch (RemoteException e) {
+                           e.printStackTrace();
+                      }
+                  }
+                  break;
+             }
+             mTestRunning = false;
+         }
+     }
+ }
diff --git a/fmapp2/src/com/caf/fmradio/FMTransmitterActivity.java b/fmapp2/src/com/caf/fmradio/FMTransmitterActivity.java
new file mode 100644
index 0000000..e83f61f
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/FMTransmitterActivity.java
@@ -0,0 +1,1563 @@
+/*
+ * 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.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 static IFMTransmitterService mService = null;
+   private static 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 */
+   final Handler mHandler = new Handler();
+   private final Handler enableRadioHandler = new Handler();
+   private final 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;
+
+   /** 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);
+       //HDMI and FM concurrecny is not supported.
+       if(isHdmiOn()) {
+          showDialog(DIALOG_CMD_FAILED_HDMI_ON);
+       }else {
+          if(false == bindToService(this, osc)) {
+             Log.d(LOGTAG, "onCreate: Failed to Start Service");
+          }else {
+             Log.d(LOGTAG, "onCreate: Start Service completed successfully");
+          }
+       }
+   }
+
+   @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();
+      LoadPreferences();
+      if(mPicker != null) {
+         setDisplayvalue();
+      }
+      mUpdatePickerValue = true;
+      mHandler.post(mUpdateRadioText);
+      updateStationInfoToUI();
+      enableRadioOnOffUI();
+   }
+
+   @Override
+   public void onDestroy() {
+      unbindFromService(this);
+      mService = null;
+      Log.d(LOGTAG, "onDestroy: unbindFromService completed");
+      super.onDestroy();
+   }
+
+   private class LoadedDataAndState {
+      public LoadedDataAndState(){};
+      public boolean onOrOff;
+   }
+
+   @Override
+   public Object onRetainNonConfigurationInstance() {
+      final 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);
+   }
+
+   private boolean isHdmiOn() {
+      //HDMI and FM concurrecny is not supported.
+      try {
+           String hdmiUserOption = android.provider.Settings.System.getString(
+                                            getContentResolver(), "HDMI_USEROPTION");
+      }catch(Exception ex){
+           Log.d(LOGTAG,"Get HDMI open failed");
+      }
+      return false;
+   }
+
+   @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;
+      }
+   };
+
+   final 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 static 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();
+         }
+      }else {
+         if(mTuneStationFrequencyTV != null) {
+            mTuneStationFrequencyTV.setOnLongClickListener(null);
+         }
+         if(mRadioTextScroller != null) {
+            mRadioTextScroller.stopScroll();
+         }
+      }
+
+      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 static 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();
+  }
+
+
+  final Runnable mUpdateStationInfo = new Runnable() {
+     public void run() {
+        updateSearchProgress();
+        resetFMStationInfoUI();
+     }
+  };
+
+  final 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();
+        }
+     }
+   }
+  };
+
+
+
+  final 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();
+            }
+        }
+     }
+  };
+
+  final 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 static 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();
+              mStringlength = mOriginalString.length();
+              if(mStringlength > 0) {
+                 mStatus = SCROLLER_STARTING;
+                 sendEmptyMessageDelayed(SCROLLER_MSG_START,
+                                           SCROLLER_START_DELAY_MS);
+              }
+           }
+     }
+  }
+
+  public static IFMTransmitterService sService = null;
+  private static HashMap<Context, ServiceBinder> sConnectionMap = new HashMap<Context, ServiceBinder>();
+
+  public static boolean bindToService(Context context) {
+     Log.e(LOGTAG, "bindToService: Context");
+     return bindToService(context, null);
+  }
+
+  public static 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 static 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 static 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);
+     }
+  };
+
+  final 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);
+         }
+
+     }
+  };
+
+  final Runnable mRadioReset = new Runnable() {
+     public void run() {
+        /* Save the existing frequency */
+        resetSearchProgress();
+        FmSharedPreferences.setTunedFrequency(mTunedFrequency);
+        SavePreferences();
+        enableRadioOnOffUI(false);
+     }
+  };
+}
diff --git a/fmapp2/src/com/caf/fmradio/FMTransmitterConfigReceiver.java b/fmapp2/src/com/caf/fmradio/FMTransmitterConfigReceiver.java
new file mode 100644
index 0000000..4f15188
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/FMTransmitterConfigReceiver.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011-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.content.Intent;
+import android.content.BroadcastReceiver;
+import android.content.pm.PackageManager;
+import android.content.Context;
+import android.content.ComponentName;
+import android.util.Log;
+import android.os.SystemProperties;
+import java.io.FileReader;
+import java.lang.String;
+
+
+public class FMTransmitterConfigReceiver extends BroadcastReceiver {
+
+    private static FileReader socinfo_fd;
+    private static char[] socinfo = new char[20];
+    private static String build_id = "1";
+
+    private static final String TAG = "FMFolderConfigReceiver";
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        Log.d(TAG, "Received intent: " + action);
+        if((action != null) && action.equals("android.intent.action.BOOT_COMPLETED")) {
+            Log.d(TAG, "boot complete intent received");
+            boolean isFmTransmitterSupported = SystemProperties.getBoolean("ro.fm.transmitter",true);
+
+            if ("msm7630_surf".equals(SystemProperties.get("ro.board.platform"))) {
+                Log.d(TAG,"this is msm7630_surf");
+                try {
+                    socinfo_fd = new FileReader("/sys/devices/system/soc/soc0/build_id");
+                    socinfo_fd.read(socinfo,0,20);
+                    socinfo_fd.close();
+                } catch(Exception e) {
+                    Log.e(TAG,"Exception in FileReader");
+                }
+                Log.d(TAG, "socinfo=" +socinfo);
+                build_id = new String(socinfo,17,1);
+                Log.d(TAG, "build_id=" +build_id);
+            }
+            if ((!isFmTransmitterSupported) || (build_id.equals("0"))) {
+            PackageManager pManager = context.getPackageManager();
+               if (pManager != null) {
+                   Log.d(TAG, "disableing the FM Transmitter");
+                   ComponentName fmTransmitter = new ComponentName("com.caf.fmradio", "com.caf.fmradio.FMTransmitterActivity");
+                   pManager.setComponentEnabledSetting(fmTransmitter, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                                                    PackageManager.DONT_KILL_APP);
+               }
+           }
+        }
+   }
+}
diff --git a/fmapp2/src/com/caf/fmradio/FMTransmitterService.java b/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
new file mode 100644
index 0000000..a720868
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
@@ -0,0 +1,1221 @@
+/*
+ * 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 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();
+         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();
+         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();
+           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);
+           } else {
+               try {
+                   Thread.sleep(100);
+               } catch (Exception ex) {
+                   Log.d( LOGTAG,  "RunningThread InterruptedException");
+               }
+               bStatus = mReceiver.enable(config);
+           }
+           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();
+         }
+      }
+   };
+
+
+   /*
+    *  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) {
+        }
+   }
+
+   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/FmSharedPreferences.java b/fmapp2/src/com/caf/fmradio/FmSharedPreferences.java
new file mode 100644
index 0000000..db215e8
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/FmSharedPreferences.java
@@ -0,0 +1,1114 @@
+/*
+ * 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 java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import qcom.fmradio.FmReceiver;
+import qcom.fmradio.FmConfig;
+import android.util.Log;
+
+public class FmSharedPreferences
+{
+   public static final int REGIONAL_BAND_NORTH_AMERICA   = 0;
+   public static final int REGIONAL_BAND_EUROPE          = 1;
+   public static final int REGIONAL_BAND_JAPAN           = 2;
+   public static final int REGIONAL_BAND_JAPAN_WIDE      = 3;
+   public static final int REGIONAL_BAND_AUSTRALIA       = 4;
+   public static final int REGIONAL_BAND_AUSTRIA         = 5;
+   public static final int REGIONAL_BAND_BELGIUM         = 6;
+   public static final int REGIONAL_BAND_BRAZIL          = 7;
+   public static final int REGIONAL_BAND_CHINA           = 8;
+   public static final int REGIONAL_BAND_CZECH           = 9;
+   public static final int REGIONAL_BAND_DENMARK         = 10;
+   public static final int REGIONAL_BAND_FINLAND         = 11;
+   public static final int REGIONAL_BAND_FRANCE          = 12;
+   public static final int REGIONAL_BAND_GERMANY         = 13;
+   public static final int REGIONAL_BAND_GREECE          = 14;
+   public static final int REGIONAL_BAND_HONGKONG        = 15;
+   public static final int REGIONAL_BAND_INDIA           = 16;
+   public static final int REGIONAL_BAND_IRELAND         = 17;
+   public static final int REGIONAL_BAND_ITALY           = 18;
+   public static final int REGIONAL_BAND_KOREA           = 19;
+   public static final int REGIONAL_BAND_MEXICO          = 20;
+   public static final int REGIONAL_BAND_NETHERLANDS     = 21;
+   public static final int REGIONAL_BAND_NEWZEALAND      = 22;
+   public static final int REGIONAL_BAND_NORWAY          = 23;
+   public static final int REGIONAL_BAND_POLAND          = 24;
+   public static final int REGIONAL_BAND_PORTUGAL        = 25;
+   public static final int REGIONAL_BAND_RUSSIA          = 26;
+   public static final int REGIONAL_BAND_SINGAPORE       = 27;
+   public static final int REGIONAL_BAND_SLOVAKIA        = 28;
+   public static final int REGIONAL_BAND_SPAIN           = 29;
+   public static final int REGIONAL_BAND_SWITZERLAND     = 30;
+   public static final int REGIONAL_BAND_SWEDEN          = 31;
+   public static final int REGIONAL_BAND_TAIWAN          = 32;
+   public static final int REGIONAL_BAND_TURKEY          = 33;
+   public static final int REGIONAL_BAND_UNITEDKINGDOM   = 34;
+   public static final int REGIONAL_BAND_UNITED_STATES   = 35;
+
+   public static final int RECORD_DUR_INDEX_0_VAL        = 5;
+   public static final int RECORD_DUR_INDEX_1_VAL       = 15;
+   public static final int RECORD_DUR_INDEX_2_VAL       = 30;
+   public static final int RECORD_DUR_INDEX_3_VAL       = -1;
+
+   private static final String LOGTAG = "FmSharedPreferences";
+
+   private static final String SHARED_PREFS = "fmradio_prefs";
+   private static final String LIST_NUM = "list_number";
+   private static final String LIST_NAME = "list_name";
+   private static final String STATION_NAME = "station_name";
+   private static final String STATION_FREQUENCY = "station_freq";
+   private static final String STATION_ID = "station_id";
+   private static final String STATION_PTY = "station_pty";
+   private static final String STATION_RDS = "station_rds";
+   private static final String STATION_NUM = "preset_number";
+
+   private static final String FMCONFIG_COUNTRY = "fmconfig_country";
+   //private static final String FMCONFIG_BAND = "fmconfig_band";
+   //private static final String FMCONFIG_MIN = "fmconfig_min";
+   //private static final String FMCONFIG_MAX = "fmconfig_max";
+   //private static final String FMCONFIG_STEP = "fmconfig_step";
+   //private static final String FMCONFIG_EMPH = "fmconfig_emphasis";
+   //private static final String FMCONFIG_RDSSTD = "fmconfig_rdsstd";
+   /* Storage key String */
+   private static final String LAST_LIST_INDEX = "last_list_index";
+   public static final int MAX_NUM_TAG_TYPES = 64;
+   public static final int NUM_TAG_CATEGORY = 8;
+   public static final String []TAG_CATEGORIES = { "DUMMY", "ITEM", "INFO", "PROGRAMME",
+                                                      "INTERACTIVITY", "RFU", "PRIVATE_CLASSES",
+                                                      "DESCRIPTOR" };
+   public static final int [][]TAG_CATEGORY_RANGE  = { {0, 0}, {1, 11}, {12, 30},
+                                                         {31, 40}, {41, 53}, {54, 55},
+                                                         {56, 58}, {59, 63} };
+   public static final String []TAG_NAMES = { "DUMMY", "ITEM.TITLE", "ITEM.ALBUM", "ITEM.TRACKNUM",
+                                                  "ITEM.ARTIST", "ITEM.COMPOSITION", "ITEM.MOVEMENT",
+                                                  "ITEM.CONDUCTOR", "ITEM.COMPOSER", "ITEM.BAND", "ITEM.COMMENT",
+                                                  "ITEM.GENERE", "INFO.NEWS", "INFO.NEWS_LOCAL", "INFO.STOCK",
+                                                  "INFO.SPORT", "INFO.LOTTERY", "INFO.HOROSCOPE",
+                                                  "INFO.DAILY_DIVERSION", "INFO.HEALTH", "INFO.EVENT",
+                                                  "INFO.SCENE", "INFO.CINEMA", "INFO.TV", "INFO.DATE_TIME",
+                                                  "INFO.WEATHER", "INFO.TRAFFIC", "INFO.ALARM", "INFO.ADS",
+                                                  "INFO.URL", "INFO.OTHER", "PROGRAMME.STATIONNAME_SHORT",
+                                                  "PROGRAMME.NOW", "PROGRAMME.NEXT", "PROGRAMME.PART",
+                                                  "PROGRAMME.HOST", "PROGRAMME.EDITORIAL_STAFF",
+                                                  "PROGRAMME.FREQUENCY", "PROGRAMME.HOMEPAGE",
+                                                  "PROGRAMME.SUBCHANNEL", "PHONE.HOTLINE", "PHONE.STUDIO",
+                                                  "PHONE.OTHER", "SMS.STUDIO", "SMS.OTHER", "EMAIL.HOTLINE",
+                                                  "EMAIL.STUDIO", "EMAIL.OTHER", "MMS.OTHER", "CHAT",
+                                                  "CHAT.CENTRE", "VOTE.QUESTION", "VOTE.CENTRE", "RFU.1",
+                                                  "RFU.2", "PRIVATE.1", "PRIVATE.2", "PRIVATE.3",
+                                                  "PLACE", "APPOINTMENT", "IDENTIFIER", "PURCHASE", "GET_DATA" };
+
+   private static final String PREF_LAST_TUNED_FREQUENCY = "last_frequency";
+   private static final String LAST_RECORD_DURATION = "last_record_duration";
+   private static String  LAST_AF_JUMP_VALUE = "last_af_jump_value";
+   private static final String AUDIO_OUTPUT_MODE = "audio_output_mode";
+
+   private static Map<String, String> mNameMap = new HashMap<String, String>();
+   private static List<PresetList> mListOfPlists = new ArrayList<PresetList>();
+   public static Set[] tagList = new TreeSet[FmSharedPreferences.MAX_NUM_TAG_TYPES];
+   public static int num_tags = 0;
+   private static FmConfig mFMConfiguration;
+
+   private static final String DEFAULT_NO_NAME = "";
+   public static final int DEFAULT_NO_FREQUENCY = 98100;
+   private static final int DEFAULT_NO_PTY = 0;
+   private static final int DEFAULT_NO_STATIONID = 0;
+   private static final int DEFAULT_NO_RDSSUP = 0;
+   private static CharSequence[] mListEntries;
+   private static CharSequence[] mListValues;
+   private static int mListIndex;
+   private Context mContext;
+   private static int mTunedFrequency = 98100;
+   private static int mFrequencyBand_Stepsize = 200;
+
+   private static int mCountry = 0;
+   /* true = Stereo and false = "force Mono" even if Station is transmitting a
+    * Stereo signal
+    */
+   private static boolean mAudioOutputMode = true;
+   private static boolean mAFAutoSwitch = true;
+   private static int mRecordDuration = 0;
+
+   FmSharedPreferences(Context context){
+      mContext = context.getApplicationContext();
+      mFMConfiguration = new FmConfig();
+      Load();
+   }
+
+   public static void removeStation(int listIndex, int stationIndex){
+      if (listIndex < getNumList())
+      {
+         mListOfPlists.get(listIndex).removeStation(stationIndex);
+      }
+   }
+   public static void removeStation(int listIndex, PresetStation station){
+      if (listIndex < getNumList())
+      {
+         mListOfPlists.get(listIndex).removeStation(station);
+      }
+   }
+
+   public static void setListName(int listIndex, String name){
+      if (listIndex < getNumList())
+      {
+         mListOfPlists.get(listIndex).setName(name);
+      }
+   }
+
+   public static void setStationName(int listIndex, int stationIndex, String name){
+      if (listIndex < getNumList())
+      {
+         mListOfPlists.get(listIndex).setStationName(stationIndex, name);
+      }
+   }
+
+   public static String getListName(int listIndex){
+      String name = "";
+      addListIfEmpty(listIndex);
+      if (listIndex < getNumList())
+      {
+         name= mListOfPlists.get(listIndex).getName();
+      }
+      return name;
+   }
+
+   public static String getStationName(int listIndex, int stationIndex){
+      String name = "";
+      if (listIndex < getNumList())
+      {
+         name = mListOfPlists.get(listIndex).getStationName(stationIndex);
+      }
+      return name;
+   }
+
+   public static double getStationFrequency(int listIndex, int stationIndex){
+      double frequency = 0;
+      if (listIndex < getNumList())
+      {
+         frequency =  mListOfPlists.get(listIndex).getStationFrequency(stationIndex);
+      }
+      return frequency;
+   }
+
+   public static PresetList getStationList(int listIndex){
+      if (listIndex < getNumList())
+      {
+         return mListOfPlists.get(listIndex);
+      }
+      return null;
+   }
+
+   public static PresetStation getselectedStation(){
+      int listIndex = getCurrentListIndex();
+      PresetStation station = null;
+      if (listIndex < getNumList())
+      {
+         station = mListOfPlists.get(listIndex).getSelectedStation();
+      }
+      return station;
+   }
+
+   public static PresetStation getStationInList(int index){
+      int listIndex = getCurrentListIndex();
+      PresetStation station = null;
+      if (listIndex < getNumList())
+      {
+         station = mListOfPlists.get(listIndex).getStationFromIndex(index);
+      }
+      return station;
+   }
+   public static PresetStation getStationFromFrequency(int frequency){
+      int listIndex = getCurrentListIndex();
+      PresetStation station = null;
+      if(listIndex < getNumList())
+      {
+         station = mListOfPlists.get(listIndex).getStationFromFrequency(frequency);
+      }
+      return station;
+   }
+
+   public static PresetStation selectNextStation(){
+      int listIndex = getCurrentListIndex();
+      PresetStation station = null;
+      if (listIndex < getNumList())
+      {
+         station = mListOfPlists.get(listIndex).selectNextStation();
+      }
+      return station;
+   }
+
+   public static PresetStation selectPrevStation(){
+      int listIndex = getCurrentListIndex();
+      PresetStation station = null;
+      if (listIndex < getNumList())
+      {
+         station = mListOfPlists.get(listIndex).selectPrevStation();
+      }
+      return station;
+   }
+
+   public static void selectStation(PresetStation station){
+      int listIndex = getCurrentListIndex();
+      if (listIndex < getNumList())
+      {
+         mListOfPlists.get(listIndex).selectStation(station);
+      }
+   }
+
+   public static int getNumList(){
+      return mListOfPlists.size();
+   }
+
+   public static int getCurrentListIndex(){
+      return mListIndex;
+   }
+
+   public static void setListIndex(int index){
+      mListIndex = index;
+   }
+
+   public static Map<String, String> getNameMap(){
+      return mNameMap;
+   }
+
+   private static void addListIfEmpty(int listIndex){
+      if ((listIndex < 1) && (getNumList() == 0))
+      {
+         createPresetList("FM");
+      }
+   }
+
+   public static void addStation(String name, int freq, int listIndex){
+      /* If no lists exists and a new station is added, add a new Preset List
+       * if "listIndex" requested was "0"
+       */
+      addListIfEmpty(listIndex);
+      if (getNumList() > listIndex)
+      {
+         mListOfPlists.get(listIndex).addStation(name, freq);
+      }
+   }
+
+   /** Add "station" into the Preset List indexed by "listIndex" */
+   public static void addStation(int listIndex, PresetStation station){
+      /* If no lists exists and a new station is added, add a new Preset List
+       * if "listIndex" requested was "0"
+       */
+      addListIfEmpty(listIndex);
+      if (getNumList() > listIndex)
+      {
+         mListOfPlists.get(listIndex).addStation(station);
+      }
+   }
+   public static void addTags(int index, String s) {
+     if ((index >= 0) && (index <FmSharedPreferences.MAX_NUM_TAG_TYPES)) {
+          if(tagList[index] == null) {
+             tagList[index] = new TreeSet<String>();
+          }
+          if (tagList[index].add(s))
+              num_tags++;
+     }
+   }
+   public static void clearTags() {
+      for(int i = 0; i <FmSharedPreferences.MAX_NUM_TAG_TYPES; i++) {
+          if(tagList[i] != null) {
+             tagList[i].clear();
+             Log.d(LOGTAG, "cleared tags of type" + i);
+          }
+      }
+      num_tags = 0;
+   }
+
+   /** Does "station" already exist in the Preset List indexed by "listIndex" */
+   public static boolean sameStationExists(int listIndex, PresetStation station){
+      boolean exists = false;
+      if (getNumList() > listIndex)
+      {
+         exists = mListOfPlists.get(listIndex).sameStationExists(station);
+      }
+      return exists;
+   }
+
+   /** Does "station" already exist in the current Preset List*/
+   public static boolean sameStationExists( PresetStation station){
+      int listIndex = getCurrentListIndex();
+      boolean exists = false;
+      if (getNumList() > listIndex)
+      {
+         exists = mListOfPlists.get(listIndex).sameStationExists(station);
+      }
+      return exists;
+   }
+
+   /** Does "station" already exist in the current Preset List*/
+   public static int getListStationCount( ){
+      int listIndex = getCurrentListIndex();
+      int numStations = 0;
+      if (getNumList() > listIndex)
+      {
+         numStations = mListOfPlists.get(listIndex).getStationCount();
+      }
+      return numStations;
+   }
+
+   public static void renamePresetList(String newName, int listIndex){
+      PresetList curList =    mListOfPlists.get(listIndex);
+      if (curList != null)
+      {
+         String oldListName = curList.getName();
+         curList.setName(newName);
+         String index = mNameMap.get(oldListName);
+         mNameMap.remove(oldListName);
+         mNameMap.put((String) newName, index);
+         repopulateEntryValueLists();
+      }
+   }
+
+   /* Returns the index of the list just created */
+   public static int createPresetList(String name) {
+      int numLists = mListOfPlists.size();
+      mListOfPlists.add(new PresetList(name));
+      String index = String.valueOf(numLists);
+      mNameMap.put(name, index);
+      repopulateEntryValueLists();
+      return numLists;
+   }
+
+
+   public static void createFirstPresetList(String name) {
+      mListIndex = 0;
+      createPresetList(name);
+   }
+
+   public static CharSequence[] repopulateEntryValueLists() {
+      ListIterator<PresetList> presetIter;
+      presetIter = mListOfPlists.listIterator();
+      int numLists = mListOfPlists.size();
+
+      mListEntries = new CharSequence[numLists];
+      mListValues = new CharSequence[numLists];
+      for (int i = 0; i < numLists; i++)
+      {
+         PresetList temp = presetIter.next();
+         mListEntries[i] = temp.getName();
+         mListValues[i] = temp.getName();
+      }
+      return mListEntries;
+   }
+
+   public static List<PresetList> getPresetLists() {
+      return mListOfPlists;
+   }
+
+
+   public void  Load(){
+      Log.d(LOGTAG, "Load preferences ");
+      if(mContext == null)
+      {
+         return;
+      }
+      SharedPreferences sp = mContext.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE);
+      mTunedFrequency = sp.getInt(PREF_LAST_TUNED_FREQUENCY, DEFAULT_NO_FREQUENCY);
+      mRecordDuration = sp.getInt(LAST_RECORD_DURATION, RECORD_DUR_INDEX_0_VAL);
+      mAFAutoSwitch = sp.getBoolean(LAST_AF_JUMP_VALUE, true);
+      mAudioOutputMode = sp.getBoolean(AUDIO_OUTPUT_MODE, true);
+     /* Reset the Lists before reading the preferences */
+      mListOfPlists.clear();
+
+      int num_lists = sp.getInt(LIST_NUM, 1);
+      if (mListOfPlists.size() == 0) {
+
+         for (int listIter = 0; listIter < num_lists; listIter++) {
+             String listName = sp.getString(LIST_NAME + listIter, "FM - " + (listIter+1));
+             int numStations = sp.getInt(STATION_NUM + listIter, 1);
+             if (listIter == 0) {
+                 createFirstPresetList(listName);
+             } else {
+                 createPresetList(listName);
+             }
+
+             PresetList curList = mListOfPlists.get(listIter);
+             for (int stationIter = 0; stationIter < numStations; stationIter++) {
+                  String stationName = sp.getString(STATION_NAME + listIter + "x" + stationIter,
+                                                      DEFAULT_NO_NAME);
+                  int stationFreq = sp.getInt(STATION_FREQUENCY + listIter + "x" + stationIter,
+                                                   DEFAULT_NO_FREQUENCY);
+                  PresetStation station = curList.addStation(stationName, stationFreq);
+
+                  int stationId = sp.getInt(STATION_ID + listIter + "x" + stationIter,
+                                              DEFAULT_NO_STATIONID);
+                  station.setPI(stationId);
+
+                  int pty = sp.getInt(STATION_PTY + listIter + "x" + stationIter, DEFAULT_NO_PTY);
+                  station.setPty(pty);
+
+                  int rdsSupported = sp.getInt(STATION_RDS + listIter + "x" + stationIter,
+                                                 DEFAULT_NO_RDSSUP);
+                  if (rdsSupported != 0) {
+                      station.setRDSSupported(true);
+                  } else {
+                      station.setRDSSupported(false);
+                  }
+             }
+         }
+      }
+      /* Load Configuration */
+      setCountry(sp.getInt(FMCONFIG_COUNTRY, 0));
+      /* Last list the user was navigating */
+      mListIndex = sp.getInt(LAST_LIST_INDEX, 0);
+      if(mListIndex >= num_lists)
+      {
+         mListIndex=0;
+      }
+   }
+
+   public void Save() {
+      if(mContext == null)
+      {
+         return;
+      }
+      Log.d(LOGTAG, "Save preferences ");
+
+      int numLists = mListOfPlists.size();
+      SharedPreferences sp = mContext.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE);
+      SharedPreferences.Editor ed = sp.edit();
+
+      ed.putInt(PREF_LAST_TUNED_FREQUENCY, mTunedFrequency);
+
+      ed.putInt(LIST_NUM, numLists);
+      /* Last list the user was navigating */
+      ed.putInt(LAST_LIST_INDEX, mListIndex);
+
+      for (int listIter = 0; listIter < numLists; listIter++)
+      {
+         PresetList curList = mListOfPlists.get(listIter);
+         ed.putString(LIST_NAME + listIter, curList.getName());
+         int numStations = curList.getStationCount();
+         ed.putInt(STATION_NUM + listIter, numStations);
+         int numStation = 0;
+         for (int stationIter = 0; stationIter < numStations; stationIter++)
+         {
+            PresetStation station = curList.getStationFromIndex(stationIter);
+            if (station != null)
+            {
+               ed.putString(STATION_NAME + listIter + "x" + numStation,
+                            station.getName());
+               ed.putInt(STATION_FREQUENCY + listIter + "x" + numStation,
+                         station.getFrequency());
+               ed.putInt(STATION_ID + listIter + "x" + numStation,
+                         station.getPI());
+               ed.putInt(STATION_PTY + listIter + "x" + numStation,
+                         station.getPty());
+               ed.putInt(STATION_RDS + listIter + "x" + numStation,
+                         (station.getRDSSupported() == true? 1:0));
+               numStation ++;
+            }
+         }
+      }
+
+      /* Save Configuration */
+      ed.putInt(FMCONFIG_COUNTRY, mCountry);
+      ed.putInt(LAST_RECORD_DURATION, mRecordDuration);
+      ed.putBoolean(LAST_AF_JUMP_VALUE, mAFAutoSwitch);
+      ed.commit();
+   }
+
+   public static void SetDefaults() {
+      mListIndex = 0;
+      mListOfPlists.clear();
+      setCountry(REGIONAL_BAND_NORTH_AMERICA);
+      setRadioBand(0);
+      setChSpacing(0);
+      setEmphasis(0);
+      setRdsStd(0);
+      mFMConfiguration.setLowerLimit(87500);
+      mFMConfiguration.setUpperLimit(107900);
+   }
+
+   public static void removeStationList(int listIndex) {
+      mListIndex = listIndex;
+      PresetList toRemove = mListOfPlists.get(mListIndex);
+
+      mNameMap.remove(toRemove.getName());
+      mListOfPlists.remove(mListIndex);
+      int numLists = mListOfPlists.size();
+
+      /* Remove for others */
+      for (int i = mListIndex; i < numLists; i++)
+      {
+         PresetList curList = mListOfPlists.get(i);
+         if (curList!=null)
+         {
+            String listName = curList.getName();
+            /* Removals */
+            mNameMap.remove(listName);
+            mNameMap.put(listName, String.valueOf(i));
+         }
+      }
+      mListIndex = 0;
+      repopulateEntryValueLists();
+   }
+
+   public static void setTunedFrequency(int frequency) {
+      mTunedFrequency = frequency;
+   }
+
+   public static int getTunedFrequency() {
+      return mTunedFrequency;
+   }
+
+   public static int getNextTuneFrequency(int frequency) {
+      int nextFrequency = (frequency + mFrequencyBand_Stepsize);
+      if (nextFrequency > getUpperLimit())
+      {
+          nextFrequency = getLowerLimit();
+      }
+      return nextFrequency;
+   }
+
+   public static int getNextTuneFrequency() {
+      int nextFrequency = (mTunedFrequency + mFrequencyBand_Stepsize);
+      if (nextFrequency > getUpperLimit())
+      {
+          nextFrequency = getLowerLimit();
+      }
+      return nextFrequency;
+   }
+
+   public static int getPrevTuneFrequency(int frequency) {
+      int prevFrequency = (frequency - mFrequencyBand_Stepsize);
+      if (prevFrequency < getLowerLimit())
+      {
+          prevFrequency = getUpperLimit();
+      }
+      return prevFrequency;
+   }
+
+   public static int getPrevTuneFrequency() {
+      int prevFrequency = (mTunedFrequency - mFrequencyBand_Stepsize);
+      if (prevFrequency < getLowerLimit())
+      {
+         prevFrequency = getUpperLimit();
+      }
+      return prevFrequency;
+   }
+
+   /**
+    * @param mFMConfiguration the mFMConfiguration to set
+    */
+   public static void setFMConfiguration(FmConfig mFMConfig) {
+      FmSharedPreferences.mFMConfiguration = mFMConfig;
+   }
+
+   /**
+    * @return the mFMConfiguration
+    */
+   public static FmConfig getFMConfiguration() {
+      return mFMConfiguration;
+   }
+
+   public static void setRadioBand(int band)
+   {
+      switch (band)
+      {
+      case FmReceiver.FM_JAPAN_WIDE_BAND:
+         {
+            mFrequencyBand_Stepsize = 50;
+            mFMConfiguration.setLowerLimit(76000);
+            mFMConfiguration.setUpperLimit(108000);
+            break;
+         }
+      case FmReceiver.FM_JAPAN_STANDARD_BAND:
+         {
+            mFrequencyBand_Stepsize = 100;
+            mFMConfiguration.setLowerLimit(76000);
+            mFMConfiguration.setUpperLimit(90000);
+            break;
+         }
+      case FmReceiver.FM_USER_DEFINED_BAND:
+         {
+            break;
+         }
+      case FmReceiver.FM_US_BAND:
+      case FmReceiver.FM_EU_BAND:
+      default:
+         {
+            band =  FmReceiver.FM_US_BAND;
+            mFMConfiguration.setLowerLimit(87500);
+            mFMConfiguration.setUpperLimit(107900);
+            mFrequencyBand_Stepsize = 100;
+         }
+      }
+      mFMConfiguration.setRadioBand(band);
+   }
+
+   public static int getRadioBand()
+   {
+      return mFMConfiguration.getRadioBand();
+   }
+
+   public static void setChSpacing(int spacing)
+   {
+      if((spacing>=FmReceiver.FM_CHSPACE_200_KHZ)
+          && (spacing<=FmReceiver.FM_CHSPACE_50_KHZ))
+      {
+         mFrequencyBand_Stepsize = 200;
+         switch (spacing)
+         {
+         case FmReceiver.FM_CHSPACE_100_KHZ:
+            {
+               mFrequencyBand_Stepsize = 100;
+               break;
+            }
+         case FmReceiver.FM_CHSPACE_50_KHZ:
+            {
+               mFrequencyBand_Stepsize = 50;
+               break;
+            }
+         }
+         mFMConfiguration.setChSpacing(spacing);
+      }
+   }
+
+   public static int getChSpacing()
+   {
+      return mFMConfiguration.getChSpacing();
+   }
+
+   public static void setRdsStd(int std)
+   {
+      if((std>=FmReceiver.FM_RDS_STD_RBDS)
+          && (std<=FmReceiver.FM_RDS_STD_NONE))
+      {
+         mFMConfiguration.setRdsStd(std);
+      }
+   }
+
+   public static int getRdsStd()
+   {
+      return mFMConfiguration.getRdsStd();
+   }
+
+   /* North America */
+   public static boolean isRDSStd()
+   {
+      return(FmReceiver.FM_RDS_STD_RDS == mFMConfiguration.getRdsStd());
+   }
+
+   public static boolean isRBDSStd()
+   {
+      return(FmReceiver.FM_RDS_STD_RBDS == mFMConfiguration.getRdsStd());
+   }
+
+   public static void setEmphasis(int emph)
+   {
+      if((emph>=FmReceiver.FM_DE_EMP75)
+          && (emph<=FmReceiver.FM_DE_EMP50))
+      {
+         mFMConfiguration.setEmphasis(emph);
+      }
+   }
+
+   public static int getEmphasis()
+   {
+      return mFMConfiguration.getEmphasis();
+   }
+
+   public static int getUpperLimit()
+   {
+      return mFMConfiguration.getUpperLimit();
+   }
+
+   public static int getLowerLimit()
+   {
+      return mFMConfiguration.getLowerLimit();
+   }
+   public static int getFrequencyStepSize() {
+      return mFrequencyBand_Stepsize;
+   }
+   public static void setLowerLimit(int lowLimit){
+      mFMConfiguration.setLowerLimit(lowLimit);
+   }
+
+   public static void setUpperLimit(int upLimit){
+      mFMConfiguration.setUpperLimit(upLimit);
+   }
+
+   public static void setCountry(int nCountryCode){
+
+      // Default: 87500  TO 10800 IN 100 KHZ STEPS
+      mFMConfiguration.setRadioBand(FmReceiver.FM_USER_DEFINED_BAND);
+      mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_100_KHZ);
+      mFMConfiguration.setEmphasis(FmReceiver.FM_DE_EMP50);
+      mFMConfiguration.setRdsStd(FmReceiver.FM_RDS_STD_RDS);
+      mFMConfiguration.setLowerLimit(87500);
+      mFMConfiguration.setUpperLimit(108000);
+
+      switch(nCountryCode)
+      {
+        case REGIONAL_BAND_NORTH_AMERICA:
+        {
+          /*NORTH_AMERICA : 87500 TO 108000 IN 200 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_US_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_200_KHZ);
+          mFMConfiguration.setEmphasis(FmReceiver.FM_DE_EMP75);
+          mFMConfiguration.setRdsStd(FmReceiver.FM_RDS_STD_RBDS);
+          mFMConfiguration.setLowerLimit(87500);
+          mFMConfiguration.setUpperLimit(107900);
+          mFrequencyBand_Stepsize = 200;
+          break;
+        }
+        case REGIONAL_BAND_EUROPE:
+        {
+          /*EUROPE/Default : 87500 TO 10800 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+
+        case REGIONAL_BAND_JAPAN:
+        {
+          /*JAPAN : 76000  TO 90000 IN 100 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_JAPAN_STANDARD_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_100_KHZ);
+          mFMConfiguration.setEmphasis(FmReceiver.FM_DE_EMP75);
+          mFMConfiguration.setLowerLimit(76000);
+          mFMConfiguration.setUpperLimit(90000);
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_JAPAN_WIDE:
+        {
+          /*JAPAN_WB : 90000 TO 108000 IN 50 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_JAPAN_WIDE_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_50_KHZ);
+          mFMConfiguration.setEmphasis(FmReceiver.FM_DE_EMP75);
+          mFMConfiguration.setLowerLimit(90000);
+          mFMConfiguration.setUpperLimit(108000);
+          mFrequencyBand_Stepsize = 50;
+          break;
+        }
+
+        /* Country specific */
+        case REGIONAL_BAND_AUSTRALIA:
+        {
+          /*AUSTRALIA : 87700 TO 108000 IN 100 KHZ STEPS*/
+          mFMConfiguration.setLowerLimit(87700);
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_AUSTRIA:
+        {
+          /*AUSTRIA : 87500 TO 108000 IN 50 KHZ STEPS*/
+          mFMConfiguration.setEmphasis(FmReceiver.FM_DE_EMP50);
+          mFrequencyBand_Stepsize = 50;
+          break;
+        }
+        case REGIONAL_BAND_BELGIUM:
+       {
+         /*BELGIUM : 87500 TO 108000 IN 100 KHZ STEPS*/
+         mFrequencyBand_Stepsize = 100;
+         break;
+       }
+       case REGIONAL_BAND_BRAZIL:
+       {
+         /*BRAZIL : 87500 TO 108000 IN 200 KHZ STEP*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_US_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_200_KHZ);
+          mFMConfiguration.setLowerLimit(87500);
+          mFMConfiguration.setUpperLimit(107900);
+          mFrequencyBand_Stepsize = 200;
+          break;
+        }
+        case REGIONAL_BAND_CHINA:
+        {
+          /*CHINA : 87000 TO 108000 IN 100 KHZ STEPS*/
+          mFMConfiguration.setLowerLimit(87000);
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_CZECH:
+        {
+          /*CZECH : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_DENMARK:
+        {
+          /*DENMARK : 87500 TO 108000 IN 50 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_EU_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_50_KHZ);
+          mFrequencyBand_Stepsize = 50;
+          break;
+        }
+        case REGIONAL_BAND_FINLAND:
+        {
+          /*FINLAND : 87500  TO 108000  IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_FRANCE:
+        {
+          /* FRANCE : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_GERMANY:
+          /*GERMANY : 87500 TO 108000 IN 50 KHZ STEPS*/
+        case REGIONAL_BAND_GREECE:
+          /*GREECE : 87500 TO 108000 IN 50 KHZ STEPS*/
+        {
+          mFMConfiguration.setRadioBand(FmReceiver.FM_EU_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_50_KHZ);
+          mFrequencyBand_Stepsize = 50;
+          break;
+        }
+        case REGIONAL_BAND_HONGKONG:
+        {
+          /*HONG KONG : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_INDIA:
+        {
+          /*INDIA : 91000 TO 106400 IN 100 KHZ STEPS*/
+          mFMConfiguration.setLowerLimit(91000);
+          mFMConfiguration.setUpperLimit(106400);
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_IRELAND:
+        {
+          /*IRELAND : 87500 TO 108000 IN 50 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_EU_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_50_KHZ);
+          mFrequencyBand_Stepsize = 50;
+          break;
+        }
+        case REGIONAL_BAND_ITALY:
+        {
+          /*ITALY : 87500 TO 108000 IN 50 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_EU_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_50_KHZ);
+          mFrequencyBand_Stepsize = 50;
+          break;
+        }
+        case REGIONAL_BAND_KOREA:
+        {
+          /*KOREA : 87500 TO 108000 IN 200 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_US_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_200_KHZ);
+          mFMConfiguration.setUpperLimit(107900);
+          mFrequencyBand_Stepsize = 200;
+          break;
+        }
+        case REGIONAL_BAND_MEXICO:
+        {
+          /*MEXICO : 88100 TO 107900 IN 200 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_US_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_200_KHZ);
+          mFMConfiguration.setEmphasis(FmReceiver.FM_DE_EMP75);
+          mFMConfiguration.setRdsStd(FmReceiver.FM_RDS_STD_RBDS);
+          mFMConfiguration.setLowerLimit(88100);
+          mFMConfiguration.setUpperLimit(107900);
+          mFrequencyBand_Stepsize = 200;
+          break;
+        }
+        case REGIONAL_BAND_NETHERLANDS:
+        {
+          /*NETHERLANDS : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_NEWZEALAND:
+        {
+          /*NEW ZEALAND : 88000 TO 107000 IN 100 KHZ STEPS*/
+          mFMConfiguration.setLowerLimit(88000);
+          mFMConfiguration.setUpperLimit(107000);
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_NORWAY:
+        {
+          /*NORWAY : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_POLAND:
+        {
+          /*POLAND : 88000 TO 108000 IN 50 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_EU_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_50_KHZ);
+          mFMConfiguration.setLowerLimit(88000);
+          mFrequencyBand_Stepsize = 50;
+          break;
+        }
+        case REGIONAL_BAND_PORTUGAL:
+        {
+          /*PORTUGAL : 87500 TO 108000 IN 50 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_EU_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_50_KHZ);
+          mFrequencyBand_Stepsize = 50;
+          break;
+        }
+        case REGIONAL_BAND_RUSSIA:
+        {
+          /*RUSSIA : 87500 TO 108000  IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_SINGAPORE:
+        {
+          /*SINGAPORE : 88000 TO 108000 IN 100 KHZ STEPS*/
+          mFMConfiguration.setLowerLimit(88000);
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_SLOVAKIA:
+        {
+          /*SLOVAKIA : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_SPAIN:
+        {
+          /*SPAIN : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_SWITZERLAND:
+        {
+          /*SWITZERLAND : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_SWEDEN:
+        {
+          /*SWEDEN : 87500 TO 108000  IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_TAIWAN:
+        {
+          /*TAIWAN : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_TURKEY:
+        {
+          /*TURKEY : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_UNITEDKINGDOM:
+        {
+          /*UNITED KINGDOM : 87500 TO 108000 IN 100 KHZ STEPS*/
+          mFrequencyBand_Stepsize = 100;
+          break;
+        }
+        case REGIONAL_BAND_UNITED_STATES:
+        {
+          /*UNITED STATES : 88100 TO 107900 IN 200 KHZ STEPS*/
+          mFMConfiguration.setRadioBand(FmReceiver.FM_US_BAND);
+          mFMConfiguration.setChSpacing(FmReceiver.FM_CHSPACE_200_KHZ);
+          mFMConfiguration.setEmphasis(FmReceiver.FM_DE_EMP75);
+          mFMConfiguration.setRdsStd(FmReceiver.FM_RDS_STD_RBDS);
+          mFMConfiguration.setLowerLimit(88100);
+          mFMConfiguration.setUpperLimit(107900);
+          mFrequencyBand_Stepsize = 200;
+          break;
+        }
+        default:
+        {
+          Log.d(LOGTAG, "Invalid: countryCode: "+nCountryCode);
+          nCountryCode=0;
+        }
+      }
+      mCountry = nCountryCode;
+      Log.d(LOGTAG, "=====================================================");
+      Log.d(LOGTAG, "Country     :"+nCountryCode);
+      Log.d(LOGTAG, "RadioBand   :"+ mFMConfiguration.getRadioBand());
+      Log.d(LOGTAG, "Emphasis    :"+ mFMConfiguration.getEmphasis());
+      Log.d(LOGTAG, "ChSpacing   :"+ mFMConfiguration.getChSpacing());
+      Log.d(LOGTAG, "RdsStd      :"+ mFMConfiguration.getRdsStd());
+      Log.d(LOGTAG, "LowerLimit  :"+ mFMConfiguration.getLowerLimit());
+      Log.d(LOGTAG, "UpperLimit  :"+ mFMConfiguration.getUpperLimit());
+      Log.d(LOGTAG, "=====================================================");
+   }
+
+
+   public static int getCountry() {
+      return mCountry;
+   }
+
+
+   public static void setAudioOutputMode(boolean bStereo) {
+      mAudioOutputMode = bStereo;
+   }
+
+   public static boolean getAudioOutputMode() {
+      return mAudioOutputMode;
+   }
+
+   public static void setRecordDuration(int durationIndex) {
+
+      Log.d(LOGTAG, "setRecordDuration "+durationIndex);
+      switch( durationIndex ) {
+      case 0: mRecordDuration = RECORD_DUR_INDEX_0_VAL; break;
+      case 1: mRecordDuration = RECORD_DUR_INDEX_1_VAL; break;
+      case 2: mRecordDuration = RECORD_DUR_INDEX_2_VAL; break;
+      case 3: mRecordDuration = RECORD_DUR_INDEX_3_VAL; break;
+      default:
+        {
+           Log.d(LOGTAG, "Invalid: durationIndex "+durationIndex);
+        }
+
+      }
+      return;
+   }
+
+   public static int getRecordDuration() {
+      return mRecordDuration;
+   }
+
+   public static void setAutoAFSwitch(boolean bAFAutoSwitch) {
+      mAFAutoSwitch = bAFAutoSwitch;
+   }
+
+   public static boolean getAutoAFSwitch() {
+      return mAFAutoSwitch;
+   }
+}
diff --git a/fmapp2/src/com/caf/fmradio/FmTags.java b/fmapp2/src/com/caf/fmradio/FmTags.java
new file mode 100644
index 0000000..f3bbdbe
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/FmTags.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011-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 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.util.*;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ProgressBar;
+import android.widget.Spinner;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+import android.widget.TextView;
+import android.widget.ListView;
+
+
+public class FmTags extends Activity {
+      private ListView la;
+      private ArrayAdapter<String> adapter;
+      private final Handler mHandler = new Handler();
+      private Iterator itr;
+
+      @Override
+       public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setContentView(R.layout.fmtags);
+            la = (ListView)findViewById(R.id.TagListView);
+       }
+       @Override
+       public void onStart() {
+            super.onStart();
+       }
+       @Override
+       public void onResume() {
+            super.onResume();
+            mHandler.post(mDisplayTagList);
+       }
+       final Runnable mDisplayTagList = new Runnable() {
+            public void run() {
+                   String[] tags;
+                   int l = 0;
+
+                   tags = new String[FmSharedPreferences.num_tags];
+                   for(int i = 0; i < FmSharedPreferences.MAX_NUM_TAG_TYPES; i++) {
+                       if (FmSharedPreferences.tagList[i] != null) {
+                          itr = FmSharedPreferences.tagList[i].iterator();
+                          while(itr.hasNext())
+                                tags[l++] = ((FmSharedPreferences.TAG_NAMES[i]) + "\n" +
+                                              "\t" + (String)itr.next());
+                       }
+                   }
+                   adapter = new ArrayAdapter(la.getContext(), android.R.layout.simple_list_item_1, tags);
+                   la.setAdapter(adapter);
+            }
+       };
+}
+
+
diff --git a/fmapp2/src/com/caf/fmradio/HorizontalNumberPicker.java b/fmapp2/src/com/caf/fmradio/HorizontalNumberPicker.java
new file mode 100644
index 0000000..8a89a85
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/HorizontalNumberPicker.java
@@ -0,0 +1,2223 @@
+/*
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.caf.fmradio;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.annotation.Widget;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Paint.Align;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.text.InputFilter;
+import android.text.InputType;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.method.NumberKeyListener;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.LayoutInflater.Filter;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.animation.DecelerateInterpolator;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.Scroller;
+import android.widget.TextView;
+
+import com.android.internal.R;
+
+/**
+ * A widget that enables the user to select a number form a predefined range.
+ * The widget presents an input filed and up and down buttons for selecting the
+ * current value. Pressing/long pressing the up and down buttons increments and
+ * decrements the current value respectively. Touching the input filed shows a
+ * scroll wheel, tapping on which while shown and not moving allows direct edit
+ * of the current value. Sliding motions up or down hide the buttons and the
+ * input filed, show the scroll wheel, and rotate the latter. Flinging is also
+ * supported. The widget enables mapping from positions to strings such that
+ * instead the position index the corresponding string is displayed.
+ * <p>
+ * For an example of using this widget, see {@link android.widget.TimePicker}.
+ * </p>
+ */
+@Widget
+public class HorizontalNumberPicker extends LinearLayout {
+
+    /**
+     * The default update interval during long press.
+     */
+    private static final long DEFAULT_LONG_PRESS_UPDATE_INTERVAL = 300;
+
+    /**
+     * The index of the middle selector item.
+     */
+//    private static final int SELECTOR_MIDDLE_ITEM_INDEX = 10;
+
+    /**
+     * The coefficient by which to adjust (divide) the max fling velocity.
+     */
+    private static final int SELECTOR_MAX_FLING_VELOCITY_ADJUSTMENT = 8;
+
+    /**
+     * The the duration for adjusting the selector wheel.
+     */
+    private static final int SELECTOR_ADJUSTMENT_DURATION_MILLIS = 800;
+
+    /**
+     * The duration of scrolling to the next/previous value while changing the
+     * current value by one, i.e. increment or decrement.
+     */
+    private static final int CHANGE_CURRENT_BY_ONE_SCROLL_DURATION = 300;
+
+    /**
+     * The the delay for showing the input controls after a single tap on the
+     * input text.
+     */
+    private static final int SHOW_INPUT_CONTROLS_DELAY_MILLIS = ViewConfiguration
+            .getDoubleTapTimeout();
+
+    /**
+     * The strength of fading in the top and bottom while drawing the selector.
+     */
+    private static final float TOP_AND_BOTTOM_FADING_EDGE_STRENGTH = 0.9f;
+
+    /**
+     * The default unscaled height of the selection divider.
+     */
+    private static final int UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT = 2;
+
+    /**
+     * In this state the selector wheel is not shown.
+     */
+    private static final int SELECTOR_WHEEL_STATE_NONE = 0;
+
+    /**
+     * In this state the selector wheel is small.
+     */
+    private static final int SELECTOR_WHEEL_STATE_SMALL = 1;
+
+    /**
+     * In this state the selector wheel is large.
+     */
+    private static final int SELECTOR_WHEEL_STATE_LARGE = 2;
+
+    /**
+     * The alpha of the selector wheel when it is bright.
+     */
+    private static final int SELECTOR_WHEEL_BRIGHT_ALPHA = 255;
+
+    /**
+     * The alpha of the selector wheel when it is dimmed.
+     */
+    private static final int SELECTOR_WHEEL_DIM_ALPHA = 60;
+
+    /**
+     * The alpha for the increment/decrement button when it is transparent.
+     */
+    private static final int BUTTON_ALPHA_TRANSPARENT = 0;
+
+    /**
+     * The alpha for the increment/decrement button when it is opaque.
+     */
+    private static final int BUTTON_ALPHA_OPAQUE = 1;
+
+    /**
+     * The property for setting the selector paint.
+     */
+    private static final String PROPERTY_SELECTOR_PAINT_ALPHA = "selectorPaintAlpha";
+
+    /**
+     * The property for setting the increment/decrement button alpha.
+     */
+    private static final String PROPERTY_BUTTON_ALPHA = "alpha";
+
+    /**
+     * The numbers accepted by the input text's {@link Filter}
+     */
+    private static final char[] DIGIT_CHARACTERS = new char[] { '0', '1', '2',
+            '3', '4', '5', '6', '7', '8', '9' };
+
+    /**
+     * Constant for unspecified size.
+     */
+    private static final int SIZE_UNSPECIFIED = -1;
+
+    /**
+     * Use a custom NumberPicker formatting callback to use two-digit minutes
+     * strings like "01". Keeping a static formatter etc. is the most efficient
+     * way to do this; it avoids creating temporary objects on every call to
+     * format().
+     *
+     * @hide
+     */
+    public static final HorizontalNumberPicker.Formatter TWO_DIGIT_FORMATTER = new HorizontalNumberPicker.Formatter() {
+        final StringBuilder mBuilder = new StringBuilder();
+
+        final java.util.Formatter mFmt = new java.util.Formatter(mBuilder,
+                java.util.Locale.US);
+
+        final Object[] mArgs = new Object[1];
+
+        public String format(int value) {
+            mArgs[0] = value;
+            mBuilder.delete(0, mBuilder.length());
+            mFmt.format("%02d", mArgs);
+            return mFmt.toString();
+        }
+    };
+
+    private static final String TAG = "HorizontalNumberPicker";
+
+    /**
+     * The increment button.
+     */
+    // private final ImageButton mIncrementButton;
+
+    /**
+     * The decrement button.
+     */
+    // private final ImageButton mDecrementButton;
+
+    /**
+     * The text for showing the current value.
+     */
+//    private final EditText mInputText;
+
+    /**
+     * The min height of this widget.
+     */
+    private final int mMinHeight = 0;
+
+    /**
+     * The max height of this widget.
+     */
+    private int mMaxHeight;
+
+    /**
+     * The max width of this widget.
+     */
+    private final int mMinWidth = 0;
+
+    /**
+     * The max width of this widget.
+     */
+    private int mMaxWidth;
+
+    /**
+     * Flag whether to compute the max width.
+     */
+    private final boolean mComputeMaxWidth;
+
+    /**
+     * The height of the text.
+     */
+    private int mTextSize = 20;
+    /**
+     * The height of the gap between text elements if the selector wheel.
+     */
+    private int mSelectorTextGapHeight;
+
+    /**
+     * The width of the gap between text elements if the selector wheel.
+     */
+    private int mSelectorTextGapWidth;
+
+    /**
+     * The values to be displayed instead the indices.
+     */
+    private String[] mDisplayedValues;
+
+    /**
+     * Lower value of the range of numbers allowed for the NumberPicker
+     */
+    private int mMinValue;
+
+    /**
+     * Upper value of the range of numbers allowed for the NumberPicker
+     */
+    private int mMaxValue;
+
+    /**
+     * Current value of this NumberPicker
+     */
+    private int mValue;
+
+    /**
+     * Listener to be notified upon current value change.
+     */
+    private OnValueChangeListener mOnValueChangeListener;
+
+    /**
+     * Listener to be notified upon scroll state change.
+     */
+    private OnScrollListener mOnScrollListener;
+
+    /**
+     * Formatter for for displaying the current value.
+     */
+    private Formatter mFormatter;
+
+    /**
+     * The speed for updating the value form long press.
+     */
+    private long mLongPressUpdateInterval = DEFAULT_LONG_PRESS_UPDATE_INTERVAL;
+
+    /**
+     * Cache for the string representation of selector indices.
+     */
+    private final SparseArray<String> mSelectorIndexToStringCache = new SparseArray<String>();
+
+    /**
+     * The selector indices whose value are show by the selector.
+     */
+    private final int[] SELECTOR_INDICES_MEDIUM = new int[] {
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE
+            };
+    private final int[] SELECTOR_INDICES_SMALL = new int[] {
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE,
+            };
+    private final int[] SELECTOR_INDICES_LARGE = new int[] {
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
+            Integer.MIN_VALUE, Integer.MIN_VALUE,
+            };
+    private int[] mSelectorIndices = SELECTOR_INDICES_MEDIUM;
+    private  int mSelectorMiddleItemIndex = mSelectorIndices.length / 2;
+    /**
+     * The offset to middle of selector.
+     */
+    private static final int SELECTOR_OFFSET_ZERO = 0;
+    /**
+     * The colors alpha of selector text.
+     */
+    private static final int SELECTOR_TEXT_ALPHA_TRANSPARENT_NONE = 255;
+
+    private static float mDensity = 1.0f;
+    private static final float LDPI = 0.75f;
+    private static final float MDPI = 1.0f;
+    private static final float HDPI = 1.5f;
+    private static final float XHDPI = 2.0f;
+
+    private float mScaleWidth = 2;
+    private float mScaleLengthShort = 10;
+    private float mScaleLengthLong = 20;
+    private float mGapBetweenNumAndScale = 18;
+    private float mHdpiPositionAdjust = 18;
+
+    public enum Scale {
+      SCALE_SMALL,
+      SCALE_MEDIUM,
+      SCALE_LARGE
+    };
+    /**
+     * The {@link Paint} for drawing the selector.
+     */
+    private final Paint mSelectorWheelPaint;
+
+    /**
+     * The height of a selector element (text + gap).
+     */
+    private int mSelectorElementHeight;
+
+    /**
+     * The width of a selector element (text + gap).
+     */
+    private int mSelectorElementWidth;
+
+    /**
+     * The initial offset of the scroll selector.
+     */
+    private int mInitialScrollOffset = Integer.MIN_VALUE;
+
+    /**
+     * The initial offset for horizontal  scroll selector .
+     */
+    private static final int INIT_SCROLL_OFFSET_HORIZONTAL = 0;
+
+    /**
+     * The initial offset for vertical  scroll selector .
+     */
+    private static final int INIT_SCROLL_OFFSET_VERTICAL = 0;
+    /**
+     * The current offset of the scroll selector.
+     */
+    private int mCurrentScrollOffset;
+
+    /**
+     * The {@link Scroller} responsible for flinging the selector.
+     */
+    private final Scroller mFlingScroller;
+
+    /**
+     * The {@link Scroller} responsible for adjusting the selector.
+     */
+    private final Scroller mAdjustScroller;
+
+    /**
+     * The previous Y coordinate while scrolling the selector.
+     */
+    private int mPreviousScrollerY;
+
+    /**
+     * The previous Y coordinate while scrolling the selector.
+     */
+    private int mPreviousScrollerX;
+
+    /**
+     * Handle to the reusable command for setting the input text selection.
+     */
+    private SetSelectionCommand mSetSelectionCommand;
+
+    /**
+     * Handle to the reusable command for adjusting the scroller.
+     */
+    private AdjustScrollerCommand mAdjustScrollerCommand;
+
+    /**
+     * Handle to the reusable command for changing the current value from long
+     * press by one.
+     */
+    private ChangeCurrentByOneFromLongPressCommand mChangeCurrentByOneFromLongPressCommand;
+
+    /**
+     * {@link Animator} for showing the up/down arrows.
+     */
+//     private final AnimatorSet mShowInputControlsAnimator;
+
+    /**
+     * {@link Animator} for dimming the selector wheel.
+     */
+//     private final Animator mDimSelectorWheelAnimator;
+
+    /**
+     * The Y position of the last down event.
+     */
+    private float mLastDownEventY;
+    /**
+     * The X position of the last down event.
+     */
+    private float mLastDownEventX;
+
+    /**
+     * The Y position of the last motion event.
+     */
+    private float mLastMotionEventY;
+
+    /**
+     * The X position of the last motion event.
+     */
+    private float mLastMotionEventX;
+
+    /**
+     * Flag if to begin edit on next up event.
+     */
+    private boolean mBeginEditOnUpEvent;
+
+    /**
+     * Flag if to adjust the selector wheel on next up event.
+     */
+    private boolean mAdjustScrollerOnUpEvent;
+
+    /**
+     * The state of the selector wheel.
+     */
+    private int mSelectorWheelState;
+
+    /**
+     * Determines speed during touch scrolling.
+     */
+    private VelocityTracker mVelocityTracker;
+
+    /**
+     * @see ViewConfiguration#getScaledTouchSlop()
+     */
+    private int mTouchSlop;
+
+    /**
+     * @see ViewConfiguration#getScaledMinimumFlingVelocity()
+     */
+    private int mMinimumFlingVelocity;
+
+    /**
+     * @see ViewConfiguration#getScaledMaximumFlingVelocity()
+     */
+    private int mMaximumFlingVelocity;
+
+    /**
+     * Flag whether the selector should wrap around.
+     */
+    private boolean mWrapSelectorWheel;
+
+    /**
+     * The back ground color used to optimize scroller fading.
+     */
+    private final int mSolidColor;
+
+    /**
+     * Flag indicating if this widget supports flinging.
+     */
+    private final boolean mFlingable;
+
+    /**
+     * Divider for showing item to be selected while scrolling
+     */
+//     private final Drawable mSelectionDivider;
+
+    /**
+     * The height of the selection divider.
+     */
+//     private final int mSelectionDividerHeight;
+
+    /**
+     * Reusable {@link Rect} instance.
+     */
+    private final Rect mTempRect = new Rect();
+
+    /**
+     * The current scroll state of the number picker.
+     */
+    private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+    /**
+     * The duration of the animation for showing the input controls.
+     */
+     private final long mShowInputControlsAnimimationDuration;
+
+    /**
+     * Flag whether the scoll wheel and the fading edges have been initialized.
+     */
+    private boolean mScrollWheelAndFadingEdgesInitialized;
+
+    private boolean mHorizontal = true;
+
+    /**
+     * Interface to listen for changes of the current value.
+     */
+    public interface OnValueChangeListener {
+
+        /**
+         * Called upon a change of the current value.
+         *
+         * @param picker
+         *            The NumberPicker associated with this listener.
+         * @param oldVal
+         *            The previous value.
+         * @param newVal
+         *            The new value.
+         */
+        void onValueChange(HorizontalNumberPicker picker, int oldVal, int newVal);
+    }
+
+
+    private OnScrollFinishListener mOnScrollFinishListener;
+
+    public interface OnScrollFinishListener{
+        public void onScrollFinish(int value);
+    }
+    /**
+     * Interface to listen for the picker scroll state.
+     */
+    public interface OnScrollListener {
+
+        /**
+         * The view is not scrolling.
+         */
+        public static int SCROLL_STATE_IDLE = 0;
+
+        /**
+         * The user is scrolling using touch, and their finger is still on the
+         * screen.
+         */
+        public static int SCROLL_STATE_TOUCH_SCROLL = 1;
+
+        /**
+         * The user had previously been scrolling using touch and performed a
+         * fling.
+         */
+        public static int SCROLL_STATE_FLING = 2;
+
+        /**
+         * Callback invoked while the number picker scroll state has changed.
+         *
+         * @param view
+         *            The view whose scroll state is being reported.
+         * @param scrollState
+         *            The current scroll state. One of
+         *            {@link #SCROLL_STATE_IDLE},
+         *            {@link #SCROLL_STATE_TOUCH_SCROLL} or
+         *            {@link #SCROLL_STATE_IDLE}.
+         */
+        public void onScrollStateChange(HorizontalNumberPicker view,
+                int scrollState);
+    }
+
+    /**
+     * Interface used to format current value into a string for presentation.
+     */
+    public interface Formatter {
+
+        /**
+         * Formats a string representation of the current value.
+         *
+         * @param value
+         *            The currently selected value.
+         * @return A formatted string representation.
+         */
+        public String format(int value);
+    }
+
+    /**
+     * Create a new number picker.
+     *
+     * @param context
+     *            The application environment.
+     */
+    public HorizontalNumberPicker(Context context) {
+        this(context, null);
+    }
+
+    /**
+     * Create a new number picker.
+     *
+     * @param context
+     *            The application environment.
+     * @param attrs
+     *            A collection of attributes.
+     */
+    public HorizontalNumberPicker(Context context, AttributeSet attrs) {
+        this(context, attrs, R.attr.numberPickerStyle);
+    }
+
+    /**
+     * Create a new number picker
+     *
+     * @param context
+     *            the application environment.
+     * @param attrs
+     *            a collection of attributes.
+     * @param defStyle
+     *            The default style to apply to this view.
+     */
+    public HorizontalNumberPicker(Context context, AttributeSet attrs,
+            int defStyle) {
+        super(context, attrs, defStyle);
+
+        // process style attributes
+        TypedArray attributesArray = context.obtainStyledAttributes(attrs,
+                R.styleable.NumberPicker, defStyle, 0);
+        mSolidColor = attributesArray.getColor(
+                R.styleable.NumberPicker_solidColor, 0);
+        //mFlingable = attributesArray.getBoolean(
+        //        R.styleable.NumberPicker_flingable, true);
+        mFlingable = true;
+
+        mComputeMaxWidth = (mMaxWidth == Integer.MAX_VALUE);
+        attributesArray.recycle();
+
+        mShowInputControlsAnimimationDuration = getResources().getInteger(
+                R.integer.config_longAnimTime);
+
+        // By default Linearlayout that we extend is not drawn. This is
+        // its draw() method is not called but dispatchDraw() is called
+        // directly (see ViewGroup.drawChild()). However, this class uses
+        // the fading edge effect implemented by View and we need our
+        // draw() method to be called. Therefore, we declare we will draw.
+        setWillNotDraw(false);
+        setSelectorWheelState(SELECTOR_WHEEL_STATE_NONE);
+
+
+        // initialize constants
+        mTouchSlop = ViewConfiguration.getTapTimeout();
+        ViewConfiguration configuration = ViewConfiguration.get(context);
+        mTouchSlop = configuration.getScaledTouchSlop();
+        mMinimumFlingVelocity = configuration.getScaledMinimumFlingVelocity();
+        mMaximumFlingVelocity = configuration.getScaledMaximumFlingVelocity()
+                / SELECTOR_MAX_FLING_VELOCITY_ADJUSTMENT;
+//        mTextSize = (int) mInputText.getTextSize();
+        // create the selector wheel paint
+        Paint paint = new Paint();
+        paint.setAntiAlias(true);
+        paint.setTextAlign(Align.CENTER);
+        paint.setTextSize(mTextSize);
+        paint.setColor(Color.WHITE);
+        mSelectorWheelPaint = paint;
+
+
+        // create the fling and adjust scrollers
+        mFlingScroller = new Scroller(getContext(), null, true);
+        mAdjustScroller = new Scroller(getContext(),
+                new DecelerateInterpolator(2.5f));
+//        updateInputTextView();
+
+         updateIncrementAndDecrementButtonsVisibilityState();
+
+        if (mFlingable) {
+            if (isInEditMode()) {
+                setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
+            } else {
+                // Start with shown selector wheel and hidden controls. When
+                // made
+                // visible hide the selector and fade-in the controls to suggest
+                // fling interaction.
+                setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
+            }
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right,
+            int bottom) {
+        final int msrdWdth = getMeasuredWidth();
+        final int msrdHght = getMeasuredHeight();
+
+        if (!mScrollWheelAndFadingEdgesInitialized) {
+            mScrollWheelAndFadingEdgesInitialized = true;
+            // need to do all this when we know our size
+            initializeSelectorWheel();
+            initializeFadingEdges();
+        }
+        setVerticalFadingEdgeEnabled(false);
+    }
+    public void setTextSize(int textSize){
+        if(textSize > 0 ){
+            mTextSize = textSize;
+            mSelectorWheelPaint.setTextSize(textSize);
+        }
+    }
+    public void setDensity(int density){
+        switch(density){
+        case DisplayMetrics.DENSITY_LOW :
+            mDensity = LDPI;
+            break;
+        case DisplayMetrics.DENSITY_MEDIUM:
+            mDensity = MDPI;
+            break;
+        case DisplayMetrics.DENSITY_HIGH:
+            mDensity = HDPI;
+            break;
+        case DisplayMetrics.DENSITY_XHIGH:
+            mDensity = XHDPI;
+            break;
+        default:
+            mDensity = MDPI;
+            break;
+        }
+    }
+
+    public void setScale(Scale scale){
+        switch(scale){
+        case SCALE_SMALL:
+            mSelectorIndices = SELECTOR_INDICES_SMALL;
+                break;
+        case SCALE_MEDIUM:
+            mSelectorIndices = SELECTOR_INDICES_MEDIUM;
+            break;
+        case SCALE_LARGE:
+            mSelectorIndices = SELECTOR_INDICES_LARGE;
+            break;
+        default :
+            break;
+        }
+
+        mSelectorMiddleItemIndex = mSelectorIndices.length / 2;
+        initializeSelectorWheel();
+//        invalidate();
+    }
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+
+        final int newWidthMeasureSpec = makeMeasureSpec(widthMeasureSpec,
+                mMaxWidth);
+        final int newHeightMeasureSpec = makeMeasureSpec(heightMeasureSpec,
+                mMaxHeight);
+        super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
+        // Flag if we are measured with width or height less than the respective
+        // min.
+        final int widthSize = resolveSizeAndStateRespectingMinSize(mMinWidth,
+                getMeasuredWidth(), widthMeasureSpec);
+        final int heightSize = resolveSizeAndStateRespectingMinSize(mMinHeight,
+                getMeasuredHeight(), heightMeasureSpec);
+        setMeasuredDimension(widthSize, heightSize);
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent event) {
+        if (!isEnabled() || !mFlingable) {
+            return false;
+        }
+        switch (event.getActionMasked()) {
+        case MotionEvent.ACTION_DOWN:
+            mLastMotionEventY = mLastDownEventY = event.getY();
+            mLastMotionEventX = mLastDownEventX = event.getX();
+            removeAllCallbacks();
+            mBeginEditOnUpEvent = false;
+            mAdjustScrollerOnUpEvent = true;
+            if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
+                mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
+                boolean scrollersFinished = mFlingScroller.isFinished()
+                        && mAdjustScroller.isFinished();
+                if (!scrollersFinished) {
+                    mFlingScroller.forceFinished(true);
+                    mAdjustScroller.forceFinished(true);
+                    onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
+                }
+                mBeginEditOnUpEvent = scrollersFinished;
+                mAdjustScrollerOnUpEvent = true;
+                return true;
+            }
+
+            mAdjustScrollerOnUpEvent = false;
+            setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
+//            hideInputControls();
+            return true;
+        case MotionEvent.ACTION_MOVE:
+            float currentMoveY = event.getY();
+            float currentMoveX = event.getX();
+            int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
+            int deltaDownX = (int) Math.abs(currentMoveX - mLastDownEventX);
+            if(mHorizontal){
+                if (mLastDownEventX > mTouchSlop) {
+                    mBeginEditOnUpEvent = false;
+                    onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+                    return true;
+                }
+            }else{
+                if (deltaDownY > mTouchSlop) {
+                    mBeginEditOnUpEvent = false;
+                    onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+                    return true;
+                }
+            }
+            break;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (!isEnabled()) {
+            return false;
+        }
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+        mVelocityTracker.addMovement(ev);
+        int action = ev.getActionMasked();
+
+        switch (action) {
+        case MotionEvent.ACTION_MOVE:
+            if (!mHorizontal) {
+                float currentMoveY = ev.getY();
+                if (mBeginEditOnUpEvent
+                        || mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
+                    int deltaDownY = (int) Math.abs(currentMoveY
+                            - mLastDownEventY);
+                    if (deltaDownY > mTouchSlop) {
+                        mBeginEditOnUpEvent = false;
+                        onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+                    }
+                }
+                int deltaMoveY = (int) (currentMoveY - mLastMotionEventY);
+                scrollBy(0, deltaMoveY);
+                invalidate();
+                mLastMotionEventY = currentMoveY;
+            } else {
+                float currentMoveX = ev.getX();
+                if (mBeginEditOnUpEvent
+                        || mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
+                    int deltaDownX = (int) Math.abs(currentMoveX
+                            - mLastDownEventX);
+                    if (deltaDownX > mTouchSlop) {
+                        mBeginEditOnUpEvent = false;
+                        onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+                    }
+                }
+                int deltaMoveX = (int) (currentMoveX - mLastMotionEventX);
+                scrollBy(deltaMoveX, 0);
+                invalidate();
+                mLastMotionEventX = currentMoveX;
+            }
+            break;
+        case MotionEvent.ACTION_UP:
+            if (mBeginEditOnUpEvent) {
+                setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
+                return true;
+            }
+//            VelocityTracker velocityTracker = mVelocityTracker;
+//            velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
+//            int initialVelocity=0;
+//            if(!mHorizontal){
+//                initialVelocity = (int) velocityTracker.getYVelocity();
+//            }else{
+//              initialVelocity = (int)velocityTracker.getXVelocity();
+//            }
+//            if (Math.abs(initialVelocity) > mMinimumFlingVelocity) {
+//                // fling after up
+//                fling(initialVelocity);
+//                onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
+//            } else {
+                if (mAdjustScrollerOnUpEvent) {
+                    if (mFlingScroller.isFinished()
+                            && mAdjustScroller.isFinished()) {
+                        postAdjustScrollerCommand(0);
+                    }
+                } else {
+                    postAdjustScrollerCommand(SHOW_INPUT_CONTROLS_DELAY_MILLIS);
+                }
+//            }
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+            break;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        final int action = event.getActionMasked();
+        switch (action) {
+        case MotionEvent.ACTION_MOVE:
+            if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
+                removeAllCallbacks();
+                 forceCompleteChangeCurrentByOneViaScroll();
+            }
+            break;
+        case MotionEvent.ACTION_CANCEL:
+        case MotionEvent.ACTION_UP:
+            removeAllCallbacks();
+            break;
+        }
+        return super.dispatchTouchEvent(event);
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        int keyCode = event.getKeyCode();
+        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
+                || keyCode == KeyEvent.KEYCODE_ENTER) {
+            removeAllCallbacks();
+        }
+        return super.dispatchKeyEvent(event);
+    }
+
+    @Override
+    public boolean dispatchTrackballEvent(MotionEvent event) {
+        int action = event.getActionMasked();
+        if (action == MotionEvent.ACTION_CANCEL
+                || action == MotionEvent.ACTION_UP) {
+            removeAllCallbacks();
+        }
+        return super.dispatchTrackballEvent(event);
+    }
+
+    @Override
+    public void computeScroll() {
+        if (mSelectorWheelState == SELECTOR_WHEEL_STATE_NONE) {
+            return;
+        }
+        Scroller scroller = mFlingScroller;
+        if (scroller.isFinished()) {
+            scroller = mAdjustScroller;
+            if (scroller.isFinished()) {
+                return;
+            }
+        }
+        scroller.computeScrollOffset();
+
+        if (mHorizontal) {
+            int currentScrollerX = scroller.getCurrX();
+            if (mPreviousScrollerX == 0) {
+                mPreviousScrollerX = scroller.getStartX();
+
+            }
+
+            scrollBy(currentScrollerX - mPreviousScrollerX, 0);
+            mPreviousScrollerX = currentScrollerX;
+
+        } else {
+            int currentScrollerY = scroller.getCurrY();
+            if (mPreviousScrollerY == 0) {
+                mPreviousScrollerY = scroller.getStartY();
+            }
+            scrollBy(0, currentScrollerY - mPreviousScrollerY);
+            mPreviousScrollerY = currentScrollerY;
+        }
+
+        if (scroller.isFinished()) {
+            onScrollerFinished(scroller);
+        } else {
+            invalidate();
+        }
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        super.setEnabled(enabled);
+    }
+
+    @Override
+    public void scrollBy(int x, int y) {
+        if (mSelectorWheelState == SELECTOR_WHEEL_STATE_NONE) {
+            return;
+        }
+        int[] selectorIndices = mSelectorIndices;
+        if (!mHorizontal) {
+            if (!mWrapSelectorWheel && y > 0
+                    && selectorIndices[mSelectorMiddleItemIndex] <= mMinValue) {
+                mCurrentScrollOffset = mInitialScrollOffset;
+                return;
+            }
+            if (!mWrapSelectorWheel && y < 0
+                    && selectorIndices[mSelectorMiddleItemIndex] >= mMaxValue) {
+                mCurrentScrollOffset = mInitialScrollOffset;
+                return;
+            }
+            mCurrentScrollOffset += y;
+            while (mCurrentScrollOffset - mInitialScrollOffset > mSelectorTextGapHeight) {
+                mCurrentScrollOffset -= mSelectorElementHeight;
+                decrementSelectorIndices(selectorIndices);
+                changeCurrent(selectorIndices[mSelectorMiddleItemIndex]);
+                if (!mWrapSelectorWheel
+                        && selectorIndices[mSelectorMiddleItemIndex] <= mMinValue) {
+                    mCurrentScrollOffset = mInitialScrollOffset;
+                }
+            }
+            while (mCurrentScrollOffset - mInitialScrollOffset < -mSelectorTextGapHeight) {
+                mCurrentScrollOffset += mSelectorElementHeight;
+                incrementSelectorIndices(selectorIndices);
+                changeCurrent(selectorIndices[mSelectorMiddleItemIndex]);
+                if (!mWrapSelectorWheel
+                        && selectorIndices[mSelectorMiddleItemIndex] >= mMaxValue) {
+                    mCurrentScrollOffset = mInitialScrollOffset;
+                }
+            }
+        } else {
+            if (!mWrapSelectorWheel && x > 0
+                    && selectorIndices[mSelectorMiddleItemIndex] <= mMinValue) {
+                mCurrentScrollOffset = mInitialScrollOffset;
+                return;
+            }
+            if (!mWrapSelectorWheel && x < 0
+                    && selectorIndices[mSelectorMiddleItemIndex] >= mMaxValue) {
+                mCurrentScrollOffset = mInitialScrollOffset;
+                return;
+            }
+            mCurrentScrollOffset += x;
+            while (mCurrentScrollOffset - mInitialScrollOffset > mSelectorTextGapWidth) {
+                mCurrentScrollOffset -= mSelectorElementWidth;
+                decrementSelectorIndices(selectorIndices);
+                changeCurrent(selectorIndices[mSelectorMiddleItemIndex]);
+                if (!mWrapSelectorWheel
+                        && selectorIndices[mSelectorMiddleItemIndex] <= mMinValue) {
+                    mCurrentScrollOffset = mInitialScrollOffset;
+                }
+            }
+            while (mCurrentScrollOffset - mInitialScrollOffset < -mSelectorTextGapWidth) {
+                mCurrentScrollOffset += mSelectorElementWidth;
+                incrementSelectorIndices(selectorIndices);
+                changeCurrent(selectorIndices[mSelectorMiddleItemIndex]);
+                if (!mWrapSelectorWheel
+                        && selectorIndices[mSelectorMiddleItemIndex] >= mMaxValue) {
+                    mCurrentScrollOffset = mInitialScrollOffset;
+                }
+            }
+        }
+
+    }
+
+    @Override
+    public int getSolidColor() {
+        return mSolidColor;
+    }
+
+    /**
+     * Sets the listener to be notified on change of the current value.
+     *
+     * @param onValueChangedListener
+     *            The listener.
+     */
+    public void setOnValueChangedListener(
+            OnValueChangeListener onValueChangedListener) {
+        mOnValueChangeListener = onValueChangedListener;
+    }
+
+    /**
+     * Set listener to be notified for scroll state changes.
+     *
+     * @param onScrollListener
+     *            The listener.
+     */
+    public void setOnScrollListener(OnScrollListener onScrollListener) {
+        mOnScrollListener = onScrollListener;
+    }
+    public void setOnScrollFinishedListener(OnScrollFinishListener onScrollFinishListener){
+        mOnScrollFinishListener = onScrollFinishListener;
+    }
+    /**
+     * Set the formatter to be used for formatting the current value.
+     * <p>
+     * Note: If you have provided alternative values for the values this
+     * formatter is never invoked.
+     * </p>
+     *
+     * @param formatter
+     *            The formatter object. If formatter is <code>null</code>,
+     *            {@link String#valueOf(int)} will be used.
+     *
+     * @see #setDisplayedValues(String[])
+     */
+    public void setFormatter(Formatter formatter) {
+        if (formatter == mFormatter) {
+            return;
+        }
+        mFormatter = formatter;
+        initializeSelectorWheelIndices();
+//        updateInputTextView();
+    }
+
+    /**
+     * Set the current value for the number picker.
+     * <p>
+     * If the argument is less than the {@link NumberPicker#getMinValue()} and
+     * {@link NumberPicker#getWrapSelectorWheel()} is <code>false</code> the
+     * current value is set to the {@link NumberPicker#getMinValue()} value.
+     * </p>
+     * <p>
+     * If the argument is less than the {@link NumberPicker#getMinValue()} and
+     * {@link NumberPicker#getWrapSelectorWheel()} is <code>true</code> the
+     * current value is set to the {@link NumberPicker#getMaxValue()} value.
+     * </p>
+     * <p>
+     * If the argument is less than the {@link NumberPicker#getMaxValue()} and
+     * {@link NumberPicker#getWrapSelectorWheel()} is <code>false</code> the
+     * current value is set to the {@link NumberPicker#getMaxValue()} value.
+     * </p>
+     * <p>
+     * If the argument is less than the {@link NumberPicker#getMaxValue()} and
+     * {@link NumberPicker#getWrapSelectorWheel()} is <code>true</code> the
+     * current value is set to the {@link NumberPicker#getMinValue()} value.
+     * </p>
+     *
+     * @param value
+     *            The current value.
+     * @see #setWrapSelectorWheel(boolean)
+     * @see #setMinValue(int)
+     * @see #setMaxValue(int)
+     */
+    public void setValue(int value) {
+        if (mValue == value) {
+            return;
+        }
+        if (value < mMinValue) {
+            value = mWrapSelectorWheel ? mMaxValue : mMinValue;
+        }
+        if (value > mMaxValue) {
+            value = mWrapSelectorWheel ? mMinValue : mMaxValue;
+        }
+        mValue = value;
+        initializeSelectorWheelIndices();
+        updateInputTextView();
+        updateIncrementAndDecrementButtonsVisibilityState();
+        invalidate();
+    }
+
+    /**
+     * Computes the max width if no such specified as an attribute.
+     */
+    private void tryComputeMaxWidth() {
+        if (!mComputeMaxWidth) {
+            return;
+        }
+        int maxTextWidth = 0;
+        if (mDisplayedValues == null) {
+            float maxDigitWidth = 0;
+            for (int i = 0; i <= 9; i++) {
+                final float digitWidth = mSelectorWheelPaint.measureText(String
+                        .valueOf(i));
+                if (digitWidth > maxDigitWidth) {
+                    maxDigitWidth = digitWidth;
+                }
+            }
+            int numberOfDigits = 0;
+            int current = mMaxValue;
+            while (current > 0) {
+                numberOfDigits++;
+                current = current / 10;
+            }
+            maxTextWidth = (int) (numberOfDigits * maxDigitWidth);
+        } else {
+            final int valueCount = mDisplayedValues.length;
+            for (int i = 0; i < valueCount; i++) {
+                final float textWidth = mSelectorWheelPaint
+                        .measureText(mDisplayedValues[i]);
+                if (textWidth > maxTextWidth) {
+                    maxTextWidth = (int) textWidth;
+                }
+            }
+        }
+//        maxTextWidth += mInputText.getPaddingLeft()
+//                + mInputText.getPaddingRight();
+        if (mMaxWidth != maxTextWidth) {
+            if (maxTextWidth > mMinWidth) {
+                mMaxWidth = maxTextWidth;
+            } else {
+                mMaxWidth = mMinWidth;
+            }
+            invalidate();
+        }
+    }
+
+    /**
+     * Gets whether the selector wheel wraps when reaching the min/max value.
+     *
+     * @return True if the selector wheel wraps.
+     *
+     * @see #getMinValue()
+     * @see #getMaxValue()
+     */
+    public boolean getWrapSelectorWheel() {
+        return mWrapSelectorWheel;
+    }
+
+    /**
+     * Sets whether the selector wheel shown during flinging/scrolling should
+     * wrap around the {@link NumberPicker#getMinValue()} and
+     * {@link NumberPicker#getMaxValue()} values.
+     * <p>
+     * By default if the range (max - min) is more than five (the number of
+     * items shown on the selector wheel) the selector wheel wrapping is
+     * enabled.
+     * </p>
+     *
+     * @param wrapSelectorWheel
+     *            Whether to wrap.
+     */
+    public void setWrapSelectorWheel(boolean wrapSelectorWheel) {
+        if (wrapSelectorWheel
+                && (mMaxValue - mMinValue) < mSelectorIndices.length) {
+            throw new IllegalStateException(
+                    "Range less than selector items count.");
+        }
+        if (wrapSelectorWheel != mWrapSelectorWheel) {
+            mWrapSelectorWheel = wrapSelectorWheel;
+            updateIncrementAndDecrementButtonsVisibilityState();
+        }
+    }
+
+    /**
+     * Sets the speed at which the numbers be incremented and decremented when
+     * the up and down buttons are long pressed respectively.
+     * <p>
+     * The default value is 300 ms.
+     * </p>
+     *
+     * @param intervalMillis
+     *            The speed (in milliseconds) at which the numbers will be
+     *            incremented and decremented.
+     */
+    public void setOnLongPressUpdateInterval(long intervalMillis) {
+        mLongPressUpdateInterval = intervalMillis;
+    }
+
+    /**
+     * Returns the value of the picker.
+     *
+     * @return The value.
+     */
+    public int getValue() {
+        return mValue;
+    }
+
+    /**
+     * Returns the min value of the picker.
+     *
+     * @return The min value
+     */
+    public int getMinValue() {
+        return mMinValue;
+    }
+
+    /**
+     * Sets the min value of the picker.
+     *
+     * @param minValue
+     *            The min value.
+     */
+    public void setMinValue(int minValue) {
+        if (mMinValue == minValue) {
+            return;
+        }
+        if (minValue < 0) {
+            throw new IllegalArgumentException("minValue must be >= 0");
+        }
+        mMinValue = minValue;
+        if (mMinValue > mValue) {
+            mValue = mMinValue;
+        }
+        boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length;
+        setWrapSelectorWheel(wrapSelectorWheel);
+        initializeSelectorWheelIndices();
+        updateInputTextView();
+        tryComputeMaxWidth();
+    }
+
+    /**
+     * Returns the max value of the picker.
+     *
+     * @return The max value.
+     */
+    public int getMaxValue() {
+        return mMaxValue;
+    }
+
+    /**
+     * Sets the max value of the picker.
+     *
+     * @param maxValue
+     *            The max value.
+     */
+    public void setMaxValue(int maxValue) {
+        if (mMaxValue == maxValue) {
+            return;
+        }
+        if (maxValue < 0) {
+            throw new IllegalArgumentException("maxValue must be >= 0");
+        }
+        mMaxValue = maxValue;
+        if (mMaxValue < mValue) {
+            mValue = mMaxValue;
+        }
+        boolean wrapSelectorWheel = mMaxValue - mMinValue > mSelectorIndices.length;
+        setWrapSelectorWheel(wrapSelectorWheel);
+        initializeSelectorWheelIndices();
+        tryComputeMaxWidth();
+    }
+
+    /**
+     * Gets the values to be displayed instead of string values.
+     *
+     * @return The displayed values.
+     */
+    public String[] getDisplayedValues() {
+        return mDisplayedValues;
+    }
+
+    /**
+     * Sets the values to be displayed.
+     *
+     * @param displayedValues
+     *            The displayed values.
+     */
+    public void setDisplayedValues(String[] displayedValues) {
+        if (mDisplayedValues == displayedValues) {
+            return;
+        }
+        mDisplayedValues = displayedValues;
+        if (mDisplayedValues != null) {
+            // Allow text entry rather than strictly numeric entry.
+//            mInputText.setRawInputType(InputType.TYPE_CLASS_TEXT
+//                    | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
+        } else {
+//            mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+        }
+//        updateInputTextView();
+        initializeSelectorWheelIndices();
+        tryComputeMaxWidth();
+    }
+    /**
+     * Sets the values to be displayed.If autoCalMinMax passed true, will calculate
+     * and set min value and max value.
+     *
+     * @param displayedValues
+     *            The displayed values.
+     * @param autoCalMinMax
+     *            Whether auto calculate and set the min value and max value.
+     */
+    public void setDisplayedValues(String[] displayeValues , boolean autoCalculateMinMax) {
+        if(autoCalculateMinMax){
+            mMinValue = 0;
+            mMaxValue = displayeValues.length - 1;
+        }
+        setDisplayedValues(displayeValues);
+    }
+
+    @Override
+    protected float getTopFadingEdgeStrength() {
+        return TOP_AND_BOTTOM_FADING_EDGE_STRENGTH;
+    }
+
+    @Override
+    protected float getBottomFadingEdgeStrength() {
+        return TOP_AND_BOTTOM_FADING_EDGE_STRENGTH;
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        // make sure we show the controls only the very
+        // first time the user sees this widget
+        if (mFlingable && !isInEditMode()) {
+            // animate a bit slower the very first time
+             showInputControls(mShowInputControlsAnimimationDuration * 2);
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        removeAllCallbacks();
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        // There is a good reason for doing this. See comments in draw().
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        // Dispatch draw to our children only if we are not currently running
+        // the animation for simultaneously dimming the scroll wheel and
+        // showing in the buttons. This class takes advantage of the View
+        // implementation of fading edges effect to draw the selector wheel.
+        // However, in View.draw(), the fading is applied after all the children
+        // have been drawn and we do not want this fading to be applied to the
+        // buttons. Therefore, we draw our children after we have completed
+        // drawing ourselves.
+        super.draw(canvas);
+
+//         Draw our children if we are not showing the selector wheel of fading
+//         it out
+//        if (mShowInputControlsAnimator.isRunning()
+//                || mSelectorWheelState != SELECTOR_WHEEL_STATE_LARGE) {
+//            long drawTime = getDrawingTime();
+//            for (int i = 0, count = getChildCount(); i < count; i++) {
+//                View child = getChildAt(i);
+//                if (!child.isShown()) {
+//                    continue;
+//                }
+//                drawChild(canvas, getChildAt(i), drawTime);
+//            }
+//        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (mSelectorWheelState == SELECTOR_WHEEL_STATE_NONE) {
+            return;
+        }
+
+        float x = 0.0f;
+        float y = 0.0f;
+        if (!mHorizontal) {
+            x = (mRight - mLeft) / 2;
+            y = mCurrentScrollOffset;
+        } else {
+            x = mCurrentScrollOffset;
+            y = (mBottom - mTop) / 2 + mTextSize/2;
+            if(Math.abs(mDensity - 1.5f) < 0.001f){
+                y += mHdpiPositionAdjust;
+            }
+        }
+
+
+        final int restoreCount = canvas.save();
+
+        if (mSelectorWheelState == SELECTOR_WHEEL_STATE_SMALL) {
+            Rect clipBounds = canvas.getClipBounds();
+            clipBounds.inset(0, mSelectorElementHeight);
+            canvas.clipRect(clipBounds);
+        }
+
+        // draw the selector wheel
+        int[] selectorIndices = mSelectorIndices;
+        for (int i = 0; i < selectorIndices.length; i++) {
+            int selectorIndex = selectorIndices[i];
+            String scrollSelectorValue = mSelectorIndexToStringCache
+                    .get(selectorIndex);
+                if(i - mSelectorMiddleItemIndex > 0 ){
+                    mSelectorWheelPaint.setColor(Color.WHITE);
+                    mSelectorWheelPaint.setAlpha((2*mSelectorMiddleItemIndex - i) * SELECTOR_TEXT_ALPHA_TRANSPARENT_NONE / mSelectorMiddleItemIndex);
+                }else if(i - mSelectorMiddleItemIndex < 0 ){
+                    mSelectorWheelPaint.setColor(Color.WHITE);
+                    mSelectorWheelPaint.setAlpha(i * SELECTOR_TEXT_ALPHA_TRANSPARENT_NONE / mSelectorMiddleItemIndex);
+                }else{
+                    mSelectorWheelPaint.setColor(Color.RED);
+                    mSelectorWheelPaint.setAlpha(SELECTOR_TEXT_ALPHA_TRANSPARENT_NONE);
+                }
+                float fNumber = Float.valueOf(scrollSelectorValue).floatValue();
+
+                boolean bShowNumber = false;
+                float fWidthOfScale = mScaleWidth ;
+                float fGapBetweenNumAndScale = mGapBetweenNumAndScale * mDensity;
+                float fScaleLength = mScaleLengthShort * mDensity;
+                //every 0.5MHz show number.
+                if((int)(fNumber * 100)%50 == 0 ){
+                    if(!(selectorIndex == getMaxValue())){
+                        bShowNumber = true;
+                        fScaleLength = mScaleLengthLong * mDensity;
+                    }
+                }
+                if(bShowNumber){
+                    canvas.drawText(scrollSelectorValue, x, y, mSelectorWheelPaint);
+                }
+                canvas.drawRect(x, y+fGapBetweenNumAndScale, x+fWidthOfScale, y + fGapBetweenNumAndScale + fScaleLength , mSelectorWheelPaint);
+
+//            }
+            if (mHorizontal) {
+                x += mSelectorElementWidth;
+            } else {
+                y += mSelectorElementHeight;
+            }
+        }
+        canvas.restoreToCount(restoreCount);
+    }
+
+    @Override
+    public void sendAccessibilityEvent(int eventType) {
+        // Do not send accessibility events - we want the user to
+        // perceive this widget as several controls rather as a whole.
+    }
+
+    /**
+     * Makes a measure spec that tries greedily to use the max value.
+     *
+     * @param measureSpec
+     *            The measure spec.
+     * @param maxSize
+     *            The max value for the size.
+     * @return A measure spec greedily imposing the max size.
+     */
+    private int makeMeasureSpec(int measureSpec, int maxSize) {
+        if (maxSize == SIZE_UNSPECIFIED) {
+            return measureSpec;
+        }
+        final int size = MeasureSpec.getSize(measureSpec);
+        final int mode = MeasureSpec.getMode(measureSpec);
+        switch (mode) {
+        case MeasureSpec.EXACTLY:
+            return measureSpec;
+        case MeasureSpec.AT_MOST:
+            return MeasureSpec.makeMeasureSpec(Math.min(size, maxSize),
+                    MeasureSpec.EXACTLY);
+        case MeasureSpec.UNSPECIFIED:
+            return MeasureSpec.makeMeasureSpec(maxSize, MeasureSpec.EXACTLY);
+        default:
+            throw new IllegalArgumentException("Unknown measure mode: " + mode);
+        }
+    }
+
+    /**
+     * Utility to reconcile a desired size and state, with constraints imposed
+     * by a MeasureSpec. Tries to respect the min size, unless a different size
+     * is imposed by the constraints.
+     *
+     * @param minSize
+     *            The minimal desired size.
+     * @param measuredSize
+     *            The currently measured size.
+     * @param measureSpec
+     *            The current measure spec.
+     * @return The resolved size and state.
+     */
+    private int resolveSizeAndStateRespectingMinSize(int minSize,
+            int measuredSize, int measureSpec) {
+        if (minSize != SIZE_UNSPECIFIED) {
+            final int desiredWidth = Math.max(minSize, measuredSize);
+            return resolveSizeAndState(desiredWidth, measureSpec, 0);
+        } else {
+            return measuredSize;
+        }
+    }
+
+    /**
+     * Resets the selector indices and clear the cached string representation of
+     * these indices.
+     */
+    private void initializeSelectorWheelIndices() {
+        mSelectorIndexToStringCache.clear();
+        int[] selectorIdices = mSelectorIndices;
+        int current = getValue();
+        for (int i = 0; i < mSelectorIndices.length; i++) {
+            int selectorIndex = current + (i - mSelectorMiddleItemIndex);
+            if (mWrapSelectorWheel) {
+                selectorIndex = getWrappedSelectorIndex(selectorIndex);
+            }
+            mSelectorIndices[i] = selectorIndex;
+            ensureCachedScrollSelectorValue(mSelectorIndices[i]);
+        }
+    }
+
+    /**
+     * Sets the current value of this NumberPicker, and sets mPrevious to the
+     * previous value. If current is greater than mEnd less than mStart, the
+     * value of mCurrent is wrapped around. Subclasses can override this to
+     * change the wrapping behavior
+     *
+     * @param current
+     *            the new value of the NumberPicker
+     */
+    private void changeCurrent(int current) {
+        if (mValue == current) {
+            return;
+        }
+        // Wrap around the values if we go past the start or end
+        if (mWrapSelectorWheel) {
+            current = getWrappedSelectorIndex(current);
+        }
+        int previous = mValue;
+        setValue(current);
+        notifyChange(previous, current);
+    }
+
+    /**
+     * Changes the current value by one which is increment or decrement based on
+     * the passes argument.
+     *
+     * @param increment
+     *            True to increment, false to decrement.
+     */
+    private void changeCurrentByOne(boolean increment) {
+        if (mFlingable) {
+            mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
+            mPreviousScrollerY = 0;
+            mPreviousScrollerX = 0;
+            forceCompleteChangeCurrentByOneViaScroll();
+            if (increment) {
+                if (mHorizontal) {
+                    mFlingScroller.startScroll(0, 0, -mSelectorElementHeight,
+                            0, CHANGE_CURRENT_BY_ONE_SCROLL_DURATION);
+                } else {
+                    mFlingScroller.startScroll(0, 0, 0,
+                            -mSelectorElementHeight,
+                            CHANGE_CURRENT_BY_ONE_SCROLL_DURATION);
+                }
+
+            } else {
+                if (mHorizontal) {
+                    mFlingScroller.startScroll(0, 0, mSelectorElementHeight, 0,
+                            CHANGE_CURRENT_BY_ONE_SCROLL_DURATION);
+                } else {
+                    mFlingScroller.startScroll(0, 0, 0, mSelectorElementHeight,
+                            CHANGE_CURRENT_BY_ONE_SCROLL_DURATION);
+                }
+
+            }
+            invalidate();
+        } else {
+            if (increment) {
+                changeCurrent(mValue + 1);
+            } else {
+                changeCurrent(mValue - 1);
+            }
+        }
+    }
+
+    /**
+     * Ensures that if we are in the process of changing the current value by
+     * one via scrolling the scroller gets to its final state and the value is
+     * updated.
+     */
+    private void forceCompleteChangeCurrentByOneViaScroll() {
+        Scroller scroller = mFlingScroller;
+        if (!scroller.isFinished()) {
+            if (mHorizontal) {
+                final int xBeforeAbort = scroller.getCurrX();
+                scroller.abortAnimation();
+                final int xDelta = scroller.getCurrX() - xBeforeAbort;
+                scrollBy(xDelta, 0);
+            } else {
+                final int yBeforeAbort = scroller.getCurrY();
+                scroller.abortAnimation();
+                final int yDelta = scroller.getCurrY() - yBeforeAbort;
+                scrollBy(0, yDelta);
+            }
+        }
+    }
+
+    /**
+     * Sets the <code>alpha</code> of the {@link Paint} for drawing the selector
+     * wheel.
+     */
+    @SuppressWarnings("unused")
+    // Called via reflection
+    private void setSelectorPaintAlpha(int alpha) {
+        mSelectorWheelPaint.setAlpha(alpha);
+        invalidate();
+    }
+
+    /**
+     * @return If the <code>event</code> is in the visible <code>view</code>.
+     */
+    private boolean isEventInVisibleViewHitRect(MotionEvent event, View view) {
+        if (view.getVisibility() == VISIBLE) {
+            view.getHitRect(mTempRect);
+            return mTempRect.contains((int) event.getX(), (int) event.getY());
+        }
+        return false;
+    }
+
+    /**
+     * Sets the <code>selectorWheelState</code>.
+     */
+    private void setSelectorWheelState(int selectorWheelState) {
+        mSelectorWheelState = selectorWheelState;
+        if (selectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
+            mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
+        }
+
+        if (mFlingable && selectorWheelState == SELECTOR_WHEEL_STATE_LARGE
+                && AccessibilityManager.getInstance(mContext).isEnabled()) {
+            AccessibilityManager.getInstance(mContext).interrupt();
+            String text = mContext
+                    .getString(R.string.number_picker_increment_scroll_action);
+        }
+    }
+
+    private void initializeSelectorWheel() {
+        initializeSelectorWheelIndices();
+        int[] selectorIndices = mSelectorIndices;
+        int totalTextHeight = selectorIndices.length * mTextSize;
+        int totalTextWidth = (selectorIndices.length - 1) * 2;
+        // set it horizontal
+        float totalTextGapHeight = (mBottom - mTop) - totalTextHeight;
+        float totalTextGapWidth = (mRight - mLeft) - totalTextWidth;
+
+        float textGapCount = selectorIndices.length - 1;
+        if (mHorizontal) {
+            mSelectorTextGapWidth = (int) (totalTextGapWidth / textGapCount);
+            Log.d(TAG,"mSelectorTextGapWidth :" + mSelectorTextGapWidth);
+            mSelectorElementWidth = 2 + mSelectorTextGapWidth;
+            mInitialScrollOffset = INIT_SCROLL_OFFSET_HORIZONTAL;
+        } else {
+            mSelectorTextGapHeight = (int) (totalTextGapHeight / textGapCount + 0.5f);
+            mSelectorElementHeight = mTextSize + mSelectorTextGapHeight;
+            mInitialScrollOffset = INIT_SCROLL_OFFSET_VERTICAL;
+        }
+        mCurrentScrollOffset = mInitialScrollOffset;
+
+    }
+
+    private void initializeFadingEdges() {
+        setVerticalFadingEdgeEnabled(true);
+        setFadingEdgeLength((mBottom - mTop - mTextSize) / 2);
+    }
+
+    /**
+     * Callback invoked upon completion of a given <code>scroller</code>.
+     */
+    private void onScrollerFinished(Scroller scroller) {
+
+        if(mOnScrollFinishListener != null){
+            mOnScrollFinishListener.onScrollFinish(mValue);
+        }
+        if (scroller == mFlingScroller) {
+            if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
+                postAdjustScrollerCommand(0);
+                onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
+            } else {
+//                 updateInputTextView();
+//                 fadeSelectorWheel(mShowInputControlsAnimimationDuration);
+            }
+        } else {
+//             updateInputTextView();
+//             showInputControls(mShowInputControlsAnimimationDuration);
+        }
+    }
+
+    /**
+     * Handles transition to a given <code>scrollState</code>
+     */
+    private void onScrollStateChange(int scrollState) {
+        if (mScrollState == scrollState) {
+            return;
+        }
+        mScrollState = scrollState;
+        if (mOnScrollListener != null) {
+
+            mOnScrollListener.onScrollStateChange(this, scrollState);
+        }
+    }
+
+    /**
+     * Flings the selector with the given <code>velocityY</code>.
+     */
+    private void fling(int velocity) {
+        mPreviousScrollerY = 0;
+        mPreviousScrollerX = 0;
+        int velocityY = velocity;
+        int velocityX = velocity;
+        if (mHorizontal) {
+            if (velocityX > 0) {
+                mFlingScroller.fling(0, 0, velocityX, 0, 0, Integer.MAX_VALUE,
+                        0, 0);
+            } else {
+                mFlingScroller.fling(Integer.MAX_VALUE, 0, velocityX, 0, 0,
+                        Integer.MAX_VALUE, 0, 0);
+            }
+        } else {
+            if (velocityY > 0) {
+                mFlingScroller.fling(0, 0, 0, velocityY, 0, 0, 0,
+                        Integer.MAX_VALUE);
+            } else {
+                mFlingScroller.fling(0, Integer.MAX_VALUE, 0, velocityY, 0, 0,
+                        0, Integer.MAX_VALUE);
+            }
+        }
+
+        invalidate();
+    }
+
+    /**
+     * Hides the input controls which is the up/down arrows and the text field.
+     */
+    private void hideInputControls() {
+        // mShowInputControlsAnimator.cancel();
+        // mIncrementButton.setVisibility(INVISIBLE);
+        // mDecrementButton.setVisibility(INVISIBLE);
+//        mInputText.setVisibility(INVISIBLE);
+    }
+
+    /**
+     * Show the input controls by making them visible and animating the alpha
+     * property up/down arrows.
+     *
+     * @param animationDuration
+     *            The duration of the animation.
+     */
+    private void showInputControls(long animationDuration) {
+//        updateIncrementAndDecrementButtonsVisibilityState();
+//         mInputText.setVisibility(VISIBLE);
+//         mShowInputControlsAnimator.setDuration(animationDuration);
+//         mShowInputControlsAnimator.start();
+    }
+
+    /**
+     * Fade the selector wheel via an animation.
+     *
+     * @param animationDuration
+     *            The duration of the animation.
+     */
+    // mark this 1
+    private void fadeSelectorWheel(long animationDuration) {
+//        mInputText.setVisibility(VISIBLE);
+//        mDimSelectorWheelAnimator.setDuration(animationDuration);
+//        mDimSelectorWheelAnimator.start();
+    }
+
+    /**
+     * Updates the visibility state of the increment and decrement buttons.
+     */
+    private void updateIncrementAndDecrementButtonsVisibilityState() {
+        if (mWrapSelectorWheel || mValue < mMaxValue) {
+            // mIncrementButton.setVisibility(VISIBLE);
+        } else {
+            // mIncrementButton.setVisibility(INVISIBLE);
+        }
+        if (mWrapSelectorWheel || mValue > mMinValue) {
+            // mDecrementButton.setVisibility(VISIBLE);
+        } else {
+            // mDecrementButton.setVisibility(INVISIBLE);
+        }
+    }
+
+    /**
+     * @return The wrapped index <code>selectorIndex</code> value.
+     */
+    private int getWrappedSelectorIndex(int selectorIndex) {
+        if (selectorIndex > mMaxValue) {
+            return mMinValue + (selectorIndex - mMaxValue)
+                    % (mMaxValue - mMinValue) - 1;
+        } else if (selectorIndex < mMinValue) {
+            return mMaxValue - (mMinValue - selectorIndex)
+                    % (mMaxValue - mMinValue) + 1;
+        }
+        return selectorIndex;
+    }
+
+    /**
+     * Increments the <code>selectorIndices</code> whose string representations
+     * will be displayed in the selector.
+     */
+    private void incrementSelectorIndices(int[] selectorIndices) {
+        for (int i = 0; i < selectorIndices.length - 1; i++) {
+            selectorIndices[i] = selectorIndices[i + 1];
+        }
+        int nextScrollSelectorIndex = selectorIndices[selectorIndices.length - 2] + 1;
+        if (mWrapSelectorWheel && nextScrollSelectorIndex > mMaxValue) {
+            nextScrollSelectorIndex = mMinValue;
+        }
+        selectorIndices[selectorIndices.length - 1] = nextScrollSelectorIndex;
+        ensureCachedScrollSelectorValue(nextScrollSelectorIndex);
+    }
+
+    /**
+     * Decrements the <code>selectorIndices</code> whose string representations
+     * will be displayed in the selector.
+     */
+    private void decrementSelectorIndices(int[] selectorIndices) {
+        for (int i = selectorIndices.length - 1; i > 0; i--) {
+            selectorIndices[i] = selectorIndices[i - 1];
+        }
+        int nextScrollSelectorIndex = selectorIndices[1] - 1;
+        if (mWrapSelectorWheel && nextScrollSelectorIndex < mMinValue) {
+            nextScrollSelectorIndex = mMaxValue;
+        }
+        selectorIndices[0] = nextScrollSelectorIndex;
+        ensureCachedScrollSelectorValue(nextScrollSelectorIndex);
+    }
+
+    /**
+     * Ensures we have a cached string representation of the given <code>
+     * selectorIndex</code>
+     * to avoid multiple instantiations of the same string.
+     */
+    private void ensureCachedScrollSelectorValue(int selectorIndex) {
+        SparseArray<String> cache = mSelectorIndexToStringCache;
+        String scrollSelectorValue = cache.get(selectorIndex);
+        if (scrollSelectorValue != null) {
+            return;
+        }
+        if (selectorIndex < mMinValue || selectorIndex > mMaxValue) {
+            scrollSelectorValue = "";
+        } else {
+            if (mDisplayedValues != null) {
+                int displayedValueIndex = selectorIndex - mMinValue;
+                scrollSelectorValue = mDisplayedValues[displayedValueIndex];
+            } else {
+                scrollSelectorValue = formatNumber(selectorIndex);
+            }
+        }
+        cache.put(selectorIndex, scrollSelectorValue);
+    }
+
+    private String formatNumber(int value) {
+        return (mFormatter != null) ? mFormatter.format(value) : String
+                .valueOf(value);
+    }
+
+    private void validateInputTextView(View v) {
+        String str = String.valueOf(((TextView) v).getText());
+        if (TextUtils.isEmpty(str)) {
+            // Restore to the old value as we don't allow empty values
+            updateInputTextView();
+        } else {
+            // Check the new value and ensure it's in range
+            int current = getSelectedPos(str.toString());
+            changeCurrent(current);
+        }
+    }
+
+    /**
+     * Updates the view of this NumberPicker. If displayValues were specified in
+     * the string corresponding to the index specified by the current value will
+     * be returned. Otherwise, the formatter specified in {@link #setFormatter}
+     * will be used to format the number.
+     */
+    private void updateInputTextView() {
+        /*
+         * If we don't have displayed values then use the current number else
+         * find the correct value in the displayed values for the current
+         * number.
+         */
+        // mark this 2
+        if (mDisplayedValues == null) {
+//            mInputText.setText(TWO_DIGIT_FORMATTER.format(mValue));
+        } else {
+//            mInputText.setText(mDisplayedValues[mValue - mMinValue]);
+        }
+//        mInputText.setSelection(mInputText.getText().length());
+
+        if (mFlingable
+                && AccessibilityManager.getInstance(mContext).isEnabled()) {
+//            String text = mContext.getString(
+//                    R.string.number_picker_increment_scroll_mode, mInputText
+//                            .getText());
+//            mInputText.setContentDescription(text);
+        }
+    }
+
+    /**
+     * Notifies the listener, if registered, of a change of the value of this
+     * NumberPicker.
+     */
+    private void notifyChange(int previous, int current) {
+        if (mOnValueChangeListener != null) {
+            mOnValueChangeListener.onValueChange(this, previous, mValue);
+        }
+    }
+
+    /**
+     * Posts a command for changing the current value by one.
+     *
+     * @param increment
+     *            Whether to increment or decrement the value.
+     */
+    private void postChangeCurrentByOneFromLongPress(boolean increment) {
+//        mInputText.clearFocus();
+        removeAllCallbacks();
+        if (mChangeCurrentByOneFromLongPressCommand == null) {
+            mChangeCurrentByOneFromLongPressCommand = new ChangeCurrentByOneFromLongPressCommand();
+        }
+        mChangeCurrentByOneFromLongPressCommand.setIncrement(increment);
+        post(mChangeCurrentByOneFromLongPressCommand);
+    }
+
+    /**
+     * Removes all pending callback from the message queue.
+     */
+    private void removeAllCallbacks() {
+        if (mChangeCurrentByOneFromLongPressCommand != null) {
+            removeCallbacks(mChangeCurrentByOneFromLongPressCommand);
+        }
+        if (mAdjustScrollerCommand != null) {
+            removeCallbacks(mAdjustScrollerCommand);
+        }
+        if (mSetSelectionCommand != null) {
+            removeCallbacks(mSetSelectionCommand);
+        }
+    }
+
+    /**
+     * @return The selected index given its displayed <code>value</code>.
+     */
+    private int getSelectedPos(String value) {
+        if (mDisplayedValues == null) {
+            try {
+                return Integer.parseInt(value);
+            } catch (NumberFormatException e) {
+                // Ignore as if it's not a number we don't care
+            }
+        } else {
+            for (int i = 0; i < mDisplayedValues.length; i++) {
+                // Don't force the user to type in jan when ja will do
+                value = value.toLowerCase();
+                if (mDisplayedValues[i].toLowerCase().startsWith(value)) {
+                    return mMinValue + i;
+                }
+            }
+
+            /*
+             * The user might have typed in a number into the month field i.e.
+             * 10 instead of OCT so support that too.
+             */
+            try {
+                return Integer.parseInt(value);
+            } catch (NumberFormatException e) {
+
+                // Ignore as if it's not a number we don't care
+            }
+        }
+        return mMinValue;
+    }
+
+    /**
+     * Posts an {@link SetSelectionCommand} from the given <code>selectionStart
+     * </code> to
+     * <code>selectionEnd</code>.
+     */
+    private void postSetSelectionCommand(int selectionStart, int selectionEnd) {
+        if (mSetSelectionCommand == null) {
+            mSetSelectionCommand = new SetSelectionCommand();
+        } else {
+            removeCallbacks(mSetSelectionCommand);
+        }
+        mSetSelectionCommand.mSelectionStart = selectionStart;
+        mSetSelectionCommand.mSelectionEnd = selectionEnd;
+        post(mSetSelectionCommand);
+    }
+
+    /**
+     * Posts an {@link AdjustScrollerCommand} within the given <code>
+     * delayMillis</code>
+     * .
+     */
+    private void postAdjustScrollerCommand(int delayMillis) {
+        if (mAdjustScrollerCommand == null) {
+            mAdjustScrollerCommand = new AdjustScrollerCommand();
+        } else {
+            removeCallbacks(mAdjustScrollerCommand);
+        }
+        postDelayed(mAdjustScrollerCommand, delayMillis);
+    }
+
+    /**
+     * Filter for accepting only valid indices or prefixes of the string
+     * representation of valid indices.
+     */
+    class InputTextFilter extends NumberKeyListener {
+
+        // XXX This doesn't allow for range limits when controlled by a
+        // soft input method!
+        public int getInputType() {
+            return InputType.TYPE_CLASS_TEXT;
+        }
+
+        @Override
+        protected char[] getAcceptedChars() {
+            return DIGIT_CHARACTERS;
+        }
+
+        @Override
+        public CharSequence filter(CharSequence source, int start, int end,
+                Spanned dest, int dstart, int dend) {
+            if (mDisplayedValues == null) {
+                CharSequence filtered = super.filter(source, start, end, dest,
+                        dstart, dend);
+                if (filtered == null) {
+                    filtered = source.subSequence(start, end);
+                }
+
+                String result = String.valueOf(dest.subSequence(0, dstart))
+                        + filtered + dest.subSequence(dend, dest.length());
+
+                if ("".equals(result)) {
+                    return result;
+                }
+                int val = getSelectedPos(result);
+
+                /*
+                 * Ensure the user can't type in a value greater than the max
+                 * allowed. We have to allow less than min as the user might
+                 * want to delete some numbers and then type a new number.
+                 */
+                if (val > mMaxValue) {
+                    return "";
+                } else {
+                    return filtered;
+                }
+            } else {
+                CharSequence filtered = String.valueOf(source.subSequence(
+                        start, end));
+                if (TextUtils.isEmpty(filtered)) {
+                    return "";
+                }
+                String result = String.valueOf(dest.subSequence(0, dstart))
+                        + filtered + dest.subSequence(dend, dest.length());
+                String str = String.valueOf(result).toLowerCase();
+                for (String val : mDisplayedValues) {
+                    String valLowerCase = val.toLowerCase();
+                    if (valLowerCase.startsWith(str)) {
+                        postSetSelectionCommand(result.length(), val.length());
+                        return val.subSequence(dstart, val.length());
+                    }
+                }
+                return "";
+            }
+        }
+    }
+
+    /**
+     * Command for setting the input text selection.
+     */
+    class SetSelectionCommand implements Runnable {
+        private int mSelectionStart;
+
+        private int mSelectionEnd;
+
+        public void run() {
+//            mInputText.setSelection(mSelectionStart, mSelectionEnd);
+        }
+    }
+
+    /**
+     * Command for adjusting the scroller to show in its center the closest of
+     * the displayed items.
+     */
+    class AdjustScrollerCommand implements Runnable {
+        public void run() {
+            mPreviousScrollerY = 0;
+            mPreviousScrollerX = 0;
+            if (mInitialScrollOffset == mCurrentScrollOffset) {
+                return;
+            }
+            if (mHorizontal) {
+                // adjust to the closest value
+                int deltaX = mInitialScrollOffset - mCurrentScrollOffset;
+                mAdjustScroller.startScroll(0, 0, deltaX, 0,
+                        SELECTOR_ADJUSTMENT_DURATION_MILLIS);
+            } else {
+                // adjust to the closest value
+                int deltaY = mInitialScrollOffset - mCurrentScrollOffset;
+                if (Math.abs(deltaY) > mSelectorElementHeight / 2) {
+                    deltaY += (deltaY > 0) ? -mSelectorElementHeight
+                            : mSelectorElementHeight;
+                }
+                mAdjustScroller.startScroll(0, 0, 0, deltaY,
+                        SELECTOR_ADJUSTMENT_DURATION_MILLIS);
+            }
+
+            invalidate();
+        }
+    }
+
+    /**
+     * Command for changing the current value from a long press by one.
+     */
+    class ChangeCurrentByOneFromLongPressCommand implements Runnable {
+        private boolean mIncrement;
+
+        private void setIncrement(boolean increment) {
+            mIncrement = increment;
+        }
+
+        public void run() {
+            changeCurrentByOne(mIncrement);
+            postDelayed(this, mLongPressUpdateInterval);
+        }
+    }
+}
diff --git a/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl b/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl
new file mode 100644
index 0000000..7358149
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl
@@ -0,0 +1,57 @@
+package com.caf.fmradio;
+
+import com.caf.fmradio.IFMRadioServiceCallbacks;
+
+interface IFMRadioService
+{
+    boolean fmOn();
+    boolean fmOff();
+    boolean fmRadioReset();
+    boolean isFmOn();
+    boolean isAnalogModeEnabled();
+    boolean isFmRecordingOn();
+    boolean isSpeakerEnabled();
+    boolean fmReconfigure();
+    void registerCallbacks(IFMRadioServiceCallbacks cb);
+    void unregisterCallbacks();
+    boolean mute();
+    boolean routeAudio(int device);
+    boolean unMute();
+    boolean isMuted();
+    boolean startRecording();
+    void stopRecording();
+    boolean tune(int frequency);
+    boolean seek(boolean up);
+    void enableSpeaker(boolean speakerOn);
+    boolean scan(int pty);
+    boolean seekPI(int piCode);
+    boolean searchStrongStationList(int numStations);
+    int[]   getSearchList();
+    boolean cancelSearch();
+    String getProgramService();
+    String getRadioText();
+    int getProgramType();
+    int getProgramID();
+    boolean setLowPowerMode(boolean bLowPower);
+    int getPowerMode();
+    boolean enableAutoAF(boolean bEnable);
+    boolean enableStereo(boolean bEnable);
+    boolean isAntennaAvailable();
+    boolean isWiredHeadsetAvailable();
+    boolean isCallActive();
+    int getRssi();
+    int getIoC();
+    int getMpxDcc();
+    int getIntDet();
+    int getSINR();
+    void setHiLoInj(int inj);
+    void delayedStop(long nDuration, int nType);
+    void cancelDelayedStop (int nType);
+    void requestFocus();
+    boolean setSinrSamplesCnt(int samplesCnt);
+    boolean setSinrTh(int sinr);
+    boolean setIntfDetLowTh(int intfLowTh);
+    boolean setIntfDetHighTh(int intfHighTh);
+    String getExtenRadioText();
+}
+
diff --git a/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl b/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl
new file mode 100644
index 0000000..1926f24
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+interface IFMRadioServiceCallbacks
+{
+  void onEnabled();
+  void onDisabled();
+  void onRadioReset();
+  void onTuneStatusChanged();
+  void onProgramServiceChanged();
+  void onRadioTextChanged();
+  void onAlternateFrequencyChanged();
+  void onSignalStrengthChanged();
+  void onSearchComplete();
+  void onSearchListComplete();
+  void onMute(boolean bMuted);
+  void onAudioUpdate(boolean bStereo);
+  void onStationRDSSupported(boolean bRDSSupported);
+  void onRecordingStopped();
+  void onExtenRadioTextChanged();
+}
diff --git a/fmapp2/src/com/caf/fmradio/IFMTransmitterService.aidl b/fmapp2/src/com/caf/fmradio/IFMTransmitterService.aidl
new file mode 100644
index 0000000..79e01de
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/IFMTransmitterService.aidl
@@ -0,0 +1,23 @@
+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/IFMTransmitterServiceCallbacks.aidl b/fmapp2/src/com/caf/fmradio/IFMTransmitterServiceCallbacks.aidl
new file mode 100644
index 0000000..641785d
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/IFMTransmitterServiceCallbacks.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009,2012-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;
+
+interface IFMTransmitterServiceCallbacks
+{
+  void onEnabled(boolean bStatus);
+  void onDisabled();
+  void onRadioReset();
+  void onTuneStatusChanged(int frequency);
+  void onRadioTextChanged();
+  void onSearchListComplete(boolean bStatus);
+  void onReconfigured();
+  void onMetaDataChanged(String str);
+  void onPSInfoSent(String str);
+}
diff --git a/fmapp2/src/com/caf/fmradio/PresetList.java b/fmapp2/src/com/caf/fmradio/PresetList.java
new file mode 100644
index 0000000..b1a0214
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/PresetList.java
@@ -0,0 +1,323 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.List;
+
+public class PresetList{
+    private    List<PresetStation> mPresetList = new ArrayList<PresetStation>();
+    private    int mCurrentStation = 0;
+    private    String mListName = "";
+
+    public PresetList(String name) {
+        mListName = name;
+    }
+
+    public String getName(){
+        return mListName;
+    }
+
+    public String toString(){
+        return mListName;
+    }
+
+    public synchronized int getStationCount(){
+        return mPresetList.size();
+    }
+
+    public synchronized String getStationName(int stationNum){
+        String name = "";
+        if (mPresetList.size() > stationNum){
+            name = mPresetList.get(stationNum).getName();
+        }
+        return name;
+    }
+
+    public synchronized int getStationFrequency(int stationNum){
+        int frequency = 102100;
+        if (mPresetList.size() > stationNum){
+            frequency = mPresetList.get(stationNum).getFrequency();
+        }
+        return frequency;
+    }
+
+    public void setName(String name){
+        mListName = name;
+    }
+
+    public synchronized void setStationFrequency(int stationNum, int frequency){
+        PresetStation mStation = mPresetList.get(stationNum);
+        mStation.setFrequency(frequency);
+    }
+
+    public synchronized void setStationName(int stationNum, String name){
+        PresetStation mStation = mPresetList.get(stationNum);
+        mStation.setName(name);
+    }
+
+    public synchronized PresetStation getStationFromIndex(int index){
+        int totalPresets = mPresetList.size();
+        PresetStation station = null;
+        if (index < totalPresets) {
+            station = mPresetList.get(index);
+        }
+        return station;
+    }
+
+    public synchronized PresetStation getStationFromFrequency(int frequency){
+        int totalPresets = mPresetList.size();
+        for (int presetNum = 0; presetNum < totalPresets; presetNum++ ) {
+            PresetStation station = mPresetList.get(presetNum);
+            if (station != null) {
+                if(frequency == station.getFrequency()) {
+                    return station;
+                }
+            }
+        }
+        return null;
+    }
+
+    public synchronized PresetStation addStation(String name, int freq){
+        PresetStation addStation = new PresetStation(name, freq);
+        if(addStation != null) {
+            mPresetList.add(addStation);
+        }
+        return addStation;
+    }
+
+    public synchronized PresetStation addStation(PresetStation station){
+        PresetStation addStation = null;
+        if(station != null) {
+            addStation = new PresetStation (station);
+            mPresetList.add(addStation);
+        }
+        return addStation;
+    }
+
+    public synchronized void removeStation(int index){
+       int totalPresets = mPresetList.size();
+       if((index >= 0) && (index < totalPresets))
+       {
+          mPresetList.remove(index);
+       }
+    }
+
+    public synchronized void removeStation(PresetStation station){
+       int index = mPresetList.indexOf(station);
+       int totalPresets = mPresetList.size();
+       if((index >= 0) && (index < totalPresets))
+       {
+          mPresetList.remove(index);
+       }
+    }
+    public synchronized void clear(){
+        mPresetList.clear();
+    }
+
+    /* If a user selects a new station in this list, this routine will be called to
+     * to update the list.
+     */
+    public synchronized boolean setSelectedStation(PresetStation selectStation){
+        int totalPresets = mPresetList.size();
+        if (selectStation != null) {
+            for (int presetNum = 0; presetNum < totalPresets; presetNum++ ) {
+                PresetStation station = mPresetList.get(presetNum);
+                if (station != null) {
+                    if(selectStation.getFrequency() == station.getFrequency()) {
+                        if(selectStation.getName().equalsIgnoreCase(station.getName())) {
+                            mCurrentStation = presetNum;
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /* Check if the same station already exists in a List
+     * to update the list.
+     */
+    public synchronized boolean sameStationExists(PresetStation compareStation){
+        int totalPresets = mPresetList.size();
+        if (compareStation != null) {
+            for (int presetNum = 0; presetNum < totalPresets; presetNum++ ) {
+                PresetStation station = mPresetList.get(presetNum);
+                if (station != null) {
+                    if(compareStation.getFrequency() == station.getFrequency()) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /* If a user selects a new station in this list, this routine will be called to
+     * to update the list.
+     */
+    public synchronized boolean setSelectedStation(int stationIndex){
+        boolean foundStation = false;
+        int totalPresets = mPresetList.size();
+        if (stationIndex < totalPresets) {
+            mCurrentStation = stationIndex;
+            foundStation = true;
+        }
+        return foundStation;
+    }
+
+    public synchronized PresetStation getSelectedStation(){
+        int totalPresets = mPresetList.size();
+        PresetStation station = null;
+        if (mCurrentStation < totalPresets) {
+            station = mPresetList.get(mCurrentStation);
+        }
+        return station;
+    }
+
+    public synchronized PresetStation selectNextStation(){
+        int totalPresets = mPresetList.size();
+        PresetStation station = null;
+        if(totalPresets > 0) {
+            mCurrentStation ++;
+            if ( (mCurrentStation) >= totalPresets) {
+                mCurrentStation =0;
+            }
+            station = mPresetList.get(mCurrentStation);
+        }
+        return station;
+    }
+
+    public synchronized PresetStation selectPrevStation(){
+        int totalPresets = mPresetList.size();
+        PresetStation station = null;
+        if(totalPresets > 0) {
+            mCurrentStation --;
+            if ( mCurrentStation < 0) {
+                mCurrentStation = totalPresets-1;
+            }
+            station = mPresetList.get(mCurrentStation);
+        }
+        return station;
+    }
+
+    public synchronized void selectStation(PresetStation selectStation){
+        int totalPresets = mPresetList.size();
+        if (selectStation != null) {
+            for (int presetNum = 0; presetNum < totalPresets; presetNum++ ) {
+                PresetStation station = mPresetList.get(presetNum);
+                if (station != null) {
+                    if(selectStation.getFrequency() == station.getFrequency()) {
+                        mCurrentStation    = presetNum;
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    /* Test Code */
+    public void addDummyStations() {
+        PresetStation station;
+        int freq;
+        String name ;
+        int pty ;
+
+        mPresetList.clear();
+        freq = 89500;
+        name = "KPBS";
+        pty = 22; //public
+        station = addStation(name, freq);
+        if(station != null) {
+            station.setPty(pty);
+            station.setPI(0);
+            station.setRDSSupported(false);
+        }
+
+        freq = 96500;
+        name = "KYXY";
+        //pty = "Soft Rock";
+        pty = 8;
+
+        station = addStation(name, freq);
+        if(station != null) {
+            station.setPty(pty);
+            station.setPI(0);
+            station.setRDSSupported(false);
+        }
+
+        freq = 98100;
+        name = "KIFM";
+        //pty = "Smooth Jazz";
+        pty = 14;
+
+        station = addStation(name, freq);
+        if(station != null) {
+            station.setPty(pty);
+            station.setPI(0);
+            station.setRDSSupported(false);
+        }
+
+        freq = 101500;
+        name = "KGB";
+        //pty = "Classic Rock";
+        pty = 6;
+
+        station = addStation(name, freq);
+        if(station != null) {
+            station.setPty(pty);
+            station.setPI(0);
+            station.setRDSSupported(false);
+        }
+
+        freq = 102100;
+        name = "KPRI";
+        //pty = "Rock";
+        pty = 5;
+        station = addStation(name, freq);
+        if(station != null) {
+            station.setPty(pty);
+            station.setPI(0);
+            station.setRDSSupported(true);
+        }
+
+        freq = 105300;
+        name = "KIOZ";
+        //pty = "Rock";
+        pty = 5;
+        station = addStation(name, freq);
+        if(station != null) {
+            station.setPty(pty);
+            station.setPI(0);
+            station.setRDSSupported(true);
+        }
+    }
+
+}
diff --git a/fmapp2/src/com/caf/fmradio/PresetStation.java b/fmapp2/src/com/caf/fmradio/PresetStation.java
new file mode 100644
index 0000000..77bf648
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/PresetStation.java
@@ -0,0 +1,951 @@
+/*
+ * 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 qcom.fmradio.FmReceiver;
+
+import android.text.TextUtils;
+//import android.util.Log;
+
+public class PresetStation
+{
+   private String mName = "";
+   private int mFrequency = 102100;
+   private int mPty = 0;
+   private int mPI = 0;
+   private String mPtyStr = "";
+   private String mPIStr = "";
+   private boolean  mRDSSupported = false;
+
+   public PresetStation(String name, int frequency) {
+           mName = name;
+      /*
+       *  setFrequency set the name to
+       *  "Frequency" String if Name is empty
+       */
+      setFrequency(frequency);
+   }
+
+   public PresetStation(PresetStation station) {
+      Copy(station);
+      /*
+       *  setFrequency set the name to
+       *  "Frequency" String if Name is empty
+       */
+      setFrequency(station.getFrequency());
+   }
+
+   public void Copy(PresetStation station) {
+      /* Let copy just do a copy
+       * without any manipulation
+       */
+      mName = station.getName();
+      mFrequency = station.getFrequency();
+      mPI = station.getPI();
+      mPty = station.getPty();
+      mRDSSupported = station.getRDSSupported();
+
+      mPtyStr = station.getPtyString();
+      mPIStr = station.getPIString();
+   }
+
+   public boolean equals(PresetStation station) {
+      boolean equal = false;
+      if (mFrequency == station.getFrequency())
+      {
+         if (mPty == (station.getPty()))
+         {
+            if (mPI == (station.getPI()))
+            {
+               if (mRDSSupported == (station.getRDSSupported()))
+               {
+                  equal = true;
+               }
+            }
+         }
+      }
+      return equal;
+   }
+
+   public void setName(String name){
+      if (!TextUtils.isEmpty(name) &&!TextUtils.isEmpty(name.trim()))
+      {
+         mName = name;
+      } else
+      {
+         mName = ""+mFrequency/1000.0;
+      }
+   }
+
+   public void setFrequency(int freq){
+      mFrequency = freq;
+      /* If no name set it to the frequency */
+      if (TextUtils.isEmpty(mName))
+      {
+         mName = ""+mFrequency/1000.0;
+      }
+      return;
+   }
+
+   public void setPty(int pty){
+      mPty = pty;
+      mPtyStr = PresetStation.parsePTY(mPty);
+   }
+
+   public void setPI(int pi){
+      mPI = pi;
+      mPIStr = PresetStation.parsePI(mPI);
+   }
+
+   public void setRDSSupported(boolean rds){
+      mRDSSupported = rds;
+   }
+
+   public String getName(){
+      return mName;
+   }
+
+   public int getFrequency(){
+      return mFrequency;
+   }
+
+   /**
+    * Routine to get the Frequency in String from an integer
+    *
+    * @param frequency : Frequency to be converted (ex: 96500)
+    *
+    * @return String : Frequency in String form (ex: 96.5)
+    */
+   public static String getFrequencyString(int frequency) {
+          double frequencyDbl = frequency / 1000.0;
+      String frequencyString =""+frequencyDbl;
+      return frequencyString;
+   }
+
+   public int getPty(){
+      return mPty;
+   }
+
+   public String getPtyString(){
+      return mPtyStr;
+   }
+
+   public int getPI(){
+      return mPI;
+   }
+
+   public String getPIString(){
+      return mPIStr;
+   }
+
+   public boolean getRDSSupported(){
+      return mRDSSupported;
+   }
+
+   /** Routine parses the PI Code from Integer to Call Sign String
+    *  Example: 0x54A6 -> KZZY
+    */
+   public static String parsePI(int piCode)
+   {
+      String callSign = "";
+      if ( (piCode >> 8) == 0xAF)
+      {//CALL LETTERS THAT MAP TO PI CODES = _ _ 0 0.
+         piCode = ((piCode & 0xFF) << 8);
+      }
+      /* Run the second exception
+         NOTE: For 9 special cases 1000,2000,..,9000 a double mapping
+         occurs utilizing exceptions 1 and 2:
+         1000->A100->AFA1;2000->A200->AFA2; ... ;
+         8000->A800->AFA8;9000->A900->AFA9
+      */
+      if ( (piCode >> 12) == 0xA)
+      {//CALL LETTERS THAT MAP TO PI CODES = _ 0 _ _.
+         piCode = ((piCode & 0xF00) << 4) + (piCode & 0xFF);
+      }
+      if ( (piCode >= 0x1000) && (piCode <= 0x994E))
+      {
+         String ShartChar;
+         /* KAAA - KZZZ */
+         if ( (piCode >= 0x1000) && (piCode <= 0x54A7))
+         {
+            piCode -= 0x1000;
+            ShartChar = "K";
+         } else
+         { /* WAAA - WZZZ*/
+            piCode -= 0x54A8;
+            ShartChar = "W";
+         }
+         int CharDiv = piCode / 26;
+         int CharPos = piCode - (CharDiv * 26);
+         char c3 = (char)('A'+CharPos);
+
+         piCode = CharDiv;
+         CharDiv = piCode / 26;
+         CharPos = piCode - (CharDiv * 26);
+         char c2 = (char)('A'+CharPos);
+
+         piCode = CharDiv;
+         CharDiv = piCode / 26;
+         CharPos = piCode - (CharDiv * 26);
+         char c1 = (char)('A'+CharPos);
+         callSign = ShartChar + c1+ c2+ c3;
+      } else if ( (piCode >= 0x9950) && (piCode <= 0x9EFF))
+      {//3-LETTER-ONLY CALL LETTERS
+         callSign = get3LetterCallSign(piCode);
+      } else
+      {//NATIONALLY-LINKED RADIO STATIONS CARRYING DIFFERENT CALL LETTERS
+         callSign = getOtherCallSign(piCode);
+      }
+      return callSign;
+   }
+
+   private static String getOtherCallSign(int piCode)
+   {
+      String callSign = "";
+      if ( (piCode >= 0xB001) && (piCode <= 0xBF01))
+      {
+         callSign = "NPR";
+      } else if ( (piCode >= 0xB002) && (piCode <= 0xBF02))
+      {
+         callSign = "CBC English";
+      } else if ( (piCode >= 0xB003) && (piCode <= 0xBF03))
+      {
+         callSign = "CBC French";
+      }
+      return callSign;
+   }
+
+   private static String get3LetterCallSign(int piCode)
+   {
+      String callSign = "";
+      switch (piCode)
+      {
+      case 0x99A5:
+         {
+            callSign = "KBW";
+            break;
+         }
+      case 0x9992:
+         {
+            callSign = "KOY";
+            break;
+         }
+      case 0x9978:
+         {
+            callSign = "WHO";
+            break;
+         }
+      case 0x99A6:
+         {
+            callSign = "KCY";
+            break;
+         }
+      case 0x9993:
+         {
+            callSign = "KPQ";
+            break;
+         }
+      case 0x999C:
+         {
+            callSign = "WHP";
+            break;
+         }
+      case 0x9990:
+         {
+            callSign = "KDB";
+            break;
+         }
+      case 0x9964:
+         {
+            callSign = "KQV";
+            break;
+         }
+      case 0x999D:
+         {
+            callSign = "WIL";
+            break;
+         }
+      case 0x99A7:
+         {
+            callSign = "KDF";
+            break;
+         }
+      case 0x9994:
+         {
+            callSign = "KSD";
+            break;
+         }
+      case 0x997A:
+         {
+            callSign = "WIP";
+            break;
+         }
+      case 0x9950:
+         {
+            callSign = "KEX";
+            break;
+         }
+      case 0x9965:
+         {
+            callSign = "KSL";
+            break;
+         }
+      case 0x99B3:
+         {
+            callSign = "WIS";
+            break;
+         }
+      case 0x9951:
+         {
+            callSign = "KFH";
+            break;
+         }
+      case 0x9966:
+         {
+            callSign = "KUJ";
+            break;
+         }
+      case 0x997B:
+         {
+            callSign = "WJR";
+            break;
+         }
+      case 0x9952:
+         {
+            callSign = "KFI";
+            break;
+         }
+      case 0x9995:
+         {
+            callSign = "KUT";
+            break;
+         }
+      case 0x99B4:
+         {
+            callSign = "WJW";
+            break;
+         }
+      case 0x9953:
+         {
+            callSign = "KGA";
+            break;
+         }
+      case 0x9967:
+         {
+            callSign = "KVI";
+            break;
+         }
+      case 0x99B5:
+         {
+            callSign = "WJZ";
+            break;
+         }
+      case 0x9991:
+         {
+            callSign = "KGB";
+            break;
+         }
+      case 0x9968:
+         {
+            callSign = "KWG";
+            break;
+         }
+      case 0x997C:
+         {
+            callSign = "WKY";
+            break;
+         }
+      case 0x9954:
+         {
+            callSign = "KGO";
+            break;
+         }
+      case 0x9996:
+         {
+            callSign = "KXL";
+            break;
+         }
+      case 0x997D:
+         {
+            callSign = "WLS";
+            break;
+         }
+      case 0x9955:
+         {
+            callSign = "KGU";
+            break;
+         }
+      case 0x9997:
+         {
+            callSign = "KXO";
+            break;
+         }
+      case 0x997E:
+         {
+            callSign = "WLW";
+            break;
+         }
+      case 0x9956:
+         {
+            callSign = "KGW";
+            break;
+         }
+      case 0x996B:
+         {
+            callSign = "KYW";
+            break;
+         }
+      case 0x999E:
+         {
+            callSign = "WMC";
+            break;
+         }
+      case 0x9957:
+         {
+            callSign = "KGY";
+            break;
+         }
+      case 0x9999:
+         {
+            callSign = "WBT";
+            break;
+         }
+      case 0x999F:
+         {
+            callSign = "WMT";
+            break;
+         }
+      case 0x99AA:
+         {
+            callSign = "KHQ";
+            break;
+         }
+      case 0x996D:
+         {
+            callSign = "WBZ";
+            break;
+         }
+      case 0x9981:
+         {
+            callSign = "WOC";
+            break;
+         }
+      case 0x9958:
+         {
+            callSign = "KID";
+            break;
+         }
+      case 0x996E:
+         {
+            callSign = "WDZ";
+            break;
+         }
+      case 0x99A0:
+         {
+            callSign = "WOI";
+            break;
+         }
+      case 0x9959:
+         {
+            callSign = "KIT";
+            break;
+         }
+      case 0x996F:
+         {
+            callSign = "WEW";
+            break;
+         }
+      case 0x9983:
+         {
+            callSign = "WOL";
+            break;
+         }
+      case 0x995A:
+         {
+            callSign = "KJR";
+            break;
+         }
+      case 0x999A:
+         {
+            callSign = "WGH";
+            break;
+         }
+      case 0x9984:
+         {
+            callSign = "WOR";
+            break;
+         }
+      case 0x995B:
+         {
+            callSign = "KLO";
+            break;
+         }
+      case 0x9971:
+         {
+            callSign = "WGL";
+            break;
+         }
+      case 0x99A1:
+         {
+            callSign = "WOW";
+            break;
+         }
+      case 0x995C:
+         {
+            callSign = "KLZ";
+            break;
+         }
+      case 0x9972:
+         {
+            callSign = "WGN";
+            break;
+         }
+      case 0x99B9:
+         {
+            callSign = "WRC";
+            break;
+         }
+      case 0x995D:
+         {
+            callSign = "KMA";
+            break;
+         }
+      case 0x9973:
+         {
+            callSign = "WGR";
+            break;
+         }
+      case 0x99A2:
+         {
+            callSign = "WRR";
+            break;
+         }
+      case 0x995E:
+         {
+            callSign = "KMJ";
+            break;
+         }
+      case 0x999B:
+         {
+            callSign = "WGY";
+            break;
+         }
+      case 0x99A3:
+         {
+            callSign = "WSB";
+            break;
+         }
+      case 0x995F:
+         {
+            callSign = "KNX";
+            break;
+         }
+      case 0x9975:
+         {
+            callSign = "WHA";
+            break;
+         }
+      case 0x99A4:
+         {
+            callSign = "WSM";
+            break;
+         }
+      case 0x9960:
+         {
+            callSign = "KOA";
+            break;
+         }
+      case 0x9976:
+         {
+            callSign = "WHB";
+            break;
+         }
+      case 0x9988:
+         {
+            callSign = "WWJ";
+            break;
+         }
+      case 0x99AB:
+         {
+            callSign = "KOB";
+            break;
+         }
+      case 0x9977:
+         {
+            callSign = "WHK";
+            break;
+         }
+      case 0x9989:
+         {
+            callSign = "WWL";
+            break;
+         }
+      }
+      return callSign;
+   }
+
+   /**
+    *  Get the Text String for the Program type Code
+    */
+   public static String parsePTY(int pty)
+   {
+      String ptyStr="";
+      int rdsStd = FmSharedPreferences.getFMConfiguration().getRdsStd();
+      if(rdsStd ==  FmReceiver.FM_RDS_STD_RBDS)
+      {
+         ptyStr = getRBDSPtyString(pty);
+      }
+      else if(rdsStd ==  FmReceiver.FM_RDS_STD_RDS)
+      {
+         ptyStr = getRDSPtyString(pty);
+      }
+      return (ptyStr);
+   }
+
+   /**
+    *  get the Text String for the RBDS Program type Code
+    */
+   public static String getRBDSPtyString(int pty)
+   {
+      String ptyStr = "";
+      switch (pty)
+      {
+         case 1:
+         {
+            ptyStr = "News";
+            break;
+         }
+         case 2:
+         {
+            ptyStr = "Information";
+            break;
+         }
+         case 3:
+         {
+            ptyStr = "Sports";
+            break;
+         }
+         case 4:
+         {
+            ptyStr = "Talk";
+            break;
+         }
+         case 5:
+         {
+            ptyStr = "Rock";
+            break;
+         }
+         case 6:
+         {
+            ptyStr = "Classic Rock";
+            break;
+         }
+         case 7:
+         {
+            ptyStr = "Adult Hits";
+            break;
+         }
+         case 8:
+         {
+            ptyStr = "Soft Rock";
+            break;
+         }
+         case 9:
+         {
+            ptyStr = "Top 40";
+            break;
+         }
+         case 10:
+         {
+            ptyStr = "Country";
+            break;
+         }
+         case 11:
+         {
+            ptyStr = "Oldies";
+            break;
+         }
+         case 12:
+         {
+            ptyStr = "Soft";
+            break;
+         }
+         case 13:
+         {
+            ptyStr = "Nostalgia";
+            break;
+         }
+         case 14:
+         {
+            ptyStr = "Jazz";
+            break;
+         }
+         case 15:
+         {
+            ptyStr = "Classical";
+            break;
+         }
+         case 16:
+         {
+            ptyStr = "Rhythm and Blues";
+            break;
+         }
+         case 17:
+         {
+            ptyStr = "Soft Rhythm and Blues";
+            break;
+         }
+         case 18:
+         {
+            ptyStr = "Foreign Language";
+            break;
+         }
+         case 19:
+         {
+            ptyStr = "Religious Music";
+            break;
+         }
+         case 20:
+         {
+            ptyStr = "Religious Talk";
+            break;
+         }
+         case 21:
+         {
+            ptyStr = "Personality";
+            break;
+         }
+         case 22:
+         {
+            ptyStr = "Public";
+            break;
+         }
+         case 23:
+         {
+            ptyStr = "College";
+            break;
+         }
+         case 29:
+         {
+            ptyStr = "Weather";
+            break;
+         }
+         case 30:
+         {
+            ptyStr = "Emergency Test";
+            break;
+         }
+         case 31:
+         {
+            ptyStr = "Emergency";
+            break;
+         }
+         default:
+         {
+            ptyStr = "";
+            //Log.e(FMRadio.LOGTAG, "Unknown RBDS ProgramType [" + pty + "]");
+            break;
+         }
+      }
+      return ptyStr;
+   }
+
+   /** get the Text String for the Program type Code */
+   public static String getRDSPtyString(int pty)
+   {
+      String ptyStr = "";
+      switch (pty)
+      {
+         case 1:
+         {
+            ptyStr = "News";
+            break;
+         }
+         case 2:
+         {
+            ptyStr = "Current Affairs";
+            break;
+         }
+         case 3:
+         {
+            ptyStr = "Information";
+            break;
+         }
+         case 4:
+         {
+            ptyStr = "Sport";
+            break;
+         }
+         case 5:
+         {
+            ptyStr = "Education";
+            break;
+         }
+         case 6:
+         {
+            ptyStr = "Drama";
+            break;
+         }
+         case 7:
+         {
+            ptyStr = "Culture";
+            break;
+         }
+         case 8:
+         {
+            ptyStr = "Science";
+            break;
+         }
+         case 9:
+         {
+            ptyStr = "Varied";
+            break;
+         }
+         case 10:
+         {
+            ptyStr = "Pop Music";
+            break;
+         }
+         case 11:
+         {
+            ptyStr = "Rock Music";
+            break;
+         }
+         case 12:
+         {
+            ptyStr = "Easy Listening Music";
+            break;
+         }
+         case 13:
+         {
+            ptyStr = "Light classical";
+            break;
+         }
+         case 14:
+         {
+            ptyStr = "Serious classical";
+            break;
+         }
+         case 15:
+         {
+            ptyStr = "Other Music";
+            break;
+         }
+         case 16:
+         {
+            ptyStr = "Weather";
+            break;
+         }
+         case 17:
+         {
+            ptyStr = "Finance";
+            break;
+         }
+         case 18:
+         {
+            ptyStr = "Children programs";
+            break;
+         }
+         case 19:
+         {
+            ptyStr = "Social Affairs";
+            break;
+         }
+         case 20:
+         {
+            ptyStr = "Religion";
+            break;
+         }
+         case 21:
+         {
+            ptyStr = "Phone In";
+            break;
+         }
+         case 22:
+         {
+            ptyStr = "Travel";
+            break;
+         }
+         case 23:
+         {
+            ptyStr = "Leisure";
+            break;
+         }
+         case 24:
+         {
+            ptyStr = "Jazz Music";
+            break;
+         }
+         case 25:
+         {
+            ptyStr = "Country Music";
+            break;
+         }
+         case 26:
+         {
+            ptyStr = "National Music";
+            break;
+         }
+         case 27:
+         {
+            ptyStr = "Oldies Music";
+            break;
+         }
+         case 28:
+         {
+            ptyStr = "Folk Music";
+            break;
+         }
+         case 29:
+         {
+            ptyStr = "Documentary";
+            break;
+         }
+         case 30:
+         {
+            ptyStr = "Emergency Test";
+            break;
+         }
+         case 31:
+         {
+            ptyStr = "Emergency";
+            break;
+         }
+         default:
+         {
+            ptyStr = "";
+            //Log.e(FMRadio.LOGTAG, "Unknown RDS ProgramType [" + pty + "]");
+            break;
+         }
+      }
+      return ptyStr;
+   }
+
+
+}
diff --git a/fmapp2/src/com/caf/fmradio/Settings.java b/fmapp2/src/com/caf/fmradio/Settings.java
new file mode 100644
index 0000000..f5c5d07
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/Settings.java
@@ -0,0 +1,397 @@
+/*
+ * 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.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.preference.ListPreference;
+import android.preference.CheckBoxPreference;
+import android.preference.PreferenceCategory;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import java.util.Locale;
+
+import android.util.Log;
+
+public class Settings extends PreferenceActivity implements
+                OnSharedPreferenceChangeListener, OnPreferenceClickListener {
+        public static final String RX_MODE = "rx_mode";
+        public static final String REGIONAL_BAND_KEY = "regional_band";
+        public static final String AUDIO_OUTPUT_KEY = "audio_output_mode";
+        public static final String RECORD_DURATION_KEY = "record_duration";
+        public static final String AUTO_AF = "af_checkbox_preference";
+        public static final String RESTORE_FACTORY_DEFAULT = "revert_to_fac";
+        public static final int RESTORE_FACTORY_DEFAULT_INT = 1;
+        public static final String RESTORE_FACTORY_DEFAULT_ACTION = "com.caf.fmradio.settings.revert_to_defaults";
+
+        private static final String LOGTAG = FMRadio.LOGTAG;
+
+        private ListPreference mBandPreference;
+        private ListPreference mAudioPreference;
+        private ListPreference mRecordDurPreference;
+        private CheckBoxPreference mAfPref;
+        private Preference mRestoreDefaultPreference;
+
+        private FmSharedPreferences mPrefs = null;
+        private boolean mRxMode = false;
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+          super.onCreate(savedInstanceState);
+          Intent intent = getIntent();
+          if (intent != null) {
+              mRxMode = intent.getBooleanExtra(RX_MODE, false);
+          }
+          mPrefs = new FmSharedPreferences(this);
+          if (mPrefs != null) {
+              setPreferenceScreen(createPreferenceHierarchy());
+          }
+        }
+
+        private PreferenceScreen createPreferenceHierarchy() {
+          int index = 0;
+          if (mPrefs == null) {
+              return null;
+          }
+          // Root
+          PreferenceScreen root = getPreferenceManager().createPreferenceScreen(
+                                this);
+
+          // Band/Country
+          String[] summaryBandItems = getResources().getStringArray(
+                                R.array.regional_band_summary);
+          mBandPreference = new ListPreference(this);
+          mBandPreference.setEntries(R.array.regional_band_entries);
+          mBandPreference.setEntryValues(R.array.regional_band_values);
+          mBandPreference.setDialogTitle(R.string.sel_band_menu);
+          mBandPreference.setKey(REGIONAL_BAND_KEY);
+          mBandPreference.setTitle(R.string.regional_band);
+          index = FmSharedPreferences.getCountry();
+          Log.d(LOGTAG, "createPreferenceHierarchy: Country: " + index);
+          // Get the preference and list the value.
+          if ((index < 0) || (index >= summaryBandItems.length)) {
+                index = 0;
+          }
+          Log.d(LOGTAG, "createPreferenceHierarchy: CountrySummary: "
+                               + summaryBandItems[index]);
+          mBandPreference.setSummary(summaryBandItems[index]);
+          mBandPreference.setValueIndex(index);
+          root.addPreference(mBandPreference);
+
+          if (mRxMode) {
+             // Audio Output (Stereo or Mono)
+             String[] summaryAudioModeItems = getResources().getStringArray(
+                                  R.array.ster_mon_entries);
+             mAudioPreference = new ListPreference(this);
+             mAudioPreference.setEntries(R.array.ster_mon_entries);
+             mAudioPreference.setEntryValues(R.array.ster_mon_values);
+             mAudioPreference.setDialogTitle(R.string.sel_audio_output);
+             mAudioPreference.setKey(AUDIO_OUTPUT_KEY);
+             mAudioPreference.setTitle(R.string.aud_output_mode);
+             boolean audiomode = FmSharedPreferences.getAudioOutputMode();
+             if (audiomode) {
+                 index = 0;
+             }else {
+                 index = 1;
+             }
+             Log.d(LOGTAG, "createPreferenceHierarchy: audiomode: " + audiomode);
+             mAudioPreference.setSummary(summaryAudioModeItems[index]);
+             mAudioPreference.setValueIndex(index);
+             root.addPreference(mAudioPreference);
+
+             // AF Auto Enable (Checkbox)
+             mAfPref = new CheckBoxPreference(this);
+             mAfPref.setKey(AUTO_AF);
+             mAfPref.setTitle(R.string.auto_select_af);
+             mAfPref.setSummaryOn(R.string.auto_select_af_enabled);
+             mAfPref.setSummaryOff(R.string.auto_select_af_disabled);
+             boolean bAFAutoSwitch = FmSharedPreferences.getAutoAFSwitch();
+             Log.d(LOGTAG, "createPreferenceHierarchy: bAFAutoSwitch: "
+                                   + bAFAutoSwitch);
+             mAfPref.setChecked(bAFAutoSwitch);
+             root.addPreference(mAfPref);
+
+             if(FMRadio.RECORDING_ENABLE) {
+                String[] summaryRecordItems = getResources().getStringArray(
+                   R.array.record_durations_entries);
+                int nRecordDuration = 0;
+                mRecordDurPreference = new ListPreference(this);
+                mRecordDurPreference.setEntries(R.array.record_durations_entries);
+                mRecordDurPreference.setEntryValues(R.array.record_duration_values);
+                mRecordDurPreference.setDialogTitle(R.string.sel_rec_dur);
+                mRecordDurPreference.setKey(RECORD_DURATION_KEY);
+                mRecordDurPreference.setTitle(R.string.record_dur);
+                nRecordDuration = FmSharedPreferences.getRecordDuration();
+                Log.d(LOGTAG, "createPreferenceHierarchy: recordDuration: "
+                        + nRecordDuration);
+                switch(nRecordDuration) {
+                case FmSharedPreferences.RECORD_DUR_INDEX_0_VAL:
+                     index = 0;
+                     break;
+                case FmSharedPreferences.RECORD_DUR_INDEX_1_VAL:
+                     index = 1;
+                     break;
+                case FmSharedPreferences.RECORD_DUR_INDEX_2_VAL:
+                     index = 2;
+                     break;
+                case FmSharedPreferences.RECORD_DUR_INDEX_3_VAL:
+                     index = 3;
+                     break;
+                }
+                // Get the preference and list the value.
+                if ((index < 0) || (index >= summaryRecordItems.length)) {
+                   index = 0;
+                }
+                Log.d(LOGTAG, "createPreferenceHierarchy: recordDurationSummary: "
+                    + summaryRecordItems[index]);
+                mRecordDurPreference.setSummary(summaryRecordItems[index]);
+                mRecordDurPreference.setValueIndex(index);
+                root.addPreference(mRecordDurPreference);
+             }
+          }
+
+          // Add a new category
+          PreferenceCategory prefCat = new PreferenceCategory(this);
+          root.addPreference(prefCat);
+
+          mRestoreDefaultPreference = new Preference(this);
+          mRestoreDefaultPreference.setTitle(
+                                       R.string.settings_revert_defaults_title);
+          mRestoreDefaultPreference.setKey(RESTORE_FACTORY_DEFAULT);
+          mRestoreDefaultPreference
+                                .setSummary(R.string.settings_revert_defaults_summary);
+          mRestoreDefaultPreference.setOnPreferenceClickListener(this);
+          root.addPreference(mRestoreDefaultPreference);
+          return root;
+        }
+	public void clearStationList() {
+          SharedPreferences sp = getSharedPreferences(FMRadio.SCAN_STATION_PREFS_NAME, 0);
+          SharedPreferences.Editor editor = sp.edit();
+          editor.clear();
+          editor.commit();
+        }
+        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+                        String key) {
+          int mTunedFreq = 0;
+          boolean bStatus = false;
+          if (key.equals(REGIONAL_BAND_KEY)) {
+	      int curListIndex = FmSharedPreferences.getCurrentListIndex();
+	      PresetList curList = FmSharedPreferences.getStationList(curListIndex);
+              String[] summaryBandItems = getResources().getStringArray(
+                                       R.array.regional_band_summary);
+              String valueStr = sharedPreferences.getString(key, "");
+              int index = 0;
+              if (valueStr != null) {
+                  index = mBandPreference.findIndexOfValue(valueStr);
+              }
+              if ((index < 0) || (index >= summaryBandItems.length)) {
+                  index = 0;
+                  mBandPreference.setValueIndex(0);
+              }
+              Log.d(LOGTAG, "onSharedPreferenceChanged: Country Change: "
+                                                        + index);
+              mBandPreference.setSummary(summaryBandItems[index]);
+              FmSharedPreferences.setCountry(index);
+              bStatus = FMRadio.fmConfigure();
+              FMTransmitterActivity.fmConfigure();
+              if (curList != null) {
+                  curList.clear();
+              }
+              clearStationList();
+          }else {
+              if(mRxMode) {
+                 if (key.equals(AUTO_AF)) {
+                     boolean bAFAutoSwitch = mAfPref.isChecked();
+                     Log.d(LOGTAG, "onSharedPreferenceChanged: Auto AF Enable: "
+                                               + bAFAutoSwitch);
+                     FmSharedPreferences.setAutoAFSwitch(bAFAutoSwitch);
+                     FMRadio.fmAutoAFSwitch();
+                     mPrefs.Save();
+                 }else if(key.equals(RECORD_DURATION_KEY)) {
+                     if(FMRadio.RECORDING_ENABLE) {
+                        String[] recordItems = getResources().getStringArray(
+                                                    R.array.record_durations_entries);
+                        String valueStr = mRecordDurPreference.getValue();
+                        int index = 0;
+                        if (valueStr != null) {
+                            index = mRecordDurPreference.findIndexOfValue(valueStr);
+                        }
+                        if ((index < 0) || (index >= recordItems.length)) {
+                             index = 0;
+                             mRecordDurPreference.setValueIndex(index);
+                        }
+                        Log.d(LOGTAG, "onSharedPreferenceChanged: recorddur: "
+                                                 + recordItems[index]);
+                        mRecordDurPreference.setSummary(recordItems[index]);
+                        FmSharedPreferences.setRecordDuration(index);
+                     }
+                 }else if (key.equals(AUDIO_OUTPUT_KEY)) {
+                     String[] bandItems = getResources().getStringArray(
+                                                R.array.ster_mon_entries);
+                     String valueStr = mAudioPreference.getValue();
+                     int index = 0;
+                     if (valueStr != null) {
+                         index = mAudioPreference.findIndexOfValue(valueStr);
+                     }
+                     if (index != 1) {
+                         if (index != 0) {
+                             index = 0;
+                             /* It shud be 0(Stereo) or 1(Mono) */
+                             mAudioPreference.setValueIndex(index);
+                         }
+                     }
+                     Log.d(LOGTAG, "onSharedPreferenceChanged: audiomode: "
+                                              + bandItems[index]);
+                     mAudioPreference.setSummary(bandItems[index]);
+                     if (index == 0) {
+                         // Stereo
+                         FmSharedPreferences.setAudioOutputMode(true);
+                     }else {
+                         // Mono
+                         FmSharedPreferences.setAudioOutputMode(false);
+                     }
+                     FMRadio.fmAudioOutputMode();
+                 }
+              }
+          }
+          if (mPrefs != null) {
+              if(bStatus) {
+                 mPrefs.Save();
+              }else {
+                 mTunedFreq = FmSharedPreferences.getTunedFrequency();
+                 if (mTunedFreq > FmSharedPreferences.getUpperLimit() ||
+                          mTunedFreq < FmSharedPreferences.getLowerLimit()) {
+                     FmSharedPreferences.setTunedFrequency(
+                          FmSharedPreferences.getLowerLimit());
+                 }
+                 mPrefs.Save();
+              }
+          }
+        }
+
+        public boolean onPreferenceClick(Preference preference) {
+          boolean handled = false;
+          if (preference == mRestoreDefaultPreference) {
+              showDialog(RESTORE_FACTORY_DEFAULT_INT);
+          }
+          return handled;
+        }
+
+        @Override
+        protected Dialog onCreateDialog(int id) {
+          switch (id) {
+          case RESTORE_FACTORY_DEFAULT_INT:
+               return new AlertDialog.Builder(this).setIcon(
+                      R.drawable.alert_dialog_icon).setTitle(
+                      R.string.settings_revert_confirm_title).setMessage(
+                      R.string.settings_revert_confirm_msg).setPositiveButton(
+                      R.string.alert_dialog_ok,
+                      new DialogInterface.OnClickListener() {
+                           public void onClick(DialogInterface dialog,
+                              int whichButton) {
+                              Intent data = new Intent(
+                                         RESTORE_FACTORY_DEFAULT_ACTION);
+                              setResult(RESULT_OK, data);
+                              restoreSettingsDefault();
+                              finish();
+                           }
+                      }).setNegativeButton(R.string.alert_dialog_cancel,
+                              new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog,
+                                                       int whichButton) {
+                                }
+                              }).create();
+                default:
+                        break;
+                }
+                return null;
+        }
+
+        private void restoreSettingsDefault() {
+          if (mPrefs != null) {
+             if (Locale.getDefault().equals(Locale.CHINA)) {
+                 mBandPreference
+                        .setValueIndex(FmSharedPreferences.REGIONAL_BAND_CHINA);
+             }else {
+                 mBandPreference
+                        .setValueIndex(FmSharedPreferences.REGIONAL_BAND_NORTH_AMERICA);
+             }
+             if (mRxMode) {
+                mAudioPreference.setValueIndex(0);
+                if (FMRadio.RECORDING_ENABLE) {
+                    mRecordDurPreference.setValueIndex(0);
+                }
+                mAfPref.setChecked(true);
+                FmSharedPreferences.SetDefaults();
+             }else {
+                if (Locale.getDefault().equals(Locale.CHINA)) {
+                    FmSharedPreferences
+                    .setCountry(FmSharedPreferences.REGIONAL_BAND_CHINA);
+                }else{
+                    FmSharedPreferences
+                    .setCountry(FmSharedPreferences.REGIONAL_BAND_NORTH_AMERICA);
+                }
+             }
+             mPrefs.Save();
+          }
+        }
+
+        @Override
+        protected void onResume() {
+          super.onResume();
+          PreferenceScreen preferenceScreen = getPreferenceScreen();
+          SharedPreferences sharedPreferences = null;
+          if (preferenceScreen != null) {
+              sharedPreferences = preferenceScreen.getSharedPreferences();
+          }
+          if (sharedPreferences != null) {
+              sharedPreferences.registerOnSharedPreferenceChangeListener(this);
+          }
+        }
+
+        @Override
+        protected void onPause() {
+          super.onPause();
+          PreferenceScreen preferenceScreen = getPreferenceScreen();
+          SharedPreferences sharedPreferences = null;
+          if (preferenceScreen != null) {
+              sharedPreferences = preferenceScreen.getSharedPreferences();
+          }
+          if (sharedPreferences != null) {
+              sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
+          }
+        }
+}
diff --git a/fmapp2/src/com/caf/fmradio/StationListActivity.java b/fmapp2/src/com/caf/fmradio/StationListActivity.java
new file mode 100644
index 0000000..46b59ad
--- /dev/null
+++ b/fmapp2/src/com/caf/fmradio/StationListActivity.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2012-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 "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.util.ArrayList;
+import java.util.HashMap;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.Handler.Callback;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.Gravity;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemLongClickListener;
+
+public class StationListActivity extends Activity implements
+        View.OnCreateContextMenuListener {
+
+    private static final String LOGTAG = "StationList";
+    private ListView mStationList;
+    private PresetList mPresetList;
+    private SimpleAdapter mAdapter;
+    private static IFMRadioService mService = null;
+    private static final int CONTEXT_MENU_RENAME = 1;
+    private static final int CONTEXT_MENU_DELETE = 2;
+
+    static final int DIALOG_RENAME_ID = 0;
+    static final int DIALOG_DELETE_ID = 1;
+    // private static String mDialogTitle;
+    private static String mDialogStationName;
+    private static int mItemId;
+    private Dialog mRenameDialog;
+    private Dialog mDeleteDialog;
+    //whether is the first headset plug event
+    private boolean isFirst = true;
+    private ServiceConnection osc = new ServiceConnection() {
+        public void onServiceConnected(ComponentName classname, IBinder obj) {
+            mService = IFMRadioService.Stub.asInterface(obj);
+            if (mService != null) {
+                return;
+            } else {
+                Log.e(LOGTAG, "IFMRadioService onServiceConnected failed");
+            }
+        }
+
+        public void onServiceDisconnected(ComponentName classname) {
+        }
+    };
+
+    ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
+    HashMap<Integer, Integer> mIndex = new HashMap<Integer, Integer>();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.station_list);
+        bindService((new Intent()).setClass(this, FMRadioService.class), osc, 0);
+
+        mStationList = (ListView) findViewById(R.id.station_list);
+        // mPresetList = new PresetList("StationList");
+        mStationList.setOnCreateContextMenuListener(this);
+        mStationList.setOnItemClickListener(new OnItemClickListener() {
+
+            @Override
+            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
+                    long arg3) {
+                String freq = ((HashMap<String, String>) mAdapter.getItem(arg2))
+                        .get("freq");
+                Float fFreq = Float.parseFloat(freq);
+                if (mService != null) {
+                    try {
+                        mService.tune((int) ((fFreq * 1000)));
+                    } catch (RemoteException e) {
+                        e.printStackTrace();
+                    }
+                } else {
+                    Log.d(LOGTAG, "mService is null........");
+                }
+            }
+        });
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        // TODO Auto-generated method stub
+        AdapterContextMenuInfo mi = (AdapterContextMenuInfo) item.getMenuInfo();
+        switch (item.getItemId()) {
+        case CONTEXT_MENU_RENAME:
+            showDialog(DIALOG_RENAME_ID);
+            break;
+        case CONTEXT_MENU_DELETE:
+            showDialog(DIALOG_DELETE_ID);
+            break;
+
+        }
+
+        return true;
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+            ContextMenuInfo menuInfo) {
+        // TODO Auto-generated method stub
+        AdapterContextMenuInfo mi = (AdapterContextMenuInfo) menuInfo;
+        menu.add(0, CONTEXT_MENU_RENAME, 0, getString(R.string.preset_rename));
+        menu.add(0, CONTEXT_MENU_DELETE, 0, getString(R.string.preset_delete));
+        mItemId = mi.position;
+        menu.setHeaderTitle(getString(R.string.station_name)+getNameFromId(mItemId));
+    }
+
+    @Override
+    protected void onResume() {
+        // TODO Auto-generated method stub
+        load();
+        super.onResume();
+    }
+
+    private boolean stationNameExist(String name) {
+        for (HashMap<String, String> item : list) {
+            if (item != null && name.equals(item.get("name"))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog, Bundle b) {
+        // TODO Auto-generated method stub
+        // super.onPrepareDialog(id, dialog);
+        // After change system language, current function will be executed before
+        // onResume , so execute load to ensure adapter is not null.
+        load();
+        switch (id) {
+        case DIALOG_RENAME_ID:
+            mRenameDialog.setTitle(getString(R.string.station_name)+getNameFromId(mItemId));
+            final EditText editText = (EditText) mRenameDialog
+                    .findViewById(R.id.name);
+            editText.setText(getNameFromId(mItemId));
+            Button bOk = (Button) mRenameDialog.findViewById(R.id.save);
+
+            bOk.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    String rename = editText.getText().toString();
+                    if (TextUtils.isEmpty(rename) || TextUtils.isEmpty(rename.trim())) {
+                        Context context = getApplicationContext();
+                        Toast toast = Toast.makeText(context, getString(R.string.station_name_empty),
+                                Toast.LENGTH_SHORT);
+                        toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
+                        toast.show();
+                    } else if (stationNameExist(rename)) {
+                        Context context = getApplicationContext();
+                        Toast toast = Toast.makeText(context,
+                                getString(R.string.station_name_exist, rename), Toast.LENGTH_SHORT);
+                        toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL, 0, 0);
+                        toast.show();
+                    } else {
+                        saveStationName(mItemId,rename);
+                        mRenameDialog.dismiss();
+                    }
+                }
+
+            });
+            Button bCancel = (Button) mRenameDialog.findViewById(R.id.cancel);
+            bCancel.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    // TODO Auto-generated method stub
+                    mRenameDialog.dismiss();
+                }
+            });
+            break;
+        case DIALOG_DELETE_ID:
+            mDeleteDialog.setTitle(getString(R.string.station_list_delete_station, getNameFromId(mItemId)));
+            TextView prompt = (TextView) mDeleteDialog.findViewById(R.id.prompt);
+            prompt.setText(getString(R.string.station_list_delete_station_prompt,getNameFromId(mItemId)));
+            Button bDelete = (Button) mDeleteDialog.findViewById(R.id.delete);
+
+            bDelete.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    deleteStation(mItemId);
+                    mDeleteDialog.dismiss();
+                }
+            });
+            Button bCancelDelete = (Button) mDeleteDialog.findViewById(R.id.cancel);
+            bCancelDelete.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    mDeleteDialog.dismiss();
+                }
+            });
+            break;
+        }
+    }
+
+    @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(
+                FMRadio.SCAN_STATION_PREFS_NAME, 0);
+        SharedPreferences.Editor editor = sp.edit();
+        editor
+                .putString(FMRadio.STATION_NAME + (stationIndex.intValue()),
+                        name);
+        editor.commit();
+        load();
+    }
+
+    private void deleteStation(int id) {
+        SharedPreferences sp = getSharedPreferences(
+                FMRadio.SCAN_STATION_PREFS_NAME, 0);
+        Integer stationIndex = mIndex.get(new Integer(id));
+        SharedPreferences.Editor editor = sp.edit();
+        editor.remove(FMRadio.STATION_NAME + (stationIndex));
+        editor.remove(FMRadio.STATION_FREQUENCY + (stationIndex));
+        editor.commit();
+        load();
+    }
+
+    private int getFrequencyFromId(int id) {
+        String freq = ((HashMap<String, String>) mAdapter.getItem(id))
+                .get("freq");
+        Float fFreq = Float.parseFloat(freq);
+        return (int) ((fFreq * 1000));
+    }
+
+    private String getNameFromId(int id) {
+        String name = ((HashMap<String, String>) mAdapter.getItem(id))
+                .get("name");
+        return name;
+
+    }
+
+    protected void load() {
+        list.clear();
+        mIndex.clear();
+        SharedPreferences sp = getSharedPreferences(
+                FMRadio.SCAN_STATION_PREFS_NAME, 0);
+        int station_number = sp.getInt(FMRadio.NUM_OF_STATIONS, 0);
+        for (int i = 1; i <= station_number; i++) {
+            HashMap<String, String> item = new HashMap<String, String>();
+            String name = sp.getString(FMRadio.STATION_NAME + i, "");
+
+            int frequency = sp.getInt(FMRadio.STATION_FREQUENCY + i, 0);
+
+            if (!name.equals("") && frequency != 0) {
+                item.put("name", name);
+                item.put("freq", String.valueOf(frequency / 1000.0f));
+                mIndex.put(new Integer(list.size()), new Integer(i));
+                list.add(item);
+            }
+        }
+
+        mAdapter = new SimpleAdapter(this, list, R.layout.station_list_item,
+                new String[] { "name", "freq" }, new int[] { R.id.name,
+                        R.id.freq });
+
+        mStationList.setAdapter(mAdapter);
+    }
+
+    @Override
+    protected void onDestroy() {
+        unbindService(osc);
+        mService = null;
+        super.onDestroy();
+    }
+
+}
diff --git a/fmapp2/src/com/caf/hc_utils/A2dpDeviceStatus.java b/fmapp2/src/com/caf/hc_utils/A2dpDeviceStatus.java
new file mode 100644
index 0000000..45b647e
--- /dev/null
+++ b/fmapp2/src/com/caf/hc_utils/A2dpDeviceStatus.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2011-2012, 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.utils;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Intent;
+import android.content.Context;
+
+public class A2dpDeviceStatus {
+    private BluetoothAdapter mAdapter;
+    private BluetoothA2dp mA2dp = null;
+    public String getActionSinkStateChangedString (){
+        return BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED;
+    }
+    public String getActionPlayStateChangedString (){
+        return BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED;
+    }
+    public boolean  isA2dpStateChange( String action) {
+        if(action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED) ) {
+           return true;
+        }
+        return false;
+    }
+    public boolean  isA2dpPlayStateChange( String action) {
+        if(action.equals(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED) ) {
+           return true;
+        }
+        return false;
+    }
+    public boolean isConnected(Intent intent) {
+        boolean isConnected = false;
+        int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE,
+                                BluetoothA2dp.STATE_DISCONNECTED);
+        if((state == BluetoothA2dp.STATE_CONNECTED) || (state == BluetoothProfile.STATE_CONNECTED)) {
+            isConnected = true;
+        }
+        return isConnected;
+    }
+    public boolean isPlaying(Intent intent) {
+        boolean isPlaying = false;
+        int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE,
+                                BluetoothA2dp.STATE_DISCONNECTED);
+        if(state == BluetoothA2dp.STATE_PLAYING ) {
+            isPlaying = true;
+        }
+        return isPlaying;
+    }
+    public boolean isDeviceAvailable() {
+        if(null != mA2dp) {
+            if( 0 != mA2dp.getConnectedDevices().size() ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public A2dpDeviceStatus(Context mContext) {
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        mAdapter.getProfileProxy(mContext, mProfileListener,
+                BluetoothProfile.A2DP);
+    }
+    private BluetoothProfile.ServiceListener mProfileListener =
+        new BluetoothProfile.ServiceListener() {
+    public void onServiceConnected(int profile, BluetoothProfile proxy) {
+        if (profile == BluetoothProfile.A2DP) {
+            mA2dp = (BluetoothA2dp) proxy;
+        }
+    }
+    public void onServiceDisconnected(int profile) {
+        if (profile == BluetoothProfile.A2DP) {
+            mA2dp = null;
+        }
+    }
+};
+}
+
diff --git a/fmapp2/src/com/caf/hc_utils/FrequencyPicker.java b/fmapp2/src/com/caf/hc_utils/FrequencyPicker.java
new file mode 100644
index 0000000..c88bb0a
--- /dev/null
+++ b/fmapp2/src/com/caf/hc_utils/FrequencyPicker.java
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.caf.utils;
+
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.widget.FrameLayout;
+
+import com.caf.fmradio.R;
+import android.widget.NumberPicker;
+import android.widget.NumberPicker.OnValueChangeListener;
+
+/**
+ * A view for selecting the frequency
+ *
+ * For a dialog using this view, see {FrequencyPickerDialog}.
+ */
+
+public class FrequencyPicker extends FrameLayout {
+
+    /* UI Components */
+    private final NumberPicker mMHzPicker;
+    private final NumberPicker mKHzPicker;
+
+    /**
+     * How we notify users the Frequency has changed.
+     */
+    private OnFrequencyChangedListener mOnFrequencyChangedListener;
+
+    private int mFrequency;
+    private int mMin;
+    private int mMax;
+    private int mStep;
+    private int mMhz;
+    private int mKhz;
+
+    /**
+     * The callback used to indicate the user changes the Frequency.
+     */
+    public interface OnFrequencyChangedListener {
+
+        /**
+         * @param view The view associated with this listener.
+         * @param frequency The Frequency that was set.
+         */
+        void onFrequencyChanged(FrequencyPicker view, int frequency);
+    }
+
+    public FrequencyPicker(Context context) {
+        this(context, null);
+    }
+
+    public FrequencyPicker(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public FrequencyPicker(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        inflater.inflate(R.layout.frequency_picker, this, true);
+
+        mMHzPicker = (NumberPicker) findViewById(R.id.mhz);
+        if (mMHzPicker != null) {
+           mMHzPicker.setOnLongPressUpdateInterval(100);
+
+           mMHzPicker.setOnValueChangedListener(new OnValueChangeListener() {
+              public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                  mMhz = newVal;
+                  mFrequency = (mMhz*1000) + (getFrequencyKHz(mKhz, mMin, mStep));
+                  validateFrequencyRange();
+                  if (mOnFrequencyChangedListener != null) {
+                        mOnFrequencyChangedListener.onFrequencyChanged(FrequencyPicker.this, mFrequency);
+                  }
+              }
+           });
+        }
+        mKHzPicker = (NumberPicker) findViewById(R.id.khz);
+        if (mKHzPicker != null) {
+           mKHzPicker.setOnLongPressUpdateInterval(100);
+           mKHzPicker.setOnValueChangedListener(new OnValueChangeListener() {
+              public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                  mKhz = newVal;
+                  mFrequency = (mMhz*1000) + (getFrequencyKHz(mKhz, mMin, mStep));
+
+                  validateFrequencyRange();
+
+                  if (mOnFrequencyChangedListener != null) {
+                        mOnFrequencyChangedListener.onFrequencyChanged(FrequencyPicker.this, mFrequency);
+                  }
+              }
+           });
+        }
+
+        updateSpinnerRange();
+
+        if (!isEnabled()) {
+            setEnabled(false);
+        }
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        super.setEnabled(enabled);
+        mMHzPicker.setEnabled(enabled);
+        mKHzPicker.setEnabled(enabled);
+    }
+
+
+    public void updateFrequency(int frequency) {
+        mFrequency = frequency;
+        updateSpinners();
+    }
+
+    private static class SavedState extends BaseSavedState {
+
+        private final int mMHZ;
+        private final int mKHZ;
+
+        /**
+         * Constructor called from {@link FrequencyPicker#onSaveInstanceState()}
+         */
+        private SavedState(Parcelable superState, int mhz, int khz) {
+            super(superState);
+            mMHZ = mhz;
+            mKHZ = khz;
+        }
+
+        /**
+         * Constructor called from {@link #CREATOR}
+         */
+        private SavedState(Parcel in) {
+            super(in);
+            mMHZ = in.readInt();
+            mKHZ = in.readInt();
+        }
+
+        public int getMHz() {
+            return mMHZ;
+        }
+
+        public int getKHz() {
+            return mKHZ;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeInt(mMHZ);
+            dest.writeInt(mKHZ);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Creator<SavedState>() {
+
+                    public SavedState createFromParcel(Parcel in) {
+                        return new SavedState(in);
+                    }
+
+                    public SavedState[] newArray(int size) {
+                        return new SavedState[size];
+                    }
+                };
+    }
+
+
+    /**
+     * Override so we are in complete control of save / restore for this widget.
+     */
+    @Override
+    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+        dispatchThawSelfOnly(container);
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+
+        return new SavedState(superState, mMhz, mKhz);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mMhz = ss.getMHz();
+        mKhz = ss.getKHz();
+    }
+
+    private String[] getKHzStrings(int min, int stepSize)
+    {
+            if(stepSize == 100)
+            {
+                    return (get100KHzStrings());
+            }
+            else if(stepSize == 50)
+            {
+                    return (get50KHzStrings());
+            }
+                   return (get200KHzStrings(min));
+    }
+
+    private int getKHzCount(int stepSize)
+    {
+            if(stepSize == 100)
+            {
+                    return (10);
+            }
+            else if(stepSize == 50)
+            {
+                    return (20);
+            }
+                   return (5);
+    }
+    private int getCurrentKHz(int frequency, int min, int stepSize)
+    {
+            if(stepSize == 100)
+            {
+                    return (getCurrent100KHz(frequency));
+            }
+            else if(stepSize == 50)
+            {
+                    return (getCurrent50KHz(frequency));
+            }
+                   return (getCurrent200KHz(frequency, min));
+    }
+
+    private int getFrequencyKHz(int kHz, int min, int stepSize)
+    {
+            if(stepSize == 100)
+            {
+                    return (getFrequency100KHz(kHz));
+            }
+            else if(stepSize == 50)
+            {
+                    return (getFrequency50KHz(kHz));
+            }
+                   return (getFrequency200KHz(kHz, min));
+    }
+
+    private int getFrequency100KHz(int kHz)
+    {
+            int frequencykhz = ((kHz-1)*100) ;
+        //Log.d("FMRadio", "FP: getCurrent100KHz: " + frequencykhz);
+                   return (frequencykhz);
+    }
+
+    private int getFrequency50KHz(int kHz)
+    {
+            int frequencykhz = ((kHz-1)*50) ;
+        //Log.d("FMRadio", "FP: getCurrent100KHz: " + frequencykhz);
+                   return (frequencykhz);
+    }
+
+    private int getFrequency200KHz(int kHz, int min)
+    {
+            int frequencykhz = ((kHz-1)*200) ;
+            if(min%200 != 0)
+            {
+                    frequencykhz = ((kHz-1)*200)+100 ;
+            }
+            //Log.d("FMRadio", "FP: getCurrent200KHz: " + frequencykhz);
+                   return (frequencykhz);
+    }
+
+    private int getCurrent100KHz(int frequency)
+    {
+            int khz = ((frequency%1000)/100) ;
+        //Log.d("FMRadio", "FP: getCurrent100KHz: " + khz);
+                   return (khz+1);
+    }
+
+    private int getCurrent50KHz(int frequency)
+    {
+            int khz = ((frequency%1000)/50)  ;
+        //Log.d("FMRadio", "FP: getCurrent50KHz: " + khz);
+                   return (khz+1);
+    }
+
+    private int getCurrent200KHz(int frequency, int min)
+    {
+            int khz = ((frequency%1000)/200);
+        //Log.d("FMRadio", "FP: getCurrent200KHz: " + khz);
+                   return (khz+1);
+    }
+
+    private String[] get50KHzStrings()
+    {
+                   String[] khzStrings= {"00","05","10","15","20","25","30","35","40","45",
+                                                 "50","55","60","65","70","75","80","85","90","95"};
+        //Log.d("FMRadio", "FP: get50KHzStrings");
+            return khzStrings;
+    }
+
+    private String[] get100KHzStrings()
+    {
+                   String[] khzStrings= {"0","1","2","3","4","5",
+                                         "6","7","8","9"};
+        //Log.d("FMRadio", "FP: get100KHzStrings");
+            return khzStrings;
+    }
+
+    private String[] get200KHzStrings(int min)
+    {
+            if(min%200 == 0)
+            {
+                    return (getEven200KHzStrings());
+            }
+                   return (getOdd200KHzStrings());
+    }
+
+    private String[] getEven200KHzStrings()
+    {
+                   String[] khzStrings= {"0","2","4","6","8"};
+        //Log.d("FMRadio", "FP: getEven200KHzStrings");
+            return khzStrings;
+    }
+    private String[] getOdd200KHzStrings()
+    {
+                   String[] khzStrings= {"1","3","5","7","9"};
+        //Log.d("FMRadio", "FP: getOdd200KHzStrings");
+            return khzStrings;
+    }
+    public void updateSteps(int steps)
+    {
+       mStep = steps;
+    }
+    public void updateMinFreq(int freq)
+    {
+       mMin = freq;
+    }
+    public void updateMaxFreq(int freq)
+    {
+       mMax = freq;
+    }
+    /**
+     * Initialize the state.
+     * @param year The initial year.
+     * @param monthOfYear The initial month.
+     * @param dayOfMonth The initial day of the month.
+     * @param onDateChangedListener How user is notified date is changed by user, can be null.
+     */
+    public void init(int min, int max, int step, int frequency,
+            OnFrequencyChangedListener onFrequencyChangedListener) {
+
+            mMin = min;
+            mMax = max;
+            mStep = step;
+        mFrequency = frequency;
+        mOnFrequencyChangedListener = onFrequencyChangedListener;
+
+        updateSpinners();
+    }
+    private void updateSpinnerRange() {
+        String[] khzStrings = getKHzStrings(mMin, mStep);
+        int khzNumSteps = getKHzCount(mStep);
+
+        if (mMHzPicker != null) {
+           mMHzPicker.setMinValue(mMin/1000);
+           mMHzPicker.setMaxValue(mMax/1000);
+        }
+        if (mKHzPicker != null) {
+           mKHzPicker.setDisplayedValues(get50KHzStrings());
+           mKHzPicker.setMinValue(1);
+           mKHzPicker.setMaxValue(khzNumSteps);
+           mKHzPicker.setDisplayedValues(khzStrings);
+        }
+    }
+
+    private void updateSpinners() {
+        int khzNumSteps = getKHzCount(mStep);
+        updateSpinnerRange();
+        mMhz = (int)(mFrequency/1000);
+            mKhz = getCurrentKHz(mFrequency, mMin, mStep) ;
+        if((mMin/1000 <=mMhz) && (mMax/1000 >=mMhz))
+        {
+            mMHzPicker.setValue(mMhz);
+        }
+        if(mKhz <= khzNumSteps)
+        {
+            mKHzPicker.setValue(mKhz);
+        }
+    }
+    private void validateFrequencyRange()
+    {
+            boolean bUpdateSpinner=false;
+        if(mFrequency < mMin)
+        {
+                mFrequency = mMin;
+                bUpdateSpinner = true;
+        }
+        if(mFrequency > mMax)
+        {
+                mFrequency = mMax;
+                bUpdateSpinner = true;
+        }
+        if(bUpdateSpinner == true)
+        {
+                updateSpinners();
+        }
+    }
+
+    public int getFrequency() {
+        return (mFrequency);
+    }
+}
diff --git a/fmapp2/src/com/caf/hc_utils/FrequencyPickerDialog.java b/fmapp2/src/com/caf/hc_utils/FrequencyPickerDialog.java
new file mode 100644
index 0000000..cac7dc1
--- /dev/null
+++ b/fmapp2/src/com/caf/hc_utils/FrequencyPickerDialog.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2012 - 2013, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.caf.utils;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import qcom.fmradio.FmConfig;
+import qcom.fmradio.FmReceiver;
+
+import com.caf.fmradio.R;
+import com.caf.utils.FrequencyPicker.OnFrequencyChangedListener;
+
+/**
+ * A simple dialog containing an FrequencyPicker.
+ */
+public class FrequencyPickerDialog extends AlertDialog implements OnClickListener,
+OnFrequencyChangedListener {
+
+    private static final String FREQUENCY = "FREQUENCY";
+    private static final String FREQ_MIN = "FREQ_MIN";
+    private static final String FREQ_MAX = "FREQ_MAX";
+    private static final String FREQ_STEP = "FREQ_STEP";
+
+    private final FrequencyPicker mFrequencyPicker;
+    private final OnFrequencySetListener mCallBack;
+    private int mMinFrequency;
+    private int mMaxFrequency;
+    private int mChannelSpacing;
+
+    /**
+     * The callback used to indicate the user is done filling in the date.
+     */
+    public interface OnFrequencySetListener {
+
+        void onFrequencySet(FrequencyPicker view, int frequency);
+    }
+    /**
+     */
+    public FrequencyPickerDialog(Context context,
+                                                            FmConfig fmConfig,
+                                                            int frequency,
+                                 OnFrequencySetListener callback) {
+        //this(context, android.R.style.Theme_Dialog, fmConfig, frequency, callback);
+       this(context, com.android.internal.R.style.Theme_Dialog_Alert, fmConfig, frequency, callback);
+    }
+
+    /**
+     */
+    public FrequencyPickerDialog(Context context,
+            int theme,
+            FmConfig fmConfig,
+                        int frequency,
+                        OnFrequencySetListener callback) {
+        super(context, theme);
+        mMinFrequency = fmConfig.getLowerLimit();
+        mMaxFrequency = fmConfig.getUpperLimit();
+        mChannelSpacing = 200;
+        if(FmReceiver.FM_CHSPACE_200_KHZ == fmConfig.getChSpacing())
+        {
+                mChannelSpacing = 200;
+        }
+        else if(FmReceiver.FM_CHSPACE_100_KHZ == fmConfig.getChSpacing())
+        {
+                mChannelSpacing = 100;
+        }
+        else if(FmReceiver.FM_CHSPACE_50_KHZ == fmConfig.getChSpacing())
+        {
+                mChannelSpacing = 50;
+        }
+        int MHz = frequency/1000;
+        int KHz = (frequency%1000)/100;
+            setTitle("FM - "+MHz+"."+KHz);
+        mCallBack = callback;
+
+        setButton("Set", this);
+        setButton2("Cancel", (OnClickListener) null);
+        setIcon(R.drawable.alert_dialog_icon);
+
+        LayoutInflater inflater =
+                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        View view = inflater.inflate(R.layout.frequency_picker_dialog, null);
+        setView(view);
+        mFrequencyPicker = (FrequencyPicker) view.findViewById(R.id.frequencyPicker);
+        if(mFrequencyPicker != null)
+        {
+                mFrequencyPicker.init(mMinFrequency, mMaxFrequency, mChannelSpacing, frequency, this);
+        }
+        else
+        {
+            Log.e("fmRadio", "Failed to find ID: R.id.frequencyPicker");
+        }
+    }
+
+    public void UpdateFrequency(int frequency)
+    {
+        int MHz = frequency/1000;
+        int KHz = (frequency%1000)/100;
+            setTitle("FM - "+MHz+"."+KHz);
+            mFrequencyPicker.updateFrequency(frequency);
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        if (mCallBack != null) {
+            mFrequencyPicker.clearFocus();
+            int frequency = mFrequencyPicker.getFrequency();
+            mCallBack.onFrequencySet(mFrequencyPicker, frequency);
+        }
+    }
+
+    public void onFrequencyChanged(FrequencyPicker view, int frequency) {
+            UpdateFrequency(frequency);
+    }
+
+    @Override
+    public Bundle onSaveInstanceState() {
+        Bundle state = super.onSaveInstanceState();
+        state.putInt(FREQUENCY, mFrequencyPicker.getFrequency());
+        state.putInt(FREQ_MIN, mMinFrequency);
+        state.putInt(FREQ_MAX, mMaxFrequency);
+        state.putInt(FREQ_STEP, mChannelSpacing);
+        return state;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        int frequency = savedInstanceState.getInt(FREQUENCY);
+        mMinFrequency = savedInstanceState.getInt(FREQ_MIN);
+        mMaxFrequency = savedInstanceState.getInt(FREQ_MAX );
+        mChannelSpacing = savedInstanceState.getInt(FREQ_STEP);
+        mFrequencyPicker.init(mMinFrequency, mMaxFrequency, mChannelSpacing, frequency, this);
+        int MHz = frequency/1000;
+        int KHz = (frequency%1000)/100;
+            setTitle("FM - "+MHz+"."+KHz);
+    }
+    public void updateSteps(int steps)
+    {
+        mChannelSpacing = 200;
+        if(FmReceiver.FM_CHSPACE_200_KHZ == steps)
+        {
+                mChannelSpacing = 200;
+        }
+        else if(FmReceiver.FM_CHSPACE_100_KHZ == steps)
+        {
+                mChannelSpacing = 100;
+        }
+        else if(FmReceiver.FM_CHSPACE_50_KHZ == steps)
+        {
+                mChannelSpacing = 50;
+        }
+        mFrequencyPicker.updateSteps(mChannelSpacing);
+    }
+    public void updateMinFreq(int freq)
+    {
+       mMinFrequency = freq;
+       mFrequencyPicker.updateMinFreq(mMinFrequency);
+    }
+    public void updateMaxFreq(int freq)
+    {
+       mMaxFrequency = freq;
+       mFrequencyPicker.updateMaxFreq(mMaxFrequency);
+    }
+}
diff --git a/fmapp2/src/com/caf/utils/A2dpDeviceStatus.java b/fmapp2/src/com/caf/utils/A2dpDeviceStatus.java
new file mode 100644
index 0000000..3f1c010
--- /dev/null
+++ b/fmapp2/src/com/caf/utils/A2dpDeviceStatus.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011, 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.utils;
+
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.Set;
+
+
+public class A2dpDeviceStatus {
+    private BluetoothA2dp mA2dp = null;
+    public String getActionSinkStateChangedString (){
+        return BluetoothA2dp.ACTION_SINK_STATE_CHANGED;
+    }
+    public String getActionPlayStateChangedString (){
+        return BluetoothA2dp.ACTION_SINK_STATE_CHANGED;
+    }
+    public boolean  isA2dpStateChange( String action) {
+        if(action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED) ) {
+           return true;
+        }
+        return false;
+    }
+    public boolean  isA2dpPlayStateChange( String action) {
+        return isA2dpStateChange(action);
+    }
+    public boolean isConnected(Intent intent) {
+        boolean isConnected = false;
+        int state = intent.getIntExtra(BluetoothA2dp.EXTRA_SINK_STATE,
+                                BluetoothA2dp.STATE_DISCONNECTED);
+        if (state == BluetoothA2dp.STATE_CONNECTED ||
+                state == BluetoothA2dp.STATE_PLAYING){
+            isConnected = true;
+        }
+        return isConnected;
+    }
+    public boolean isPlaying(Intent intent) {
+        boolean isPlaying = false;
+        int state = intent.getIntExtra(BluetoothA2dp.EXTRA_SINK_STATE,
+                                BluetoothA2dp.STATE_DISCONNECTED);
+        if(state == BluetoothA2dp.STATE_PLAYING){
+            isPlaying = true;
+        }
+        return isPlaying;
+    }
+    public boolean isDeviceAvailable() {
+        if(null == mA2dp) return false;
+        Set<BluetoothDevice> sinks = mA2dp.getConnectedSinks();
+        if (sinks != null && sinks.size() != 0) {
+           return true;
+        }
+        return false;
+    }
+
+    public A2dpDeviceStatus(Context mContext) {
+        mA2dp = new BluetoothA2dp(mContext);
+    }
+
+}
diff --git a/fmapp2/src/com/caf/utils/FrequencyPicker.java b/fmapp2/src/com/caf/utils/FrequencyPicker.java
new file mode 100644
index 0000000..1ea10e8
--- /dev/null
+++ b/fmapp2/src/com/caf/utils/FrequencyPicker.java
@@ -0,0 +1,407 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.caf.utils;
+
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.widget.FrameLayout;
+
+import com.caf.fmradio_2.R;
+import android.widget.NumberPicker;
+import android.widget.NumberPicker.OnChangedListener;
+
+/**
+ * A view for selecting the frequency
+ *
+ * For a dialog using this view, see {FrequencyPickerDialog}.
+ */
+
+public class FrequencyPicker extends FrameLayout {
+
+    /* UI Components */
+    private final NumberPicker mMHzPicker;
+    private final NumberPicker mKHzPicker;
+
+    /**
+     * How we notify users the Frequency has changed.
+     */
+    private OnFrequencyChangedListener mOnFrequencyChangedListener;
+
+    private int mFrequency;
+    private int mMin;
+    private int mMax;
+    private int mStep;
+    private int mMhz;
+    private int mKhz;
+
+    /**
+     * The callback used to indicate the user changes the Frequency.
+     */
+    public interface OnFrequencyChangedListener {
+
+        /**
+         * @param view The view associated with this listener.
+         * @param frequency The Frequency that was set.
+         */
+        void onFrequencyChanged(FrequencyPicker view, int frequency);
+    }
+
+    public FrequencyPicker(Context context) {
+        this(context, null);
+    }
+
+    public FrequencyPicker(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public FrequencyPicker(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        inflater.inflate(R.layout.frequency_picker, this, true);
+
+        mMHzPicker = (NumberPicker) findViewById(R.id.mhz);
+        if (mMHzPicker != null) {
+            mMHzPicker.setSpeed(100);
+            mMHzPicker.setOnChangeListener(new OnChangedListener() {
+              public void onChanged(NumberPicker picker, int oldVal, int newVal) {
+                 mMhz = newVal;
+                 mFrequency = (mMhz * 1000) + (getFrequencyKHz(mKhz, mMin, mStep));
+                 validateFrequencyRange();
+                 if (mOnFrequencyChangedListener != null) {
+                     mOnFrequencyChangedListener.onFrequencyChanged(FrequencyPicker.this, mFrequency);
+                 }
+              }
+           });
+        }
+        mKHzPicker = (NumberPicker) findViewById(R.id.khz);
+        if (mKHzPicker != null) {
+            mKHzPicker.setSpeed(100);
+            mKHzPicker.setOnChangeListener(new OnChangedListener() {
+              public void onChanged(NumberPicker picker, int oldVal, int newVal) {
+                 mKhz = newVal;
+                 mFrequency = (mMhz * 1000) + (getFrequencyKHz(mKhz, mMin, mStep));
+
+                 validateFrequencyRange();
+
+                 if (mOnFrequencyChangedListener != null) {
+                     mOnFrequencyChangedListener.onFrequencyChanged(FrequencyPicker.this, mFrequency);
+                 }
+              }
+           });
+        }
+
+        updateSpinnerRange();
+
+        if (!isEnabled()) {
+            setEnabled(false);
+        }
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        super.setEnabled(enabled);
+        if (mMHzPicker != null) {
+            mMHzPicker.setEnabled(enabled);
+        }
+        if (mKHzPicker != null) {
+            mKHzPicker.setEnabled(enabled);
+        }
+    }
+
+
+    public void updateFrequency(int frequency) {
+        mFrequency = frequency;
+        updateSpinners();
+    }
+
+    private static class SavedState extends BaseSavedState {
+
+        private final int mMHZ;
+        private final int mKHZ;
+
+        /**
+         * Constructor called from {@link FrequencyPicker#onSaveInstanceState()}
+         */
+        private SavedState(Parcelable superState, int mhz, int khz) {
+            super(superState);
+            mMHZ = mhz;
+            mKHZ = khz;
+        }
+
+        /**
+         * Constructor called from {@link #CREATOR}
+         */
+        private SavedState(Parcel in) {
+            super(in);
+            mMHZ = in.readInt();
+            mKHZ = in.readInt();
+        }
+
+        public int getMHz() {
+            return mMHZ;
+        }
+
+        public int getKHz() {
+            return mKHZ;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeInt(mMHZ);
+            dest.writeInt(mKHZ);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+             new Creator<SavedState>() {
+
+               public SavedState createFromParcel(Parcel in) {
+                    return new SavedState(in);
+               }
+
+               public SavedState[] newArray(int size) {
+                    return new SavedState[size];
+               }
+            };
+    }
+
+
+    /**
+     * Override so we are in complete control of save / restore for this widget.
+     */
+    @Override
+    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+        dispatchThawSelfOnly(container);
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+
+        return new SavedState(superState, mMhz, mKhz);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mMhz = ss.getMHz();
+        mKhz = ss.getKHz();
+    }
+
+    private String[] getKHzStrings(int min, int stepSize)
+    {
+        if(stepSize == 100)
+        {
+           return (get100KHzStrings());
+        }
+        else if(stepSize == 50)
+        {
+           return (get50KHzStrings());
+        }
+        return (get200KHzStrings(min));
+    }
+
+    private int getKHzCount(int stepSize)
+    {
+        if(stepSize == 100)
+        {
+           return (10);
+        }
+        else if(stepSize == 50)
+        {
+           return (20);
+        }
+        return (5);
+    }
+
+    private int getCurrentKHz(int frequency, int min, int stepSize)
+    {
+        if(stepSize == 100)
+        {
+            return (getCurrent100KHz(frequency));
+        }
+        else if(stepSize == 50)
+        {
+            return (getCurrent50KHz(frequency));
+        }
+        return (getCurrent200KHz(frequency, min));
+    }
+
+    private int getFrequencyKHz(int kHz, int min, int stepSize)
+    {
+        if(stepSize == 100)
+        {
+           return (getFrequency100KHz(kHz));
+        }
+        else if(stepSize == 50)
+        {
+           return (getFrequency50KHz(kHz));
+        }
+        return (getFrequency200KHz(kHz, min));
+    }
+
+    private int getFrequency100KHz(int kHz)
+    {
+        int frequencykhz = ((kHz - 1) * 100);
+        return (frequencykhz);
+    }
+
+    private int getFrequency50KHz(int kHz)
+    {
+        int frequencykhz = ((kHz - 1) * 50);
+        return (frequencykhz);
+    }
+
+    private int getFrequency200KHz(int kHz, int min)
+    {
+        int frequencykhz = ((kHz - 1) * 200);
+        if((min % 200) != 0)
+        {
+            frequencykhz = ((kHz - 1) * 200) + 100;
+        }
+        return (frequencykhz);
+    }
+
+    private int getCurrent100KHz(int frequency)
+    {
+        int khz = ((frequency % 1000) / 100);
+        return (khz + 1);
+    }
+
+    private int getCurrent50KHz(int frequency)
+    {
+        int khz = ((frequency % 1000) / 50);
+        return (khz + 1);
+    }
+
+    private int getCurrent200KHz(int frequency, int min)
+    {
+        int khz = ((frequency % 1000) / 200);
+        return (khz + 1);
+    }
+
+    private String[] get50KHzStrings()
+    {
+        String[] khzStrings= {"00","05","10","15","20","25","30","35","40","45",
+                                                 "50","55","60","65","70","75","80","85","90","95"};
+        return khzStrings;
+    }
+
+    private String[] get100KHzStrings()
+    {
+        String[] khzStrings= {"0","1","2","3","4","5",
+                                         "6","7","8","9"};
+        return khzStrings;
+    }
+
+    private String[] get200KHzStrings(int min)
+    {
+        if((min % 200) == 0)
+        {
+           return (getEven200KHzStrings());
+        }
+        return (getOdd200KHzStrings());
+    }
+
+    private String[] getEven200KHzStrings()
+    {
+        String[] khzStrings= {"0","2","4","6","8"};
+        return khzStrings;
+    }
+    private String[] getOdd200KHzStrings()
+    {
+        String[] khzStrings= {"1","3","5","7","9"};
+        return khzStrings;
+    }
+
+    /**
+     * Initialize the state.
+     * @param year The initial year.
+     * @param monthOfYear The initial month.
+     * @param dayOfMonth The initial day of the month.
+     * @param onDateChangedListener How user is notified date is changed by user, can be null.
+     */
+    public void init(int min, int max, int step, int frequency,
+            OnFrequencyChangedListener onFrequencyChangedListener) {
+
+        mMin = min;
+        mMax = max;
+        mStep = step;
+        mFrequency = frequency;
+        mOnFrequencyChangedListener = onFrequencyChangedListener;
+
+        updateSpinners();
+    }
+    private void updateSpinnerRange() {
+        String[] khzStrings = getKHzStrings(mMin, mStep);
+        int khzNumSteps = getKHzCount(mStep);
+
+        if (mMHzPicker != null) {
+           mMHzPicker.setRange(mMin / 1000, mMax / 1000);
+        }
+        if (mKHzPicker != null) {
+           mKHzPicker.setRange(1, khzNumSteps, khzStrings);
+        }
+    }
+
+    private void updateSpinners() {
+        int khzNumSteps = getKHzCount(mStep);
+        updateSpinnerRange();
+        mMhz = (int)(mFrequency / 1000);
+        mKhz = getCurrentKHz(mFrequency, mMin, mStep) ;
+        if((mMin / 1000 <= mMhz) && (mMax / 1000 >= mMhz))
+        {
+            mMHzPicker.setCurrent(mMhz);
+        }
+        if(mKhz <= khzNumSteps)
+        {
+            mKHzPicker.setCurrent(mKhz);
+        }
+    }
+    private void validateFrequencyRange()
+    {
+        boolean bUpdateSpinner = false;
+        if(mFrequency < mMin)
+        {
+                mFrequency = mMin;
+                bUpdateSpinner = true;
+        }
+        if(mFrequency > mMax)
+        {
+                mFrequency = mMax;
+                bUpdateSpinner = true;
+        }
+        if(bUpdateSpinner == true)
+        {
+                updateSpinners();
+        }
+    }
+
+    public int getFrequency() {
+        return (mFrequency);
+    }
+}
diff --git a/fmapp2/src/com/caf/utils/FrequencyPickerDialog.java b/fmapp2/src/com/caf/utils/FrequencyPickerDialog.java
new file mode 100644
index 0000000..3c6168b
--- /dev/null
+++ b/fmapp2/src/com/caf/utils/FrequencyPickerDialog.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ *
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.caf.utils;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import qcom.fmradio.FmConfig;
+import qcom.fmradio.FmReceiver;
+
+import com.caf.fmradio.R;
+import com.caf.utils.FrequencyPicker.OnFrequencyChangedListener;
+
+/**
+ * A simple dialog containing an FrequencyPicker.
+ */
+public class FrequencyPickerDialog extends AlertDialog implements OnClickListener,
+OnFrequencyChangedListener {
+
+    private static final String FREQUENCY = "FREQUENCY";
+    private static final String FREQ_MIN = "FREQ_MIN";
+    private static final String FREQ_MAX = "FREQ_MAX";
+    private static final String FREQ_STEP = "FREQ_STEP";
+
+    private final FrequencyPicker mFrequencyPicker;
+    private final OnFrequencySetListener mCallBack;
+    private int mMinFrequency;
+    private int mMaxFrequency;
+    private int mChannelSpacing;
+
+    /**
+     * The callback used to indicate the user is done filling in the date.
+     */
+    public interface OnFrequencySetListener {
+
+        void onFrequencySet(FrequencyPicker view, int frequency);
+    }
+    /**
+     */
+    public FrequencyPickerDialog(Context context,
+                                                            FmConfig fmConfig,
+                                                            int frequency,
+                                 OnFrequencySetListener callback) {
+        //this(context, android.R.style.Theme_Dialog, fmConfig, frequency, callback);
+       this(context, com.android.internal.R.style.Theme_Dialog_Alert, fmConfig, frequency, callback);
+    }
+
+    /**
+     */
+    public FrequencyPickerDialog(Context context,
+            int theme,
+            FmConfig fmConfig,
+                        int frequency,
+                        OnFrequencySetListener callback) {
+        super(context, theme);
+        mMinFrequency = fmConfig.getLowerLimit();
+        mMaxFrequency = fmConfig.getUpperLimit();
+        mChannelSpacing = 200;
+        if(FmReceiver.FM_CHSPACE_200_KHZ == fmConfig.getChSpacing())
+        {
+                mChannelSpacing = 200;
+        }
+        else if(FmReceiver.FM_CHSPACE_100_KHZ == fmConfig.getChSpacing())
+        {
+                mChannelSpacing = 100;
+        }
+        else if(FmReceiver.FM_CHSPACE_50_KHZ == fmConfig.getChSpacing())
+        {
+                mChannelSpacing = 50;
+        }
+        int MHz = frequency/1000;
+        int KHz = (frequency%1000)/100;
+            setTitle("FM - "+MHz+"."+KHz);
+        mCallBack = callback;
+
+        setButton("Set", this);
+        setButton2("Cancel", (OnClickListener) null);
+        setIcon(R.drawable.alert_dialog_icon);
+
+        LayoutInflater inflater =
+                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        View view = inflater.inflate(R.layout.frequency_picker_dialog, null);
+        setView(view);
+        mFrequencyPicker = (FrequencyPicker) view.findViewById(R.id.frequencyPicker);
+        if(mFrequencyPicker != null)
+        {
+                mFrequencyPicker.init(mMinFrequency, mMaxFrequency, mChannelSpacing, frequency, this);
+        }
+        else
+        {
+            Log.e("fmRadio", "Failed to find ID: R.id.frequencyPicker");
+        }
+    }
+
+    public void UpdateFrequency(int frequency)
+    {
+        int MHz = frequency/1000;
+        int KHz = (frequency%1000)/100;
+            setTitle("FM - "+MHz+"."+KHz);
+            mFrequencyPicker.updateFrequency(frequency);
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        if (mCallBack != null) {
+            mFrequencyPicker.clearFocus();
+            int frequency = mFrequencyPicker.getFrequency();
+            mCallBack.onFrequencySet(mFrequencyPicker, frequency);
+        }
+    }
+
+    public void onFrequencyChanged(FrequencyPicker view, int frequency) {
+            UpdateFrequency(frequency);
+    }
+
+    @Override
+    public Bundle onSaveInstanceState() {
+        Bundle state = super.onSaveInstanceState();
+        state.putInt(FREQUENCY, mFrequencyPicker.getFrequency());
+        state.putInt(FREQ_MIN, mMinFrequency);
+        state.putInt(FREQ_MAX, mMaxFrequency);
+        state.putInt(FREQ_STEP, mChannelSpacing);
+        return state;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        int frequency = savedInstanceState.getInt(FREQUENCY);
+        mMinFrequency = savedInstanceState.getInt(FREQ_MIN);
+        mMaxFrequency = savedInstanceState.getInt(FREQ_MAX );
+        mChannelSpacing = savedInstanceState.getInt(FREQ_STEP);
+        mFrequencyPicker.init(mMinFrequency, mMaxFrequency, mChannelSpacing, frequency, this);
+        int MHz = frequency/1000;
+        int KHz = (frequency%1000)/100;
+            setTitle("FM - "+MHz+"."+KHz);
+    }
+}