Skip to content

Instantly share code, notes, and snippets.

@ngoquang2708
Created October 4, 2016 16:28
Show Gist options
  • Save ngoquang2708/aa36df33685db82277647ad3a785fba8 to your computer and use it in GitHub Desktop.
Save ngoquang2708/aa36df33685db82277647ad3a785fba8 to your computer and use it in GitHub Desktop.
diff --git a/Android.mk b/Android.mk
index 1fc1a34..f6bd934 100644
--- a/Android.mk
+++ b/Android.mk
@@ -28,7 +28,11 @@ LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := FMRadio
+ifeq ($(strip $(BOARD_HAVE_FMRADIO_BCM)),true)
+LOCAL_STATIC_JAVA_LIBRARIES += com.broadcom.fm
+else
LOCAL_JNI_SHARED_LIBRARIES := libfmjni
+endif
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_PRIVILEGED_MODULE := true
@@ -40,4 +44,6 @@ LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages android.support.v7.cardv
include $(BUILD_PACKAGE)
+ifneq ($(strip $(BOARD_HAVE_FMRADIO_BCM)),true)
include $(call all-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/src/com/android/fmradio/FmListener.java b/src/com/android/fmradio/FmListener.java
index e060c52..fad83b4 100644
--- a/src/com/android/fmradio/FmListener.java
+++ b/src/com/android/fmradio/FmListener.java
@@ -84,6 +84,7 @@
int MSGID_SET_CHANNEL_FINISHED = 6;
int MSGID_SET_MUTE_FINISHED = 7;
// Fm main
+ int MSGID_OPENDEVICE_FINISHED = 8;
int MSGID_POWERUP_FINISHED = 9;
int MSGID_POWERDOWN_FINISHED = 10;
int MSGID_FM_EXIT = 11;
diff --git a/src/com/android/fmradio/FmNative.java b/src/com/android/fmradio/FmNative.java
index da8cbce..8304ee5 100644
--- a/src/com/android/fmradio/FmNative.java
+++ b/src/com/android/fmradio/FmNative.java
@@ -16,27 +16,33 @@
package com.android.fmradio;
+import android.content.Context;
+
/**
* This class define FM native interface, will description FM native interface
*/
-public class FmNative {
- static {
- System.loadLibrary("fmjni");
- }
+public abstract class FmNative {
+ private static FmNative mInstance = null;
+
+ public static synchronized FmNative getInstance() {
+ if (mInstance == null)
+ mInstance = new FmNativeBroadcom();
+ return mInstance;
+ }
/**
* Open FM device, call before power up
*
* @return (true,success; false, failed)
*/
- static native boolean openDev();
+ public abstract boolean openDev(Context ctx);
/**
* Close FM device, call after power down
*
* @return (true, success; false, failed)
*/
- static native boolean closeDev();
+ public abstract boolean closeDev();
/**
* power up FM with frequency use long antenna
@@ -45,7 +51,7 @@
*
* @return (true, success; false, failed)
*/
- static native boolean powerUp(float frequency);
+ public abstract boolean powerUp(float frequency);
/**
* Power down FM
@@ -54,7 +60,7 @@
*
* @return (true, success; false, failed)
*/
- static native boolean powerDown(int type);
+ public abstract boolean powerDown(int type);
/**
* tune to frequency
@@ -63,7 +69,7 @@
*
* @return (true, success; false, failed)
*/
- static native boolean tune(float frequency);
+ public abstract boolean tune(float frequency);
/**
* seek with frequency in direction
@@ -73,14 +79,14 @@
*
* @return frequency(float)
*/
- static native float seek(float frequency, boolean isUp);
+ public abstract float seek(float frequency, boolean isUp);
/**
* Auto scan(from 87.50-108.00)
*
* @return The scan station array(short)
*/
- static native short[] autoScan();
+ public abstract short[] autoScan();
/**
* Stop scan, also can stop seek, other native when scan should call stop
@@ -88,7 +94,7 @@
*
* @return (true, can stop scan process; false, can't stop scan process)
*/
- static native boolean stopScan();
+ public abstract boolean stopScan();
/**
* Open or close rds fuction
@@ -97,35 +103,35 @@
*
* @return rdsset
*/
- static native int setRds(boolean rdson);
+ public abstract int setRds(boolean rdson);
/**
* Read rds events
*
* @return rds event type
*/
- static native short readRds();
+ public abstract short readRds();
/**
* Get program service(program name)
*
* @return The program name
*/
- static native byte[] getPs();
+ public abstract byte[] getPs();
/**
* Get radio text, RDS standard does not support Chinese character
*
* @return The LRT (Last Radio Text) bytes
*/
- static native byte[] getLrText();
+ public abstract byte[] getLrText();
/**
* Active alternative frequencies
*
* @return The frequency(float)
*/
- static native short activeAf();
+ public abstract short activeAf();
/**
* Mute or unmute FM voice
@@ -134,14 +140,14 @@
*
* @return (true, success; false, failed)
*/
- static native int setMute(boolean mute);
+ public abstract int setMute(boolean mute);
/**
* Inquiry if RDS is support in driver
*
* @return (1, support; 0, NOT support; -1, error)
*/
- static native int isRdsSupport();
+ public abstract int isRdsSupport();
/**
* Switch antenna
@@ -150,5 +156,5 @@
*
* @return (0, success; 1 failed; 2 not support)
*/
- static native int switchAntenna(int antenna);
+ public abstract int switchAntenna(int antenna);
}
diff --git a/src/com/android/fmradio/FmNativeBroadcom.java b/src/com/android/fmradio/FmNativeBroadcom.java
new file mode 100644
index 0000000..60036d6
--- /dev/null
+++ b/src/com/android/fmradio/FmNativeBroadcom.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.fmradio;
+
+import android.content.Context;
+
+import com.broadcom.fm.fmreceiver.FmProxy;
+import com.broadcom.fm.fmreceiver.IFmReceiverEventHandler;
+import com.broadcom.fm.fmreceiver.IFmProxyCallback;
+
+import java.util.ArrayList;
+
+/**
+ * This class define FM native interface, will description FM native interface
+ */
+public class FmNativeBroadcom extends FmNative implements IFmProxyCallback, IFmReceiverEventHandler {
+ private static final int TIMEOUT = 5000;
+
+ private static final int RDS_ID_PTY_EVT = 2;
+ private static final int RDS_ID_PS_EVT = 7;
+ private static final int RDS_ID_PTYN_EVT = 8;
+ private static final int RDS_ID_RT_EVT = 9;
+
+ private static final int RDS_EVT_PS = 1;
+ private static final int RDS_EVT_RT = 2;
+
+ private FmProxy mFmReceiver = null;
+
+ private float mfrequency = 0.0f;
+ private boolean mRdsOn = false;
+ private int mRdsEvent = 0;
+ private String mRdsProgramService;
+ private String mRdsRadioText;
+
+ public boolean openDev(Context ctx) {
+ synchronized(this) {
+ if (mFmReceiver == null) {
+ if (!FmProxy.getProxy(ctx, this)) {
+ return false;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return false;
+ }
+ return (mFmReceiver != null);
+ }
+ return true;
+ }
+ }
+
+ public boolean closeDev() {
+ synchronized(this) {
+ if (mFmReceiver != null) {
+ try {
+ mFmReceiver.unregisterEventHandler();
+ mFmReceiver.finish();
+ } catch (IllegalArgumentException ei) {
+ ;
+ } catch (Exception e) {
+ // Fatal Exception to closeDev
+ } finally {
+ mFmReceiver = null;
+ }
+ }
+ return true;
+ }
+ }
+
+ public boolean powerUp(float frequency) {
+ synchronized (this) {
+ if (mFmReceiver == null) {
+ return false;
+ }
+ if (mFmReceiver.turnOnRadio(FmProxy.FUNC_REGION_NA | FmProxy.FUNC_RBDS | FmProxy.FUNC_AF | FmProxy.FUNC_SOFTMUTE) != FmProxy.STATUS_OK) {
+ return false;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return false;
+ }
+ if (mFmReceiver.tuneRadio((int)(frequency * 100)) != FmProxy.STATUS_OK) {
+ return false;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return false;
+ }
+ if (mFmReceiver.setAudioPath(FmProxy.AUDIO_PATH_DIGITAL) != FmProxy.STATUS_OK) {
+ return false;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return false;
+ }
+ if (mFmReceiver.setFMVolume(255) != FmProxy.STATUS_OK) {
+ return false;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public boolean powerDown(int type) {
+ synchronized (this) {
+ if (mFmReceiver == null) {
+ return false;
+ }
+ if (mFmReceiver.turnOffRadio() != FmProxy.STATUS_OK) {
+ return false;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public boolean tune(float frequency) {
+ synchronized (this) {
+ if (mFmReceiver == null) {
+ return false;
+ }
+ if (mFmReceiver.tuneRadio((int)(frequency * 100)) != FmProxy.STATUS_OK) {
+ return false;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return false;
+ }
+ return mfrequency == frequency;
+ }
+ }
+
+ public float seek(float frequency, boolean isUp) {
+ synchronized (this) {
+ if (mFmReceiver == null) {
+ return 0f;
+ }
+ if (mFmReceiver.tuneRadio((int)(frequency * 100)) != FmProxy.STATUS_OK) {
+ return 0f;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return 0f;
+ }
+ if (mfrequency != frequency) {
+ return 0f;
+ }
+ if (mFmReceiver.seekStation(isUp ? FmProxy.SCAN_MODE_UP : FmProxy.SCAN_MODE_DOWN) != FmProxy.STATUS_OK) {
+ return 0f;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return 0f;
+ }
+ return mfrequency == frequency ? 0f : mfrequency;
+ }
+ }
+
+ public short[] autoScan() {
+ synchronized (this) {
+ ArrayList<Short> freqList = new ArrayList<Short>();
+ float frequency = FmUtils.computeFrequency(FmUtils.getLowestStation());
+
+ if (mFmReceiver == null) {
+ return null;
+ }
+ if (mFmReceiver.tuneRadio((int)(frequency * 100)) != FmProxy.STATUS_OK) {
+ return null;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return null;
+ }
+ while (true) {
+ if (mFmReceiver.seekStation(FmProxy.SCAN_MODE_UP) != FmProxy.STATUS_OK) {
+ return null;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return null;
+ }
+ if ((mfrequency <= frequency) || (mfrequency >= FmUtils.computeFrequency(FmUtils.getHighestStation()))) {
+ break;
+ }
+ freqList.add((short)FmUtils.computeStation(mfrequency));
+ frequency = mfrequency;
+ }
+ if (freqList.size() == 0) {
+ return null;
+ }
+ short[] freqArray = new short[freqList.size()];
+ for (int i = 0; i < freqList.size(); i++) {
+ freqArray[i] = freqList.get(i);
+ }
+ return freqArray;
+ }
+ }
+
+ public boolean stopScan() {
+ synchronized (this) {
+ if (mFmReceiver == null) {
+ return false;
+ }
+ if (mFmReceiver.seekStationAbort() != FmProxy.STATUS_OK) {
+ return false;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public int setRds(boolean rdson) {
+ synchronized (this) {
+ if (mFmReceiver == null) {
+ return 0;
+ }
+ if (mFmReceiver.setRdsMode(rdson ? FmProxy.RDS_MODE_DEFAULT_ON : FmProxy.RDS_MODE_OFF,
+ FmProxy.RDS_FEATURE_PS | FmProxy.RDS_FEATURE_RT,
+ FmProxy.AF_MODE_OFF, FmProxy.MIN_SIGNAL_STRENGTH_DEFAULT) != FmProxy.STATUS_OK) {
+ return 0;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return 0;
+ }
+ return 1;
+ }
+ }
+
+ public short readRds() {
+ synchronized (this) {
+ if (mFmReceiver == null) {
+ return 0;
+ }
+ if (mRdsOn) {
+ if ((mRdsEvent & RDS_EVT_PS) != 0) {
+ mRdsEvent &= ~RDS_EVT_PS;
+ return 0x0008;
+ }
+ if ((mRdsEvent & RDS_EVT_RT) != 0) {
+ mRdsEvent &= ~RDS_EVT_RT;
+ return 0x0040;
+ }
+ }
+ return 0;
+ }
+ }
+
+ public byte[] getPs() {
+ synchronized (this) {
+ if ((mFmReceiver == null) || !mRdsOn) {
+ return null;
+ }
+ try {
+ return mRdsProgramService.getBytes("UTF8");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ }
+
+ public byte[] getLrText() {
+ synchronized (this) {
+ if ((mFmReceiver == null) || !mRdsOn || (mRdsRadioText == null)) {
+ return null;
+ }
+ try {
+ return mRdsRadioText.getBytes("UTF8");
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ }
+
+ public short activeAf() {
+ synchronized (this) {
+ if (mFmReceiver == null) {
+ return 0;
+ }
+ if (mFmReceiver.setRdsMode(FmProxy.RDS_MODE_DEFAULT_ON,
+ FmProxy.RDS_FEATURE_PS | FmProxy.RDS_FEATURE_RT | FmProxy.RDS_FEATURE_TP | FmProxy.RDS_FEATURE_PTY | FmProxy.RDS_FEATURE_PTYN,
+ FmProxy.AF_MODE_ON, FmProxy.MIN_SIGNAL_STRENGTH_DEFAULT) != FmProxy.STATUS_OK) {
+ return 0;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return 0;
+ }
+ return (short)FmUtils.computeStation(mfrequency);
+ }
+ }
+
+ public int setMute(boolean mute) {
+ synchronized (this) {
+ if (mFmReceiver == null) {
+ return 0;
+ }
+ if (mFmReceiver.muteAudio(mute) != FmProxy.STATUS_OK) {
+ return 0;
+ }
+ try {
+ this.wait(TIMEOUT);
+ } catch (Exception e) {
+ return 0;
+ }
+ return 1;
+ }
+ }
+
+ public int isRdsSupport() {
+ return 1;
+ }
+
+ public int switchAntenna(int antenna) {
+ return 2;
+ }
+
+
+ public void onProxyAvailable(Object ProxyObject) {
+ synchronized (this) {
+ mFmReceiver = (FmProxy)ProxyObject;
+ mFmReceiver.registerEventHandler(this);
+ this.notifyAll();
+ }
+ }
+
+ public void onAudioModeEvent(int audioMode) {
+ synchronized (this) {
+ this.notifyAll();
+ }
+ }
+
+
+ public void onAudioPathEvent(int audioPath) {
+ synchronized (this) {
+ this.notifyAll();
+ }
+ }
+
+ public void onEstimateNoiseFloorLevelEvent(int nfl) {
+ synchronized (this) {
+ this.notifyAll();
+ }
+ }
+
+ public void onLiveAudioQualityEvent(int rssi, int snr) {
+ synchronized (this) {
+ this.notifyAll();
+ }
+ }
+
+ public void onRdsDataEvent(int rdsDataType, int rdsIndex,
+ String rdsText) {
+ synchronized (this) {
+ if (mRdsOn) {
+ if (rdsDataType == RDS_ID_PS_EVT) {
+ mRdsEvent |= RDS_EVT_PS;
+ mRdsProgramService = rdsText;
+ } else if (rdsDataType == RDS_ID_RT_EVT) {
+ mRdsEvent |= RDS_EVT_RT;
+ mRdsRadioText = rdsText;
+ }
+ }
+ }
+ }
+
+ public void onRdsModeEvent(int rdsMode, int alternateFreqHopEnabled) {
+ synchronized (this) {
+ mRdsOn = rdsMode != FmProxy.RDS_MODE_OFF;
+ this.notifyAll();
+ }
+ }
+
+ public void onSeekCompleteEvent(int freq, int rssi,
+ int snr, boolean seeksuccess) {
+ synchronized (this) {
+ if (seeksuccess)
+ mfrequency = freq / 100f;
+ this.notifyAll();
+ }
+ }
+
+ public void onStatusEvent(int freq, int rssi, int snr, boolean radioIsOn,
+ int rdsProgramType, String rdsProgramService,
+ String rdsRadioText, String rdsProgramTypeName, boolean isMute) {
+ synchronized (this) {
+ mfrequency = freq / 100f;
+ this.notifyAll();
+ }
+ }
+
+ public void onWorldRegionEvent(int worldRegion) {
+ synchronized (this) {
+ this.notifyAll();
+ }
+ }
+
+ public void onVolumeEvent(int status, int volume) {
+ synchronized (this) {
+ this.notifyAll();
+ }
+ }
+}
diff --git a/src/com/android/fmradio/FmRecorder.java b/src/com/android/fmradio/FmRecorder.java
index 389fbc2..d45cae3 100644
--- a/src/com/android/fmradio/FmRecorder.java
+++ b/src/com/android/fmradio/FmRecorder.java
@@ -46,10 +46,10 @@
// file prefix
public static final String RECORDING_FILE_PREFIX = "FM";
// file extension
- public static final String RECORDING_FILE_EXTENSION = ".3gpp";
+ public static final String RECORDING_FILE_EXTENSION = ".m4a";
// recording file folder
public static final String FM_RECORD_FOLDER = "FM Recording";
- private static final String RECORDING_FILE_TYPE = "audio/3gpp";
+ private static final String RECORDING_FILE_TYPE = "audio/mp4";
private static final String RECORDING_FILE_SOURCE = "FM Recordings";
// error type no sdcard
public static final int ERROR_SDCARD_NOT_PRESENT = 0;
diff --git a/src/com/android/fmradio/FmService.java b/src/com/android/fmradio/FmService.java
index f6e98c3..f2582e6 100644
--- a/src/com/android/fmradio/FmService.java
+++ b/src/com/android/fmradio/FmService.java
@@ -106,6 +106,10 @@
// Set audio policy for FM
// should check AUDIO_POLICY_FORCE_FOR_MEDIA in audio_policy.h
private static final int FOR_PROPRIETARY = 1;
+
+ // use audio patch api
+ private static final boolean USE_AUDIO_PATCH = false;
+
// Forced Use value
private int mForcedUseForMedia;
@@ -134,7 +138,7 @@
// RT String
private String mRtTextString = "";
// Notification target class name
- private String mTargetClassName = "com.android.fmradio.FmMainActivity";
+ private String mTargetClassName = FmMainActivity.class.getName();
// RDS thread use to receive the information send by station
private Thread mRdsThread = null;
// record whether RDS thread exit
@@ -217,6 +221,8 @@
private Notification.Builder mNotificationBuilder = null;
private BigTextStyle mNotificationStyle = null;
+ private FmNative mFmNative = null;
+
@Override
public IBinder onBind(Intent intent) {
return mBinder;
@@ -401,12 +407,14 @@ private synchronized void startRender() {
// need to create new audio record and audio play back track,
// because input/output device may be changed.
if (mAudioRecord != null) {
- mAudioRecord.stop();
+ if (mAudioRecord.getState() != AudioRecord.STATE_UNINITIALIZED)
+ mAudioRecord.stop();
mAudioRecord.release();
mAudioRecord = null;
}
if (mAudioTrack != null) {
- mAudioTrack.stop();
+ if (mAudioTrack.getState() != AudioTrack.STATE_UNINITIALIZED)
+ mAudioTrack.stop();
mAudioTrack.release();
mAudioTrack = null;
}
@@ -567,9 +575,15 @@ private boolean isSpeakerPhoneOn() {
*
* @return true if FM device open, false FM device not open
*/
+ public void openDeviceAsync() {
+ mFmServiceHandler.removeMessages(FmListener.MSGID_OPENDEVICE_FINISHED);
+ Message msg = mFmServiceHandler.obtainMessage(FmListener.MSGID_OPENDEVICE_FINISHED);
+ mFmServiceHandler.sendMessage(msg);
+ }
+
private boolean openDevice() {
if (!mIsDeviceOpen) {
- mIsDeviceOpen = FmNative.openDev();
+ mIsDeviceOpen = mFmNative.openDev(this);
}
return mIsDeviceOpen;
}
@@ -582,7 +596,7 @@ private boolean openDevice() {
private boolean closeDevice() {
boolean isDeviceClose = false;
if (mIsDeviceOpen) {
- isDeviceClose = FmNative.closeDev();
+ isDeviceClose = mFmNative.closeDev();
mIsDeviceOpen = !isDeviceClose;
}
// quit looper
@@ -636,7 +650,7 @@ private boolean powerUp(float frequency) {
openDevice();
}
- if (!FmNative.powerUp(frequency)) {
+ if (!mFmNative.powerUp(frequency)) {
mPowerStatus = POWER_DOWN;
return false;
}
@@ -644,6 +658,15 @@ private boolean powerUp(float frequency) {
// need mute after power up
setMute(true);
+ if (mPowerStatus == POWER_UP) {
+ if (AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_FM_TUNER,
+ AudioSystem.DEVICE_STATE_AVAILABLE, "", "") != AudioSystem.SUCCESS) {
+ Log.e(TAG, "powerUp() set AudioSystem.DEVICE_STATE_AVAILABLE for AudioSystem.DEVICE_IN_FM_TUNER failed!");
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_FM_TUNER,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, "", "");
+ }
+ }
+
return (mPowerStatus == POWER_UP);
}
@@ -695,6 +718,10 @@ public void powerDownAsync() {
* @return true if power down success
*/
private boolean powerDown() {
+ // Disable DEVICE_IN_FM_TUNER
+ AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_FM_TUNER,
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, "", "");
+
if (mPowerStatus == POWER_DOWN) {
return true;
}
@@ -707,7 +734,7 @@ private boolean powerDown() {
setRds(false);
enableFmAudio(false);
- if (!FmNative.powerDown(0)) {
+ if (!mFmNative.powerDown(0)) {
if (isRdsSupported()) {
stopRdsThread();
@@ -760,7 +787,7 @@ public void tuneStationAsync(float frequency) {
private boolean tuneStation(float frequency) {
if (mPowerStatus == POWER_UP) {
setRds(false);
- boolean bRet = FmNative.tune(frequency);
+ boolean bRet = mFmNative.tune(frequency);
if (bRet) {
setRds(true);
mCurrentStation = FmUtils.computeStation(frequency);
@@ -812,7 +839,7 @@ private float seekStation(float frequency, boolean isUp) {
setRds(false);
mIsNativeSeeking = true;
- float fRet = FmNative.seek(frequency, isUp);
+ float fRet = mFmNative.seek(frequency, isUp);
mIsNativeSeeking = false;
// make mIsStopScanCalled false, avoid stop scan make this true,
// when start scan, it will return null.
@@ -836,7 +863,7 @@ public void startScanAsync() {
short[] stationsInShort = null;
if (!mIsStopScanCalled) {
mIsNativeScanning = true;
- stationsInShort = FmNative.autoScan();
+ stationsInShort = mFmNative.autoScan();
mIsNativeScanning = false;
}
@@ -885,7 +912,7 @@ public boolean stopScan() {
mFmServiceHandler.removeMessages(FmListener.MSGID_SEEK_FINISHED);
if (mIsNativeScanning || mIsNativeSeeking) {
mIsStopScanCalled = true;
- bRet = FmNative.stopScan();
+ bRet = mFmNative.stopScan();
}
return bRet;
}
@@ -920,7 +947,7 @@ private int setRds(boolean on) {
}
int ret = -1;
if (isRdsSupported()) {
- ret = FmNative.setRds(on);
+ ret = mFmNative.setRds(on);
}
return ret;
}
@@ -959,7 +986,7 @@ private int activeAf() {
return -1;
}
- int frequency = FmNative.activeAf();
+ int frequency = mFmNative.activeAf();
return frequency;
}
@@ -992,7 +1019,7 @@ public int setMute(boolean mute) {
Log.w(TAG, "setMute, FM is not powered up");
return -1;
}
- int iRet = FmNative.setMute(mute);
+ int iRet = mFmNative.setMute(mute);
mIsMuted = mute;
return iRet;
}
@@ -1012,7 +1039,7 @@ public boolean isMuted() {
* @return (true, support; false, not support)
*/
public boolean isRdsSupported() {
- boolean isRdsSupported = (FmNative.isRdsSupport() == 1);
+ boolean isRdsSupported = (mFmNative.isRdsSupport() == 1);
return isRdsSupported;
}
@@ -1104,7 +1131,7 @@ public void switchAntennaAsync(int antenna) {
*/
private int switchAntenna(int antenna) {
// if fm not powerup, switchAntenna will flag whether has earphone
- int ret = FmNative.switchAntenna(antenna);
+ int ret = mFmNative.switchAntenna(antenna);
return ret;
}
@@ -1275,6 +1302,7 @@ public String getRecordingName() {
@Override
public void onCreate() {
super.onCreate();
+ mFmNative = FmNative.getInstance();
mContext = getApplicationContext();
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
@@ -1291,7 +1319,7 @@ public void onCreate() {
handlerThread.start();
mFmServiceHandler = new FmRadioServiceHandler(handlerThread.getLooper());
- openDevice();
+ openDeviceAsync();
// set speaker to default status, avoid setting->clear data.
setForceUse(mIsSpeakerUsed);
@@ -1409,7 +1437,7 @@ public void onAudioPatchListUpdate(AudioPatch[] patchList) {
} else if (mIsRender) {
ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>();
mAudioManager.listAudioPatches(patches);
- if (isPatchMixerToEarphone(patches)) {
+ if (USE_AUDIO_PATCH && isPatchMixerToEarphone(patches)) {
int status;
stopAudioTrack();
stopRender();
@@ -1547,13 +1575,13 @@ public void run() {
break;
}
- int iRdsEvents = FmNative.readRds();
+ int iRdsEvents = mFmNative.readRds();
if (iRdsEvents != 0) {
Log.d(TAG, "startRdsThread, is rds events: " + iRdsEvents);
}
if (RDS_EVENT_PROGRAMNAME == (RDS_EVENT_PROGRAMNAME & iRdsEvents)) {
- byte[] bytePS = FmNative.getPs();
+ byte[] bytePS = mFmNative.getPs();
if (null != bytePS) {
String ps = new String(bytePS).trim();
if (!mPsString.equals(ps)) {
@@ -1575,7 +1603,7 @@ public void run() {
}
if (RDS_EVENT_LAST_RADIOTEXT == (RDS_EVENT_LAST_RADIOTEXT & iRdsEvents)) {
- byte[] byteLRText = FmNative.getLrText();
+ byte[] byteLRText = mFmNative.getLrText();
if (null != byteLRText) {
String rds = new String(byteLRText).trim();
if (!mRtTextString.equals(rds)) {
@@ -1605,7 +1633,7 @@ public void run() {
} else if (mPowerStatus == POWER_DOWN) {
Log.d(TAG, "startRdsThread, fm is power down, do nothing.");
} else {
- int iFreq = FmNative.activeAf();
+ int iFreq = mFmNative.activeAf();
if (FmUtils.isValidStation(iFreq)) {
// if the new frequency is not equal to current
// frequency.
@@ -1699,7 +1727,7 @@ private void startPatchOrRender() {
ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>();
mAudioManager.listAudioPatches(patches);
if (mAudioPatch == null) {
- if (isPatchMixerToEarphone(patches)) {
+ if (USE_AUDIO_PATCH && isPatchMixerToEarphone(patches)) {
int status;
stopAudioTrack();
stopRender();
@@ -2406,6 +2434,11 @@ public void handleMessage(Message msg) {
switch (msg.what) {
+ // Open Device
+ case FmListener.MSGID_OPENDEVICE_FINISHED:
+ openDevice();
+ break;
+
// power up
case FmListener.MSGID_POWERUP_FINISHED:
bundle = msg.getData();
@@ -2736,10 +2769,10 @@ private boolean firstPlaying(float frequency) {
return false;
}
boolean isSeekTune = false;
- float seekStation = FmNative.seek(frequency, false);
+ float seekStation = mFmNative.seek(frequency, false);
int station = FmUtils.computeStation(seekStation);
if (FmUtils.isValidStation(station)) {
- isSeekTune = FmNative.tune(seekStation);
+ isSeekTune = mFmNative.tune(seekStation);
if (isSeekTune) {
playFrequency(seekStation);
}
diff --git a/src/com/android/fmradio/FmUtils.java b/src/com/android/fmradio/FmUtils.java
index b6219fd..b081f5f 100644
--- a/src/com/android/fmradio/FmUtils.java
+++ b/src/com/android/fmradio/FmUtils.java
@@ -66,6 +66,14 @@
// StorageManager For FM record
private static StorageManager sStorageManager = null;
+ public static int getHighestStation() {
+ return HIGHEST_STATION;
+ }
+
+ public static int getLowestStation() {
+ return LOWEST_STATION;
+ }
+
/**
* Whether the frequency is valid.
*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment