Merge tag 'AU_LINUX_ANDROID_LA.HB.1.1.1.05.01.01.063.362' into HEAD
* commit '6c5cd5c66629b5f802fa4a2dbba72aaccd3c4635':
FM: Handle the airplane mode change gracefully
Change-Id: If740e101942cef9add243b33b55378a2665fcf9b
diff --git a/Android.mk b/Android.mk
index 027bddf..4777981 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,13 +1,14 @@
-ifneq ($(TARGET_USES_AOSP),true)
-
-ifeq ($(BOARD_HAVE_QCOM_FM),true)
-ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM)))
LOCAL_PATH:= $(call my-dir)
LOCAL_DIR_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
+#ifneq ($(TARGET_USES_AOSP),true)
+
+#ifeq ($(BOARD_HAVE_QCOM_FM),true)
+#ifneq (,$(filter $(QCOM_BOARD_PLATFORMS),$(TARGET_BOARD_PLATFORM)))
+
LOCAL_SRC_FILES := $(call all-java-files-under, qcom/fmradio)
LOCAL_JNI_SHARED_LIBRARIES := libqcomfm_jni
@@ -18,11 +19,12 @@
include $(LOCAL_PATH)/jni/Android.mk
LOCAL_PATH := $(LOCAL_DIR_PATH)
include $(LOCAL_PATH)/fmapp2/Android.mk
-LOCAL_PATH := $(LOCAL_DIR_PATH)
-include $(LOCAL_PATH)/FMRecord/Android.mk
+#LOCAL_PATH := $(LOCAL_DIR_PATH)
+#include $(LOCAL_PATH)/FMRecord/Android.mk
+#endif # is-vendor-board-platform
+#endif # BOARD_HAVE_QCOM_FM
+
+#endif # Not (TARGET_USES_AOSP)
+
LOCAL_PATH := $(LOCAL_DIR_PATH)
include $(LOCAL_PATH)/libfm_jni/Android.mk
-endif # is-vendor-board-platform
-endif # BOARD_HAVE_QCOM_FM
-
-endif # Not (TARGET_USES_AOSP)
diff --git a/FMRecord/res/layout/record_status_bar.xml b/FMRecord/res/layout/record_status_bar.xml
index d2e1151..9651fd0 100644
--- a/FMRecord/res/layout/record_status_bar.xml
+++ b/FMRecord/res/layout/record_status_bar.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-14, 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:
@@ -37,6 +37,7 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
+ android:textColor="#000000"
android:text="@string/fm_record_progress"/>
</RelativeLayout>
diff --git a/fmapp2/res/values/strings.xml b/fmapp2/res/values/strings.xml
index 55b2932..3d490d0 100644
--- a/fmapp2/res/values/strings.xml
+++ b/fmapp2/res/values/strings.xml
@@ -273,6 +273,7 @@
<string name="band_sweep_choose">Choose Band Sweep Method</string>
<string name="set">Set</string>
<string name="cancel">Cancel</string>
- <string name="user_defind_band_msg">Enter Freq from range 76.0 - 108.0 and with min 1 channel spacing</string>
+ <string name="user_defind_band_msg">Enter Freq from range 76.0 - 108.0, with min 1 channel spacing and 100KHz space between max, min freq</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/fmapp2/src/com/caf/fmradio/FMRadio.java b/fmapp2/src/com/caf/fmradio/FMRadio.java
index 99a71f4..12693cf 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadio.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadio.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -443,9 +443,6 @@
@Override
public void onStop() {
Log.d(LOGTAG, "FMRadio: onStop");
- if(isSleepTimerActive()) {
- mSleepUpdateHandlerThread.interrupt();
- }
if(isRecording()) {
try {
if (null != mRecordUpdateHandlerThread) {
@@ -484,6 +481,10 @@
protected void onPause() {
Log.d(LOGTAG, "FMRadio: onPause");
super.onPause();
+ if (isSleepTimerActive()) {
+ Log.d(LOGTAG, "FMRadio: Sleep Timer active");
+ mSleepUpdateHandlerThread.interrupt();
+ }
mRadioTextScroller.stopScroll();
mERadioTextScroller.stopScroll();
FmSharedPreferences.setTunedFrequency(mTunedStation.getFrequency());
@@ -1774,9 +1775,17 @@
private void startRecording() {
if(mService != null) {
try {
- mService.startRecording();
- } catch (RemoteException e) {
- e.printStackTrace();
+ 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 );
}
}
}
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
index ec535c5..25ceeb2 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadioService.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -48,6 +48,17 @@
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.media.AudioSystem;
import android.media.MediaRecorder;
+import android.media.AudioDevicePort;
+import android.media.AudioDevicePortConfig;
+import android.media.AudioFormat;
+import android.media.AudioManager.OnAudioPortUpdateListener;
+import android.media.AudioMixPort;
+import android.media.AudioPatch;
+import android.media.AudioPort;
+import android.media.AudioPortConfig;
+import android.media.AudioRecord;
+import android.media.AudioTrack;
+
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
@@ -76,7 +87,6 @@
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;
@@ -133,6 +143,7 @@
private boolean misAnalogModeSupported = false;
private boolean misAnalogPathEnabled = false;
private boolean mA2dpDisconnected = false;
+ private boolean mA2dpConnected = false;
//PhoneStateListener instances corresponding to each
private FmRxRdsData mFMRxRDSData=null;
@@ -186,6 +197,20 @@
private boolean mIsSSRInProgress = false;
private boolean mIsSSRInProgressFromActivity = false;
private int mKeyActionDownCount = 0;
+ private static final int AUDIO_SAMPLE_RATE = 44100;
+ private static final int AUDIO_CHANNEL_CONFIG =
+ AudioFormat.CHANNEL_CONFIGURATION_STEREO;
+ private static final int AUDIO_ENCODING_FORMAT =
+ AudioFormat.ENCODING_PCM_16BIT;
+ private static final int FM_RECORD_BUF_SIZE =
+ AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE,
+ AUDIO_CHANNEL_CONFIG, AUDIO_ENCODING_FORMAT);
+ private Thread mRecordSinkThread = null;
+ private AudioRecord mAudioRecord = null;
+ private AudioTrack mAudioTrack = null;
+ private boolean mIsRecordSink = false;
+ private static final int AUDIO_FRAMES_COUNT_TO_IGNORE = 3;
+ private Object mRecordSinkLock = new Object();
public FMRadioService() {
}
@@ -210,7 +235,7 @@
registerSleepExpired();
registerRecordTimeout();
registerDelayedServiceStop();
- registerFMRecordingStatus();
+ registerExternalStorageListener();
registerAirplaneModeStatusChanged();
// registering media button receiver seperately as we need to set
// different priority for receiving media events
@@ -298,8 +323,13 @@
unregisterReceiver(mAirplaneModeChanged);
mAirplaneModeChanged = null;
}
+ if( mSdcardUnmountReceiver != null ) {
+ unregisterReceiver(mSdcardUnmountReceiver);
+ mSdcardUnmountReceiver = null;
+ }
/* Since the service is closing, disable the receiver */
- fmOff();
+ if (isFmOn())
+ fmOff();
TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
tmgr.listen(mPhoneStateListener, 0);
@@ -311,50 +341,162 @@
super.onDestroy();
}
- public void registerFMRecordingStatus() {
- if (mFmRecordingStatus == null) {
- mFmRecordingStatus = new BroadcastReceiver() {
+ private synchronized void startAudioRecordSink() {
+ mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.RADIO_TUNER,
+ AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG,
+ AUDIO_ENCODING_FORMAT, FM_RECORD_BUF_SIZE);
+ mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
+ AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG,
+ AUDIO_ENCODING_FORMAT, FM_RECORD_BUF_SIZE,
+ AudioTrack.MODE_STREAM);
+ }
+
+ private synchronized void startRecordSink() {
+ Log.d(LOGTAG, "startRecordSink "
+ + AudioSystem.getForceUse(AudioSystem.FOR_MEDIA));
+
+ if (mAudioRecord != null) {
+ mAudioRecord.stop();
+ }
+ if (mAudioTrack != null) {
+ mAudioTrack.stop();
+ }
+ startAudioRecordSink();
+ createRecordSinkThread();
+
+ mIsRecordSink = true;
+ synchronized (mRecordSinkLock) {
+ mRecordSinkLock.notify();
+ }
+ }
+
+ private synchronized void stopRecordSink() {
+ Log.d(LOGTAG, "stopRecordSink");
+ mRecordSinkLock = false;
+ synchronized (mRecordSinkLock) {
+ mRecordSinkLock.notify();
+ }
+ }
+
+ private synchronized void createRecordSinkThread() {
+ if (mRecordSinkThread == null) {
+ mRecordSinkThread = new RecordSinkThread();
+ mRecordSinkThread.start();
+ }
+ }
+
+ private synchronized void exitRecordSinkThread() {
+ stopRecordSink();
+ mRecordSinkThread.interrupt();
+ mRecordSinkThread = null;
+ }
+
+ private boolean isRecordSinking() {
+ return mIsRecordSink;
+ }
+
+ class RecordSinkThread extends Thread {
+ private int mCurrentFrame = 0;
+ private boolean isAudioFrameNeedIgnore() {
+ return mCurrentFrame < AUDIO_FRAMES_COUNT_TO_IGNORE;
+ }
+
+ @Override
+ public void run() {
+ try {
+ byte[] buffer = new byte[FM_RECORD_BUF_SIZE];
+ while (!Thread.interrupted()) {
+ if (isRecordSinking()) {
+ // Speaker mode or BT a2dp mode will come here and keep reading and writing.
+ // If we want FM sound output from speaker or BT a2dp, we must record data
+ // to AudioRecrd and write data to AudioTrack.
+ if (mAudioRecord.getRecordingState() == AudioRecord.RECORDSTATE_STOPPED) {
+ mAudioRecord.startRecording();
+ }
+
+ if (mAudioTrack.getPlayState() == AudioTrack.PLAYSTATE_STOPPED) {
+ mAudioTrack.play();
+ }
+ int size = mAudioRecord.read(buffer, 0, FM_RECORD_BUF_SIZE);
+ // check whether need to ignore first 3 frames audio data from AudioRecord
+ // to avoid pop noise.
+ if (isAudioFrameNeedIgnore()) {
+ mCurrentFrame += 1;
+ continue ;
+ }
+ if (size <= 0) {
+ Log.e(LOGTAG, "RecordSinkThread read data from AudioRecord "
+ + "error size: " + size);
+ continue;
+ }
+ byte[] tmpBuf = new byte[size];
+ System.arraycopy(buffer, 0, tmpBuf, 0, size);
+ // Check again to avoid noises, because RecordSink may be changed
+ // while AudioRecord is reading.
+ if (isRecordSinking()) {
+ mAudioTrack.write(tmpBuf, 0, tmpBuf.length);
+ }
+ } else {
+ // Earphone mode will come here and wait.
+ mCurrentFrame = 0;
+
+ if (mAudioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
+ mAudioTrack.stop();
+ }
+
+ if (mAudioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
+ mAudioRecord.stop();
+ }
+
+ synchronized (mRecordSinkLock) {
+ mRecordSinkLock.wait();
+ }
+ }
+ }
+ } catch (InterruptedException e) {
+ Log.d(LOGTAG, "RecordSinkThread.run, thread is interrupted, need exit thread");
+ } finally {
+ if (mAudioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
+ mAudioRecord.stop();
+ }
+ if (mAudioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
+ mAudioTrack.stop();
+ }
+ }
+ }
+ }
+
+ /**
+ * 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) {
- Log.d(LOGTAG, "received intent " +intent);
String action = intent.getAction();
- 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;
- mSampleStart = SystemClock.elapsedRealtime();
+ 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 {
- if ((mServiceInUse) && (mCallbacks != null) ) {
- Log.d(LOGTAG, "start recording thread");
- mCallbacks.onRecordingStarted();
- }
- startRecordServiceStatusCheck();
- } catch (RemoteException e) {
+ stopRecording();
+ } catch (Exception 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();
- }
- mSampleStart = 0;
- stopRecordServiceStatusCheck();
- }
+ }
}
}
};
IntentFilter iFilter = new IntentFilter();
- iFilter.addAction(ACTION_FM_RECORDING_STATUS);
- registerReceiver(mFmRecordingStatus , iFilter);
+ iFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
+ iFilter.addAction(Intent.ACTION_MEDIA_EJECT);
+ iFilter.addDataScheme("file");
+ registerReceiver(mSdcardUnmountReceiver, iFilter);
}
- }
+ }
public void registerAirplaneModeStatusChanged() {
if (mAirplaneModeChanged == null) {
@@ -395,6 +537,7 @@
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
+ Log.d(LOGTAG, "on receive HeadsetListener" +action);
if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
Log.d(LOGTAG, "ACTION_HEADSET_PLUG Intent received");
// Listen for ACTION_HEADSET_PLUG broadcasts.
@@ -411,26 +554,16 @@
} else if(mA2dpDeviceState.isA2dpStateChange(action) ) {
boolean bA2dpConnected =
mA2dpDeviceState.isConnected(intent);
+ Log.d(LOGTAG, "bA2dpConnected:" +bA2dpConnected);
if (!bA2dpConnected) {
Log.d(LOGTAG, "A2DP device is dis-connected!");
mA2dpDisconnected = true;
+ mA2dpConnected = false;
} else {
Log.d(LOGTAG, "A2DP device is connected!");
mA2dpDisconnected = false;
+ mA2dpConnected = true;
}
- if (isAnalogModeEnabled()) {
- Log.d(LOGTAG, "FM Audio Path is Analog Mode: FM Over BT not allowed");
- return ;
- }
- //when A2dp connected/disconnected
- // In above two cases we need to Stop and Start FM which
- // will take care of audio routing
- if( (isFmOn()) &&
- (false == mStoppedOnFocusLoss)) {
- Log.d(LOGTAG, "stopping and starting FM\n");
- stopFM();
- startFM();
- }
} else if (action.equals("HDMI_CONNECTED")) {
//FM should be off when HDMI is connected.
fmOff();
@@ -922,13 +1055,7 @@
mAudioManager.registerMediaButtonEventReceiver(fmRadio);
mStoppedOnFocusLoss = false;
- if (!isSpeakerEnabled() && !mA2dpDeviceSupportInHal && (true == mA2dpDeviceState.isDeviceAvailable()) &&
- !isAnalogModeEnabled()
- && (true == startA2dpPlayback())) {
- mOverA2DP=true;
- Log.d(LOGTAG, "Audio source set it as A2DP");
- AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_BT_A2DP);
- } else {
+ if (!mA2dpDeviceState.isDeviceAvailable()) {
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
@@ -941,11 +1068,8 @@
Log.d(LOGTAG, "Audio source set it as headset");
AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_NONE);
}
- AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
- AudioSystem.DEVICE_STATE_AVAILABLE, "");
-
}
- sendRecordServiceIntent(RECORD_START);
+ startRecordSink();
mPlaybackInProgress = true;
mUnMuteOnFocusLoss = false;
mSpeakerOnFocusLoss = false;
@@ -953,28 +1077,13 @@
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, "");
- }
+ stopRecordSink();
+ exitRecordSinkThread();
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, "");
- sendRecordServiceIntent(RECORD_STOP);
- }
mPlaybackInProgress = false;
}
@@ -994,178 +1103,258 @@
return status;
}
- private Runnable recordStatusCheckThread = new Runnable() {
- @Override
- public void run() {
- while(!Thread.currentThread().isInterrupted()) {
- try {
- if(!getRecordServiceStatus()) {
- Log.d(LOGTAG, "FM Recording Service stopped");
- mFmRecordingOn = false;
- try {
- if ((mServiceInUse) && (mCallbacks != null) ) {
- Log.d(LOGTAG, "Callback for stop recording");
- mCallbacks.onRecordingStopped();
- }
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- mSampleStart = 0;
- break;
- };
- Thread.sleep(500);
- }catch(Exception e) {
- Log.d(LOGTAG, "RecordService status check thread interrupted");
- break;
- }
- }
- }
- };
-
- private void startRecordServiceStatusCheck() {
- if((mRecordServiceCheckThread == null) ||
- (mRecordServiceCheckThread.getState() == Thread.State.TERMINATED)) {
- mRecordServiceCheckThread = new Thread(null,
- recordStatusCheckThread,
- "getRecordServiceStatus");
- }
- if((mRecordServiceCheckThread != null) &&
- (mRecordServiceCheckThread.getState() == Thread.State.NEW)) {
- mRecordServiceCheckThread.start();
- }
- }
-
- private void stopRecordServiceStatusCheck() {
- if(mRecordServiceCheckThread != null) {
- mRecordServiceCheckThread.interrupt();
- }
- }
-
- public void startRecording() {
- Log.d(LOGTAG, "In startRecording of Recorder");
- if (!getRecordServiceStatus()) {
- Log.d(LOGTAG, "Recording Service is not in running state");
- sendRecordServiceIntent(RECORD_START);
- try {
- Thread.sleep(200);
- } catch (Exception ex) {
- Log.d( LOGTAG, "RunningThread InterruptedException");
- return;
- }
- }
- if ((true == mSingleRecordingInstanceSupported) &&
- (true == mOverA2DP )) {
- Toast.makeText( this,
- "playback on BT in progress,can't record now",
- Toast.LENGTH_SHORT).show();
- return;
- }
- sendRecordIntent(RECORD_START);
- }
-
- 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",
+ 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;
- }
- mA2dp.setOutputFile(mA2DPSampleFile.getAbsolutePath());
- mA2dp.prepare();
- mA2dp.start();
- } catch (Exception exception) {
- mA2dp.reset();
- mA2dp.release();
- mA2dp = null;
+ }
+ stopRecording();
+
+ if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
+ Log.e(LOGTAG, "startRecording, no external storage available");
+ return false;
+ }
+
+ if (!updateAndShowStorageHint())
+ return false;
+ long maxFileSize = mStorageSpace - LOW_STORAGE_THRESHOLD;
+ mRecorder = new MediaRecorder();
+ try {
+ mRecorder.setMaxFileSize(maxFileSize);
+ } catch (RuntimeException exception) {
+
+ }
+
+ mSampleFile = null;
+ File sampleDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +"/FMRecording");
+ if(!(sampleDir.mkdirs() || sampleDir.isDirectory()))
+ return false;
+ 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;
}
+
+ try {
+ Log.d(LOGTAG, "AudioSource.RADIO_TUNER" +MediaRecorder.AudioSource.RADIO_TUNER);
+ mRecorder.setAudioSource(MediaRecorder.AudioSource.RADIO_TUNER);
+ 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();
+ Log.d(LOGTAG, "start");
+ 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;
+ Log.d(LOGTAG, "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(LOGTAG, "Maximum file size/duration reached, stop 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 = SystemClock.elapsedRealtime();
+ Log.d(LOGTAG, "mSampleStart: " +mSampleStart);
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;
- }
+ }
public void stopRecording() {
- if (!mFmRecordingOn)
+ Log.d(LOGTAG, "Enter stopRecord");
+ mFmRecordingOn = false;
+ if (mRecorder == null)
return;
- sendRecordIntent(RECORD_STOP);
+ 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();
+ }
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.
@@ -1224,6 +1413,14 @@
}
}
}
+ } else {
+ if (!isFmOn() && (mServiceInUse) && (mCallbacks != null)) {
+ try {
+ mCallbacks.onDisabled();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
}
}//idle
}
@@ -1559,9 +1756,9 @@
return(mService.get().isMuted());
}
- public void startRecording()
+ public boolean startRecording()
{
- mService.get().startRecording();
+ return(mService.get().startRecording());
}
public void stopRecording()
@@ -2074,53 +2271,17 @@
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();
+ Log.d(LOGTAG, "speakerOn:" + speakerOn);
+ if ((false == speakerOn) && (!mA2dpConnected)) {
+ Log.d(LOGTAG, "enabling headset");
+ AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_NONE);
}
-
- //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();
- }
- }
+ Log.d(LOGTAG, "enabling speaker");
AudioSystem.setForceUse(AudioSystem.FOR_MEDIA, AudioSystem.FORCE_SPEAKER);
- if (analogmode)
- startFM();
}
-
+ Log.d(LOGTAG, "speakerOn completed:" + speakerOn);
}
/*
* ReConfigure the FM Setup parameters
diff --git a/fmapp2/src/com/caf/fmradio/FMTransmitterService.java b/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
index 980c968..021e468 100644
--- a/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
+++ b/fmapp2/src/com/caf/fmradio/FMTransmitterService.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2013, 2015, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -474,8 +474,8 @@
}
Log.e(LOGTAG, "FMTx is on: Requesting to start FM TX");
- AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_TX,
- AudioSystem.DEVICE_STATE_AVAILABLE, "");
+// AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_TX,
+// AudioSystem.DEVICE_STATE_AVAILABLE, "");
}
if(true == bStatus )
@@ -507,8 +507,8 @@
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, "");
+// AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_TX,
+// AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
}
/*
* Turn OFF FM: Disable the FM Host and hardware .
diff --git a/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl b/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl
index 7a2062d..6140f0d 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();
- void startRecording();
+ boolean startRecording();
void stopRecording();
boolean tune(int frequency);
boolean seek(boolean up);
diff --git a/fmapp2/src/com/caf/fmradio/Settings.java b/fmapp2/src/com/caf/fmradio/Settings.java
index e6adb21..de19f01 100644
--- a/fmapp2/src/com/caf/fmradio/Settings.java
+++ b/fmapp2/src/com/caf/fmradio/Settings.java
@@ -265,6 +265,7 @@
int noOfChannels = 0;
int channelSpacing = 0;
int preIndex;
+ int band_width;
if (key.equals(REGIONAL_BAND_KEY)) {
int curListIndex = FmSharedPreferences.getCurrentListIndex();
@@ -339,8 +340,10 @@
noOfChannels = 0;
max_freq = FmSharedPreferences.getUpperLimit();
min_freq = FmSharedPreferences.getLowerLimit();
- noOfChannels = (int) (max_freq - freq)/FmSharedPreferences.getFrequencyStepSize();
- if((freq > 0) && (freq < max_freq) && (freq >= 76000) && (noOfChannels > 0)) {
+ band_width = (int) (max_freq - freq);
+ noOfChannels = band_width/FmSharedPreferences.getFrequencyStepSize();
+ if((freq > 0) && (freq < max_freq) && (freq >= 76000)
+ && (noOfChannels > 0) && (band_width >= 100)) {
FmSharedPreferences.setLowerLimit((int)freq);
sendSettingsChangedIntent(FM_BAND_CHANGED);
setBandSummary(summaryBandItems.length - 1);
@@ -365,8 +368,10 @@
noOfChannels = 0;
min_freq = FmSharedPreferences.getLowerLimit();
max_freq = FmSharedPreferences.getUpperLimit();
- noOfChannels = (int) (freq - min_freq)/FmSharedPreferences.getFrequencyStepSize();
- if((freq > 0) && (freq > min_freq) && (freq <= 108000) && (noOfChannels > 0)) {
+ band_width = (int) (freq - min_freq);
+ noOfChannels = band_width/FmSharedPreferences.getFrequencyStepSize();
+ if((freq > 0) && (freq > min_freq) && (freq <= 108000)
+ && (noOfChannels > 0) && (band_width >= 100)) {
FmSharedPreferences.setUpperLimit((int)freq);
sendSettingsChangedIntent(FM_BAND_CHANGED);
setBandSummary(summaryBandItems.length - 1);
diff --git a/jni/FmConst.h b/jni/FmConst.h
index c4cd33b..00e6f82 100644
--- a/jni/FmConst.h
+++ b/jni/FmConst.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2015, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -44,7 +44,7 @@
#define STD_BUF_SIZE 256
const char *const FM_PERFORMANCE_PARAMS = "/etc/fm/fm_srch_af_th.conf";
-const char *const CALIB_DATA_NAME = "/data/app/Riva_fm_cal";
+const char *const CALIB_DATA_NAME = "/data/misc/fm/Riva_fm_cal";
#define V4L2_CTRL_CLASS_USER 0x00980000
#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
diff --git a/libfm_jni/FM_Const.h b/libfm_jni/FM_Const.h
index a93fe77..b0cc684 100644
--- a/libfm_jni/FM_Const.h
+++ b/libfm_jni/FM_Const.h
@@ -121,7 +121,7 @@
const char *const SCRIPT_START_PROP = "ctl.start";
const char *const FM_SOC_DL_SCRIPT = "fm_dl";
const char *const SCRIPT_STOP_PROP = "ctl.stOP";
-const char *const CALIB_DATA_NAME = "/data/app/Riva_fm_cal";
+const char *const CALIB_DATA_NAME = "/data/misc/fm/Riva_fm_cal";
const char *const SOC_PATCH_DL_SCRPT = "fm_dl";
const char *const FM_DEVICE_PATH = "/dev/radio0";
const char *const FM_PERFORMANCE_PARAMS = "/etc/fm/fm_srch_af_th.conf";
diff --git a/libfm_jni/FmIoctlsInterface.cpp b/libfm_jni/FmIoctlsInterface.cpp
index bd3440b..fbe035c 100644
--- a/libfm_jni/FmIoctlsInterface.cpp
+++ b/libfm_jni/FmIoctlsInterface.cpp
@@ -119,7 +119,7 @@
channel.type = V4L2_TUNER_RADIO;
ret = ioctl(fd, VIDIOC_G_FREQUENCY, &channel);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
freq = (channel.frequency / TUNE_MULT);
@@ -139,7 +139,7 @@
channel.frequency = (freq * TUNE_MULT);
ret = ioctl(fd, VIDIOC_S_FREQUENCY, &channel);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
return FM_SUCCESS;
@@ -158,7 +158,7 @@
control.id = id;
ret = ioctl(fd, VIDIOC_S_CTRL, &control);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
return FM_SUCCESS;
@@ -190,7 +190,7 @@
v4l2_ctls.count = 1;
v4l2_ctls.controls = &ext_ctl;
ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, &v4l2_ctls);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
return FM_SUCCESS;
@@ -210,7 +210,7 @@
control.id = id;
ret = ioctl(fd, VIDIOC_G_CTRL, &control);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
val = control.value;
@@ -230,7 +230,7 @@
hw_seek.type = V4L2_TUNER_RADIO;
ret = ioctl(fd, VIDIOC_S_HW_FREQ_SEEK, &hw_seek);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
return FM_SUCCESS;
@@ -252,7 +252,7 @@
ret = ioctl(fd, VIDIOC_S_TUNER, &tuner);
ret = set_control(fd, V4L2_CID_PRV_REGION, 0);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
return FM_SUCCESS;
@@ -270,8 +270,8 @@
tuner.index = 0;
tuner.signal = 0;
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
- if(ret != IOCTL_SUCC) {
- ret = FM_SUCCESS;
+ if(ret < IOCTL_SUCC) {
+ ret = FM_FAILURE;
}else {
rmssi = tuner.signal;
ret = FM_SUCCESS;
@@ -289,7 +289,7 @@
tuner.index = 0;
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
freq = (tuner.rangehigh / TUNE_MULT);
@@ -308,7 +308,7 @@
tuner.index = 0;
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
freq = (tuner.rangelow / TUNE_MULT);
@@ -327,7 +327,7 @@
tuner.index = 0;
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
tuner.audmode = mode;
@@ -357,7 +357,7 @@
v4l2_buf.length = STD_BUF_SIZE;
v4l2_buf.m.userptr = (ULINT)buff;
ret = ioctl(fd, VIDIOC_DQBUF, &v4l2_buf);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
return v4l2_buf.bytesused;
@@ -375,7 +375,7 @@
ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, v4l2_ctls);
- if(ret != IOCTL_SUCC) {
+ if(ret < IOCTL_SUCC) {
return FM_FAILURE;
}else {
return FM_SUCCESS;
diff --git a/libfm_jni/FmRadioController.cpp b/libfm_jni/FmRadioController.cpp
index 55bcef4..613a062 100644
--- a/libfm_jni/FmRadioController.cpp
+++ b/libfm_jni/FmRadioController.cpp
@@ -159,8 +159,11 @@
int ret = FM_SUCCESS;
struct timespec ts;
ConfigFmThs thsObj;
+ char value[PROPERTY_VALUE_MAX] = {'\0'};
ALOGI("%s,[freq=%d]\n", __func__, freq);
+ property_get("qcom.bluetooth.soc", value, NULL);
+ ALOGD("BT soc is %s\n", value);
if (fd_driver < 0) {
ret = open_dev();
if (ret != FM_SUCCESS) {
@@ -171,12 +174,14 @@
if (cur_fm_state == FM_OFF) {
ALOGE("cur_fm_state = %d\n",cur_fm_state);
- ret = FmIoctlsInterface::start_fm_patch_dl(fd_driver);
- if (ret != FM_SUCCESS) {
- ALOGE("FM patch downloader failed: %d\n", ret);
- close_dev();
- set_fm_state(FM_OFF);
- return FM_FAILURE;
+ if (strcmp(value, "rome") != 0) {
+ ret = FmIoctlsInterface::start_fm_patch_dl(fd_driver);
+ if (ret != FM_SUCCESS) {
+ ALOGE("FM patch downloader failed: %d\n", ret);
+ close_dev();
+ set_fm_state(FM_OFF);
+ return FM_FAILURE;
+ }
}
if (event_listener_thread == 0) {
ret = pthread_create(&event_listener_thread, NULL,
@@ -1095,10 +1100,15 @@
void
)
{
+ char value[PROPERTY_VALUE_MAX] = {'\0'};
+
ALOGI("FM handle ready Event\n");
FmIoctlsInterface::set_control(fd_driver,
V4L2_CID_PRV_AUDIO_PATH, AUDIO_DIGITAL_PATH);
- FmIoctlsInterface::set_calibration(fd_driver);
+ property_get("qcom.bluetooth.soc", value, NULL);
+ if (strcmp(value, "rome") != 0) {
+ FmIoctlsInterface::set_calibration(fd_driver);
+ }
pthread_mutex_lock(&mutex_turn_on_cond);
set_fm_state(FM_ON);
pthread_cond_broadcast(&turn_on_cond);