FM: New mechanism to handle FM recording

- FM Radio is running with system process.
- System process does not have permission to access SDCard.
- Handle the FM recording in another application.

Change-Id: Ie321143b4a2601f2c669292154510eef8cbf7940
CRs-Fixed: 515621
diff --git a/Android.mk b/Android.mk
index 7ba73d6..a08bbc1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -17,4 +17,6 @@
 include $(LOCAL_PATH)/fmapp/Android.mk
 LOCAL_PATH := $(LOCAL_DIR_PATH)
 include $(LOCAL_PATH)/fmapp2/Android.mk
+LOCAL_PATH := $(LOCAL_DIR_PATH)
+include $(LOCAL_PATH)/FMRecord/Android.mk
 endif # is-vendor-board-platform
diff --git a/FMRecord/Android.mk b/FMRecord/Android.mk
new file mode 100644
index 0000000..00837f0
--- /dev/null
+++ b/FMRecord/Android.mk
@@ -0,0 +1,14 @@
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src/com/codeaurora/fmrecording/)
+
+LOCAL_PACKAGE_NAME := FMRecord
+LOCAL_CERTIFICATE := platform
+LOCAL_PROGUARD_ENABLED := disabled
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/FMRecord/AndroidManifest.xml b/FMRecord/AndroidManifest.xml
new file mode 100644
index 0000000..beb0cf7
--- /dev/null
+++ b/FMRecord/AndroidManifest.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.codeaurora.fmrecording" >
+      <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+      <uses-permission android:name="android.permission.RECORD_AUDIO" />
+      <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+      <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+
+<application>
+
+<receiver android:name="FMRecordingReceiver">
+      <intent-filter>
+         <action android:name="codeaurora.intent.action.FM" />
+      </intent-filter>
+</receiver>
+
+<service android:name="com.codeaurora.fmrecording.FMRecordingService"></service>
+</application>
+</manifest>
diff --git a/FMRecord/res/values/strings.xml b/FMRecord/res/values/strings.xml
new file mode 100644
index 0000000..59f14ad
--- /dev/null
+++ b/FMRecord/res/values/strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- 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>
+    <!-- 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="save_record_file">FM Recorded file saved to "<xliff:g id="record_file">%1$s</xliff:g>"</string>
+</resources>
diff --git a/FMRecord/src/com/codeaurora/fmrecording/FMRecordingReceiver.java b/FMRecord/src/com/codeaurora/fmrecording/FMRecordingReceiver.java
new file mode 100644
index 0000000..9389f10
--- /dev/null
+++ b/FMRecord/src/com/codeaurora/fmrecording/FMRecordingReceiver.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 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.codeaurora.fmrecording;
+
+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 java.lang.String;
+
+
+public class FMRecordingReceiver extends BroadcastReceiver {
+
+    private static final String TAG = "FMRecordingReceiver";
+    public static final String ACTION_FM =
+           "codeaurora.intent.action.FM";
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        Log.d(TAG, "Received intent: " + action);
+        if((action != null) && action.equals(ACTION_FM)) {
+            Log.d(TAG, "FM intent received");
+            Intent in = new Intent();
+            in.putExtras(intent);
+            in.setClass(context, FMRecordingService.class);
+            int state = intent.getIntExtra("state", 0);
+            boolean startService = true;
+
+            if (state == 1) {
+                Log.d(TAG, "FM ON intent received");
+                startService = true;
+                context.startService(in);
+            } else if(state == 0){
+                Log.d(TAG, "FM OFF intent received");
+                startService = false;
+                context.stopService(in);
+            }
+        }
+   }
+}
diff --git a/FMRecord/src/com/codeaurora/fmrecording/FMRecordingService.java b/FMRecord/src/com/codeaurora/fmrecording/FMRecordingService.java
new file mode 100644
index 0000000..2b0d00a
--- /dev/null
+++ b/FMRecord/src/com/codeaurora/fmrecording/FMRecordingService.java
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 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.codeaurora.fmrecording;
+
+import java.util.*;
+import android.app.Service;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+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.util.Log;
+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 java.io.File;
+import android.widget.Toast;
+import android.os.UserHandle;
+import android.net.Uri;
+import android.content.res.Resources;
+import android.os.StatFs;
+
+public class FMRecordingService extends Service {
+    private static final String TAG     = "FMRecordingService";
+    private BroadcastReceiver mFmRecordingReceiver = null;
+    private BroadcastReceiver mSdcardUnmountReceiver = null;
+    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 boolean mFmRecordingOn = false;
+    public static final String ACTION_FM_RECORDING =
+                       "codeaurora.intent.action.FM_Recording";
+    public static final String ACTION_FM_RECORDING_STATUS =
+                "codeaurora.intent.action.FM.Recording.Status";
+
+    private File mSampleFile = null;
+    private MediaRecorder mRecorder = null;
+    long mSampleStart = 0;
+    static final int START = 1;
+    static final int STOP = 0;
+
+    public void onCreate() {
+
+        super.onCreate();
+        Log.d(TAG, "FMRecording Service onCreate");
+        registerRecordingListner();
+        registerExternalStorageListener();
+    }
+
+    public int onStartCommand(Intent intent, int flags, int startId) {
+
+        Log.d(TAG, "FMRecording Service onCreate");
+        return START_NOT_STICKY;
+    }
+
+    public void onDestroy() {
+        Log.d(TAG, "FMRecording Service onDestroy");
+        if (mFmRecordingOn == true) {
+            Log.d(TAG, "Still recording on progress, Stoping it");
+            stopRecord();
+        }
+        unregisterBroadCastReceiver(mFmRecordingReceiver);
+        unregisterBroadCastReceiver(mSdcardUnmountReceiver);
+        super.onDestroy();
+    }
+
+    public IBinder onBind(Intent intent) {
+        Log.v(TAG, "FMRecording Service onBind");
+        return null;
+    }
+
+   private void unregisterBroadCastReceiver(BroadcastReceiver myreceiver) {
+
+       if (myreceiver != null) {
+           unregisterReceiver(myreceiver);
+           myreceiver = null;
+       }
+   }
+    /**
+      * 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.
+      */
+    private 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(TAG, "ACTION_MEDIA_UNMOUNTED Intent received");
+                         if (mFmRecordingOn == true) {
+                             try {
+                                  stopRecord();
+                             } 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);
+        }
+    }
+
+    private static long getAvailableSpace() {
+        String state = Environment.getExternalStorageState();
+        Log.d(TAG, "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(TAG, "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;
+    }
+
+    private void sendRecordingStatusIntent(int status) {
+        Intent intent = new Intent(ACTION_FM_RECORDING_STATUS);
+        intent.putExtra("state", status);
+        Log.d(TAG, "posting intent for FM Recording status as = " +status);
+        getApplicationContext().sendBroadcastAsUser(intent, UserHandle.ALL);
+    }
+    private boolean startRecord() {
+
+        Log.d(TAG, "Enter startRecord");
+        if (mRecorder != null) { /* Stop existing recording if any */
+            Log.d(TAG, "Stopping existing record");
+            try {
+                 mRecorder.stop();
+                 mRecorder.reset();
+                 mRecorder.release();
+                 mRecorder = null;
+            } catch(Exception e) {
+                 e.printStackTrace();
+            }
+        }
+        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();
+
+        try {
+             mSampleFile = File.createTempFile("FMRecording", ".3gpp", sampleDir);
+        } catch (IOException e) {
+             Log.e(TAG, "Not able to access SD Card");
+             Toast.makeText(this, "Not able to access SD Card", Toast.LENGTH_SHORT).show();
+        }
+        try {
+             Log.d(TAG, "AudioSource.FM_RX" +MediaRecorder.AudioSource.FM_RX);
+             mRecorder.setAudioSource(MediaRecorder.AudioSource.FM_RX);
+             mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+             mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
+        } catch (RuntimeException exception) {
+             Log.d(TAG, "RuntimeException while settings");
+             mRecorder.reset();
+             mRecorder.release();
+             mRecorder = null;
+             return false;
+        }
+        Log.d(TAG, "setOutputFile");
+        mRecorder.setOutputFile(mSampleFile.getAbsolutePath());
+        try {
+             mRecorder.prepare();
+             Log.d(TAG, "start");
+             mRecorder.start();
+        } catch (IOException e) {
+             Log.d(TAG, "IOException while start");
+             mRecorder.reset();
+             mRecorder.release();
+             mRecorder = null;
+             return false;
+        } catch (RuntimeException e) {
+             Log.d(TAG, "RuntimeException while start");
+             mRecorder.reset();
+             mRecorder.release();
+             mRecorder = null;
+             return false;
+        }
+        mFmRecordingOn = true;
+        Log.d(TAG, "mSampleFile.getAbsolutePath() " +mSampleFile.getAbsolutePath());
+        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(TAG, "Maximum file size/duration reached, stopping the recording");
+                         stopRecord();
+                     }
+                     // Show the toast.
+                     Toast.makeText(FMRecordingService.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(TAG, "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) {
+                         stopRecord();
+                     }
+                     updateAndShowStorageHint();
+                 }
+             }
+        });
+        mSampleStart = System.currentTimeMillis();
+        sendRecordingStatusIntent(START);
+        return true;
+    }
+
+    private void stopRecord() {
+        Log.d(TAG, "Enter stopRecord");
+        mFmRecordingOn = false;
+        if (mRecorder == null)
+            return;
+        try {
+             mRecorder.stop();
+             mRecorder.reset();
+             mRecorder.release();
+             mRecorder = null;
+        } catch(Exception e) {
+             e.printStackTrace();
+        }
+
+        sendRecordingStatusIntent(STOP);
+        saveFile();
+    }
+
+    private void saveFile() {
+        int sampleLength = (int)((System.currentTimeMillis() - mSampleStart)/1000 );
+        Log.d(TAG, "Enter saveFile");
+        if (sampleLength == 0)
+            return;
+        String state = Environment.getExternalStorageState();
+        Log.d(TAG, "storage state is " + state);
+
+        if (Environment.MEDIA_MOUNTED.equals(state)) {
+            try {
+                 this.addToMediaDB(mSampleFile);
+                 Toast.makeText(this,getString(R.string.save_record_file,
+                                               mSampleFile.getAbsolutePath( )),
+                                               Toast.LENGTH_LONG).show();
+            } catch(Exception e) {
+                 e.printStackTrace();
+            }
+        } else {
+            Log.e(TAG, "SD card must have removed during recording. ");
+            Toast.makeText(this, "Recording aborted", Toast.LENGTH_SHORT).show();
+        }
+        return;
+    }
+
+    /*
+     * Adds file and returns content uri.
+     */
+    private Uri addToMediaDB(File file) {
+        Log.d(TAG, "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(TAG, "Inserting audio record: " + cv.toString());
+        ContentResolver resolver = getContentResolver();
+        Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
+        Log.d(TAG, "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(TAG, "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 registerRecordingListner() {
+        if (mFmRecordingReceiver == null) {
+            mFmRecordingReceiver = new BroadcastReceiver() {
+                 @Override
+                 public void onReceive(Context context, Intent intent) {
+                     Log.d(TAG, "Received intent " +intent);
+                     String action = intent.getAction();
+                     Log.d(TAG, " action = " +action);
+                     if (action.equals(ACTION_FM_RECORDING)) {
+                         int state = intent.getIntExtra("state", STOP);
+                         Log.d(TAG, "ACTION_FM_RECORDING Intent received" +state);
+                         if (state == START) {
+                             Log.d(TAG, "Recording start");
+                             startRecord();
+                         } else if (state == STOP) {
+                             Log.d(TAG, "Stop recording");
+                             stopRecord();
+                         }
+                     }
+                 }
+            };
+            IntentFilter iFilter = new IntentFilter();
+            iFilter.addAction(ACTION_FM_RECORDING);
+            registerReceiver(mFmRecordingReceiver, iFilter);
+        }
+    }
+
+}
diff --git a/fmapp/AndroidManifest.xml b/fmapp/AndroidManifest.xml
index d0232bc..6c0f4f8 100644
--- a/fmapp/AndroidManifest.xml
+++ b/fmapp/AndroidManifest.xml
@@ -41,6 +41,8 @@
     <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"/>
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
 
     <application
         android:icon="@drawable/ic_launcher_fmradio"
diff --git a/fmapp/src/com/codeaurora/fmradio/FMRadio.java b/fmapp/src/com/codeaurora/fmradio/FMRadio.java
index d592bc2..408cf04 100644
--- a/fmapp/src/com/codeaurora/fmradio/FMRadio.java
+++ b/fmapp/src/com/codeaurora/fmradio/FMRadio.java
@@ -2139,20 +2139,20 @@
       {
          try
          {
-           mRecording = mService.startRecording();
+           mService.startRecording();
          } catch (RemoteException e)
          {
             e.printStackTrace();
          }
-         //Initiate record timer thread here
-         if( mRecording == true ) {
-             int durationInMins = FmSharedPreferences.getRecordDuration();
-             Log.e(LOGTAG, " Fected duration:" + durationInMins );
-             initiateRecordDurationTimer( durationInMins );
-         }
       }
    }
 
+   private void startRecordingTimer() {
+      mRecording = true;
+      int durationInMins = FmSharedPreferences.getRecordDuration();
+      Log.e(LOGTAG, " Fected duration:" + durationInMins );
+      initiateRecordDurationTimer( durationInMins );
+   }
    private void stopRecording() {
        mRecording = false;
        DebugToasts("Stopped Recording", Toast.LENGTH_SHORT);
@@ -3591,5 +3591,10 @@
          Log.d(LOGTAG, "mServiceCallbacks.onRecordingStopped:");
          stopRecording();
       }
+      public void onRecordingStarted()
+      {
+         Log.d(LOGTAG, "mServiceCallbacks.onRecordingStarted:");
+         startRecordingTimer();
+      }
    };
 }
diff --git a/fmapp/src/com/codeaurora/fmradio/FMRadioService.java b/fmapp/src/com/codeaurora/fmradio/FMRadioService.java
index d467162..e15117d 100644
--- a/fmapp/src/com/codeaurora/fmradio/FMRadioService.java
+++ b/fmapp/src/com/codeaurora/fmradio/FMRadioService.java
@@ -78,6 +78,10 @@
 import android.content.ComponentName;
 import android.os.StatFs;
 import android.os.SystemClock;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.app.IntentService;
+import android.os.UserHandle;
 
 /**
  * Provides "background" FM Radio (that uses the hardware) capabilities,
@@ -160,6 +164,16 @@
    private static final String SLEEP_EXPIRED_ACTION = "com.codeaurora.fmradio.SLEEP_EXPIRED";
    private static final String RECORD_EXPIRED_ACTION = "com.codeaurora.fmradio.RECORD_TIMEOUT";
    private static final String SERVICE_DELAYED_STOP_ACTION = "com.codeaurora.fmradio.SERVICE_STOP";
+   public static final String ACTION_FM =
+               "codeaurora.intent.action.FM";
+   public static final String ACTION_FM_RECORDING =
+           "codeaurora.intent.action.FM_Recording";
+   public static final String ACTION_FM_RECORDING_STATUS =
+           "codeaurora.intent.action.FM.Recording.Status";
+   private String mFilePath = "";
+   private BroadcastReceiver mFmRecordingStatus  = null;
+   static final int RECORD_START = 1;
+   static final int RECORD_STOP = 0;
 
    public FMRadioService() {
    }
@@ -184,7 +198,7 @@
       registerSleepExpired();
       registerRecordTimeout();
       registerDelayedServiceStop();
-      registerExternalStorageListener();
+      registerFMRecordingStatus();
       // registering media button receiver seperately as we need to set
       // different priority for receiving media events
       registerFmMediaButtonReceiver();
@@ -233,10 +247,6 @@
           unregisterReceiver(mHeadsetReceiver);
           mHeadsetReceiver = null;
       }
-      if( mSdcardUnmountReceiver != null ) {
-          unregisterReceiver(mSdcardUnmountReceiver);
-          mSdcardUnmountReceiver = null;
-      }
       if( mMusicCommandListener != null ) {
           unregisterReceiver(mMusicCommandListener);
           mMusicCommandListener = null;
@@ -257,6 +267,10 @@
           unregisterReceiver(mDelayedServiceStopListener);
           mDelayedServiceStopListener = null;
       }
+      if (mFmRecordingStatus != null ) {
+          unregisterReceiver(mFmRecordingStatus);
+          mFmRecordingStatus = null;
+      }
       /* Since the service is closing, disable the receiver */
       fmOff();
 
@@ -270,38 +284,46 @@
       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() {
+   public void registerFMRecordingStatus() {
+         if (mFmRecordingStatus == null) {
+             mFmRecordingStatus = new BroadcastReceiver() {
                  @Override
                  public void onReceive(Context context, Intent intent) {
+                     Log.d(LOGTAG, "received 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) {
+                     if (action.equals(ACTION_FM_RECORDING_STATUS)) {
+                         Log.d(LOGTAG, "ACTION_FM_RECORDING_STATUS Intent received");
+                         int state = intent.getIntExtra("state", 0);
+                         if (state == RECORD_START) {
+                             Log.d(LOGTAG, "FM Recording started");
+                             mFmRecordingOn = true;
                              try {
-                                  stopRecording();
-                             } catch (Exception e) {
+                                  if ((mServiceInUse) && (mCallbacks != null) ) {
+                                      Log.d(LOGTAG, "start recording thread");
+                                      mCallbacks.onRecordingStarted();
+                                  } 
+                             } catch (RemoteException e) {
                                   e.printStackTrace();
                              }
-                         }
+                         } else if (state == RECORD_STOP) {
+                             Log.d(LOGTAG, "FM Recording stopped");
+                             mFmRecordingOn = false;
+                             try {
+                                  if ((mServiceInUse) && (mCallbacks != null) ) {
+                                     mCallbacks.onRecordingStopped();
+                                  }
+                             } catch (RemoteException 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);
+             iFilter.addAction(ACTION_FM_RECORDING_STATUS);
+             registerReceiver(mFmRecordingStatus , iFilter);
          }
-     }
-
+   }
 
      /**
      * Registers an intent to listen for ACTION_HEADSET_PLUG
@@ -666,6 +688,20 @@
       return true;
    }
 
+   private void sendRecordIntent(int action) {
+       Intent intent = new Intent(ACTION_FM_RECORDING);
+       intent.putExtra("state", action);
+       Log.d(LOGTAG, "Sending Recording intent for = " +action);
+       getApplicationContext().sendBroadcast(intent);
+   }
+
+   private void sendRecordServiceIntent(int action) {
+       Intent intent = new Intent(ACTION_FM);
+       intent.putExtra("state", action);
+       Log.d(LOGTAG, "Sending Recording intent for = " +action);
+       getApplicationContext().sendBroadcast(intent);
+   }
+
    private void startFM(){
        Log.d(LOGTAG, "In startFM");
        if(true == mAppShutdown) { // not to send intent to AudioManager in Shutdown
@@ -703,6 +739,7 @@
            }
            AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
                                      AudioSystem.DEVICE_STATE_AVAILABLE, "");
+           sendRecordServiceIntent(RECORD_START);
        }
        mPlaybackInProgress = true;
    }
@@ -716,6 +753,7 @@
            Log.d(LOGTAG, "FMRadio: Requesting to stop FM");
            AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
                                     AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
+           sendRecordServiceIntent(RECORD_STOP);
        }
        mPlaybackInProgress = false;
    }
@@ -729,105 +767,23 @@
           Log.d(LOGTAG, "FMRadio: Requesting to stop FM");
           AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
                                     AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
+          sendRecordServiceIntent(RECORD_STOP);
        }
        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;
+   public void 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;
        }
-        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;
-  }
+       sendRecordIntent(RECORD_START);
+   }
 
    public boolean startA2dpPlayback() {
         Log.d(LOGTAG, "In startA2dpPlayback");
@@ -925,197 +881,13 @@
        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)
+       if (!mFmRecordingOn)
            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);
-               Toast.makeText(this,getString(R.string.save_record_file, mSampleFile.getAbsolutePath()),
-                          Toast.LENGTH_LONG).show();
-          }
-          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();
-       }
+       sendRecordIntent(RECORD_STOP);
        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.
@@ -1480,9 +1252,9 @@
          return(mService.get().isMuted());
       }
 
-      public boolean startRecording()
+      public void startRecording()
       {
-         return(mService.get().startRecording());
+         mService.get().startRecording();
       }
 
       public void stopRecording()
@@ -1870,7 +1642,7 @@
 
       if (isFmRecordingOn())
       {
-          resetRecording();
+          stopRecording();
       }
 
       AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
diff --git a/fmapp/src/com/codeaurora/fmradio/FMStats.java b/fmapp/src/com/codeaurora/fmradio/FMStats.java
index 2306907..a68ccc4 100644
--- a/fmapp/src/com/codeaurora/fmradio/FMStats.java
+++ b/fmapp/src/com/codeaurora/fmradio/FMStats.java
@@ -2062,6 +2062,10 @@
           {
              Log.d(LOGTAG, "mServiceCallbacks.onFinishActivity:");
           }
+          public void onRecordingStarted()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onRecordingStarted:");
+          }
       };
       /* Radio Vars */
      final Handler mHandler = new Handler();
diff --git a/fmapp/src/com/codeaurora/fmradio/IFMRadioService.aidl b/fmapp/src/com/codeaurora/fmradio/IFMRadioService.aidl
index 79d83f7..d80c320 100644
--- a/fmapp/src/com/codeaurora/fmradio/IFMRadioService.aidl
+++ b/fmapp/src/com/codeaurora/fmradio/IFMRadioService.aidl
@@ -46,7 +46,7 @@
     boolean routeAudio(int device);
     boolean unMute();
     boolean isMuted();
-    boolean startRecording();
+    void startRecording();
     void stopRecording();
     boolean tune(int frequency);
     boolean seek(boolean up);
diff --git a/fmapp/src/com/codeaurora/fmradio/IFMRadioServiceCallbacks.aidl b/fmapp/src/com/codeaurora/fmradio/IFMRadioServiceCallbacks.aidl
index eb782e8..4d116ec 100644
--- a/fmapp/src/com/codeaurora/fmradio/IFMRadioServiceCallbacks.aidl
+++ b/fmapp/src/com/codeaurora/fmradio/IFMRadioServiceCallbacks.aidl
@@ -45,4 +45,5 @@
   void onStationRDSSupported(boolean bRDSSupported);
   void onRecordingStopped();
   void onExtenRadioTextChanged();
+  void onRecordingStarted();
 }
diff --git a/fmapp2/AndroidManifest.xml b/fmapp2/AndroidManifest.xml
index 4cef8c0..b377b9d 100644
--- a/fmapp2/AndroidManifest.xml
+++ b/fmapp2/AndroidManifest.xml
@@ -42,6 +42,8 @@
     <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"/>
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
 
     <application
         android:icon="@drawable/ic_launcher_fmradio"
diff --git a/fmapp2/src/com/caf/fmradio/FMRadio.java b/fmapp2/src/com/caf/fmradio/FMRadio.java
index caa9bb2..631ab40 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadio.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadio.java
@@ -1768,21 +1768,20 @@
    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 );
+              mService.startRecording();
+         } catch (RemoteException e) {
+              e.printStackTrace();
          }
       }
    }
 
+   private void startRecordingTimer() {
+      mRecording = true;
+      int durationInMins = FmSharedPreferences.getRecordDuration();
+      Log.e(LOGTAG, " Fected duration:" + durationInMins );
+      initiateRecordDurationTimer( durationInMins );
+   }
+
    private void stopRecording() {
        mRecording = false;
        DebugToasts("Stopped Recording", Toast.LENGTH_SHORT);
@@ -3033,5 +3032,10 @@
          Log.d(LOGTAG, "mServiceCallbacks.onRecordingStopped:");
          stopRecording();
       }
+      public void onRecordingStarted()
+      {
+         Log.d(LOGTAG, "mServiceCallbacks.onRecordingStarted:");
+         startRecordingTimer();
+      }
    };
 }
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
index 5d971cf..54b9aed 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadioService.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -41,6 +41,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.app.IntentService;
+import android.os.UserHandle;
 import android.content.BroadcastReceiver;
 import android.media.AudioManager;
 import android.media.AudioManager.OnAudioFocusChangeListener;
@@ -160,6 +162,15 @@
    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 static final String ACTION_FM =
+               "codeaurora.intent.action.FM";
+   public static final String ACTION_FM_RECORDING =
+           "codeaurora.intent.action.FM_Recording";
+   public static final String ACTION_FM_RECORDING_STATUS =
+           "codeaurora.intent.action.FM.Recording.Status";
+   private BroadcastReceiver mFmRecordingStatus  = null;
+   static final int RECORD_START = 1;
+   static final int RECORD_STOP = 0;
 
    public FMRadioService() {
    }
@@ -184,7 +195,7 @@
       registerSleepExpired();
       registerRecordTimeout();
       registerDelayedServiceStop();
-      registerExternalStorageListener();
+      registerFMRecordingStatus();
       // registering media button receiver seperately as we need to set
       // different priority for receiving media events
       registerFmMediaButtonReceiver();
@@ -233,10 +244,6 @@
           unregisterReceiver(mHeadsetReceiver);
           mHeadsetReceiver = null;
       }
-      if( mSdcardUnmountReceiver != null ) {
-          unregisterReceiver(mSdcardUnmountReceiver);
-          mSdcardUnmountReceiver = null;
-      }
       if( mMusicCommandListener != null ) {
           unregisterReceiver(mMusicCommandListener);
           mMusicCommandListener = null;
@@ -257,6 +264,10 @@
           unregisterReceiver(mDelayedServiceStopListener);
           mDelayedServiceStopListener = null;
       }
+      if (mFmRecordingStatus != null ) {
+          unregisterReceiver(mFmRecordingStatus);
+          mFmRecordingStatus = null;
+      }
       /* Since the service is closing, disable the receiver */
       fmOff();
 
@@ -270,38 +281,46 @@
       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() {
+   public void registerFMRecordingStatus() {
+         if (mFmRecordingStatus == null) {
+             mFmRecordingStatus = new BroadcastReceiver() {
                  @Override
                  public void onReceive(Context context, Intent intent) {
+                     Log.d(LOGTAG, "received 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) {
+                     if (action.equals(ACTION_FM_RECORDING_STATUS)) {
+                         Log.d(LOGTAG, "ACTION_FM_RECORDING_STATUS Intent received");
+                         int state = intent.getIntExtra("state", 0);
+                         if (state == RECORD_START) {
+                             Log.d(LOGTAG, "FM Recording started");
+                             mFmRecordingOn = true;
                              try {
-                                  stopRecording();
-                             } catch (Exception e) {
+                                  if ((mServiceInUse) && (mCallbacks != null) ) {
+                                      Log.d(LOGTAG, "start recording thread");
+                                      mCallbacks.onRecordingStarted();
+                                  }
+                             } catch (RemoteException e) {
                                   e.printStackTrace();
                              }
-                         }
+                         } else if (state == RECORD_STOP) {
+                             Log.d(LOGTAG, "FM Recording stopped");
+                             mFmRecordingOn = false;
+                             try {
+                                  if ((mServiceInUse) && (mCallbacks != null) ) {
+                                     mCallbacks.onRecordingStopped();
+                                  }
+                             } catch (RemoteException 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);
+             iFilter.addAction(ACTION_FM_RECORDING_STATUS);
+             registerReceiver(mFmRecordingStatus , iFilter);
          }
-     }
-
+   }
 
      /**
      * Registers an intent to listen for ACTION_HEADSET_PLUG
@@ -666,6 +685,20 @@
       return true;
    }
 
+   private void sendRecordIntent(int action) {
+       Intent intent = new Intent(ACTION_FM_RECORDING);
+       intent.putExtra("state", action);
+       Log.d(LOGTAG, "Sending Recording intent for = " +action);
+       getApplicationContext().sendBroadcast(intent);
+   }
+
+   private void sendRecordServiceIntent(int action) {
+       Intent intent = new Intent(ACTION_FM);
+       intent.putExtra("state", action);
+       Log.d(LOGTAG, "Sending Recording intent for = " +action);
+       getApplicationContext().sendBroadcast(intent);
+   }
+
    private void startFM(){
        Log.d(LOGTAG, "In startFM");
        if(true == mAppShutdown) { // not to send intent to AudioManager in Shutdown
@@ -703,6 +736,7 @@
            }
            AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
                                AudioSystem.DEVICE_STATE_AVAILABLE, "");
+           sendRecordServiceIntent(RECORD_START);
        }
        mPlaybackInProgress = true;
    }
@@ -716,6 +750,7 @@
            Log.d(LOGTAG, "FMRadio: Requesting to stop FM");
            AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
                                      AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
+           sendRecordServiceIntent(RECORD_STOP);
        }
        mPlaybackInProgress = false;
    }
@@ -729,105 +764,23 @@
            Log.d(LOGTAG, "FMRadio: Requesting to stop FM");
            AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
                                      AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
+           sendRecordServiceIntent(RECORD_STOP);
        }
        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;
+   public void 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;
        }
-        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;
-  }
+       sendRecordIntent(RECORD_START);
+   }
 
    public boolean startA2dpPlayback() {
         Log.d(LOGTAG, "In startA2dpPlayback");
@@ -925,195 +878,13 @@
        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)
+       if (!mFmRecordingOn)
            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();
-       }
+       sendRecordIntent(RECORD_STOP);
        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.
@@ -1468,9 +1239,9 @@
          return(mService.get().isMuted());
       }
 
-      public boolean startRecording()
+      public void startRecording()
       {
-         return(mService.get().startRecording());
+         mService.get().startRecording();
       }
 
       public void stopRecording()
@@ -1790,7 +1561,7 @@
 
       if (isFmRecordingOn())
       {
-          resetRecording();
+          stopRecording();
       }
 
       AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
diff --git a/fmapp2/src/com/caf/fmradio/FMStats.java b/fmapp2/src/com/caf/fmradio/FMStats.java
index 2afb301..feb6aab 100644
--- a/fmapp2/src/com/caf/fmradio/FMStats.java
+++ b/fmapp2/src/com/caf/fmradio/FMStats.java
@@ -1290,6 +1290,10 @@
           {
              Log.d(LOGTAG, "mServiceCallbacks.onFinishActivity:");
           }
+          public void onRecordingStarted()
+          {
+             Log.d(LOGTAG, "mServiceCallbacks.onRecordingStarted:");
+          }
       };
       /* Radio Vars */
      final Handler mHandler = new Handler();
diff --git a/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl b/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl
index 7358149..8e2fe99 100644
--- a/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl
+++ b/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl
@@ -18,7 +18,7 @@
     boolean routeAudio(int device);
     boolean unMute();
     boolean isMuted();
-    boolean startRecording();
+    void startRecording();
     void stopRecording();
     boolean tune(int frequency);
     boolean seek(boolean up);
diff --git a/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl b/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl
index 1926f24..4b9d2f0 100644
--- a/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl
+++ b/fmapp2/src/com/caf/fmradio/IFMRadioServiceCallbacks.aidl
@@ -45,4 +45,5 @@
   void onStationRDSSupported(boolean bRDSSupported);
   void onRecordingStopped();
   void onExtenRadioTextChanged();
+  void onRecordingStarted();
 }