FM-APP2: Added recording option on RF Stats activity
- Added recording button on action bar to start/stop
recording from RF Stats activity
Change-Id: Ia4ce12bf2bf860187a583ad07162ee02080d0d60
diff --git a/fmapp2/res/menu/menu_rf_stats.xml b/fmapp2/res/menu/menu_rf_stats.xml
new file mode 100644
index 0000000..505e49b
--- /dev/null
+++ b/fmapp2/res/menu/menu_rf_stats.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_recording"
+ android:icon="@drawable/ic_menu_record"
+ android:showAsAction="ifRoom|withText" />
+
+ <item android:id="@+id/menu_record_duration"
+ android:showAsAction="ifRoom|withText"
+ android:title=""/>
+
+</menu>
+
diff --git a/fmapp2/src/com/caf/fmradio/FMRadio.java b/fmapp2/src/com/caf/fmradio/FMRadio.java
index 631ab40..e311172 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadio.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadio.java
@@ -460,7 +460,7 @@
}
}
}
- if(isRecordTimerActive()) {
+ if(isRecording()) {
try {
if (null != mRecordUpdateHandlerThread) {
mRecordUpdateHandlerThread.interrupt();
@@ -468,17 +468,6 @@
}catch (NullPointerException e) {
e.printStackTrace();
}
- long rtimeNow = ((SystemClock.elapsedRealtime()));
- if (rtimeNow < mRecordDuration) {
- try {
- if (null != mService) {
- mService.delayedStop((mRecordDuration - rtimeNow),
- FMRadioService.STOP_RECORD);
- }
- }catch (Exception e) {
- e.printStackTrace();
- }
- }
}
super.onStop();
}
@@ -505,8 +494,8 @@
}
initiateSleepThread();
}
- if(isRecordTimerActive()) {
- Log.d(LOGTAG, "isRecordTimerActive is true");
+ if(isRecording()) {
+ Log.d(LOGTAG,"isRecordTimerActive is true");
try {
if (null != mService) {
mService.cancelDelayedStop(FMRadioService.STOP_RECORD);
@@ -774,66 +763,35 @@
private static final int RECORDTIMER_EXPIRED = 0x1003;
private static final int RECORDTIMER_UPDATE = 0x1004;
- private boolean hasRecordTimerExpired() {
- boolean expired = true;
- /* If record duration is 'until stopped' then return false and exit */
- if (mRecordUntilStopped)
- return false;
- if (isRecordTimerActive()) {
- long timeNow = ((SystemClock.elapsedRealtime()));
- //Log.d(LOGTAG, "hasSleepTimerExpired - " + mSleepAtPhoneTime + " now: "+ timeNow);
- if ((mRecording == false) || (timeNow < mRecordDuration)) {
- expired = false;
- }
- }
- return expired;
- }
-
- private boolean isRecordTimerActive() {
- boolean active = false;
- if (mRecordDuration > 0) {
- active = true;
- }
- return active;
- }
-
private void updateExpiredRecordTime() {
int vis = View.VISIBLE;
- if (mRecordUntilStopped || isRecordTimerActive()) {
+ if(isRecording())
+ {
long timeNow = ((SystemClock.elapsedRealtime()));
- if (mRecordUntilStopped || (mRecordDuration >= timeNow)) {
- long seconds = (timeNow - mRecordStartTime) / 1000;
- String Msg = makeTimeString(seconds);
- mRecordingMsgTV.setText(Msg);
- }else {
- /* Clean up timer */
- mRecordDuration = 0;
- }
+ long seconds = (timeNow - getRecordingStartTime()) / 1000;
+ String Msg = makeTimeString(seconds);
+ mRecordingMsgTV.setText(Msg);
+ mRecordingMsgTV.setVisibility(vis);
}
- mRecordingMsgTV.setVisibility(vis);
}
/* Recorder Thread processing */
private Runnable doRecordProcessing = new Runnable() {
public void run() {
- boolean recordTimerExpired;
- if (mRecordUntilStopped) {
- recordTimerExpired = false;
- }else {
- recordTimerExpired = hasRecordTimerExpired();
- }
- while ((recordTimerExpired == false) &&
- (!Thread.currentThread().isInterrupted())) {
- try {
- Thread.sleep(500);
- Message statusUpdate = new Message();
- statusUpdate.what = RECORDTIMER_UPDATE;
- mUIUpdateHandlerHandler.sendMessage(statusUpdate);
- recordTimerExpired = hasRecordTimerExpired();
- }catch (InterruptedException e) {
- Thread.currentThread().interrupt();
+ while (isRecording() &&
+ (!Thread.currentThread().isInterrupted()))
+ {
+ try
+ {
+ Thread.sleep(500);
+ Message statusUpdate = new Message();
+ statusUpdate.what = RECORDTIMER_UPDATE;
+ mUIUpdateHandlerHandler.sendMessage(statusUpdate);
+ } catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
}
- if(true == recordTimerExpired) {
+ if(!isRecording()) {
Message finished = new Message();
finished.what = RECORDTIMER_EXPIRED;
mUIUpdateHandlerHandler.sendMessage(finished);
@@ -842,24 +800,22 @@
}
};
- private static long mRecordDuration = 0;
- private static long mRecordStartTime = 0;
- private static boolean mRecordUntilStopped = false;
private Thread mRecordUpdateHandlerThread = null;
- private void initiateRecordDurationTimer(long mins) {
+ private long getRecordingStartTime() {
- if(mins == FmSharedPreferences.RECORD_DUR_INDEX_3_VAL) {
- mRecordUntilStopped = true;
- mRecordStartTime = SystemClock.elapsedRealtime();
- }else {
- mRecordUntilStopped = false;
- mRecordDuration = (mRecordStartTime = SystemClock.elapsedRealtime())
- +
- (mins * 60 * 1000);
+ if(mService == null)
+ return 0;
+
+ try {
+ return mService.getRecordingStartTime();
+ }catch(RemoteException e) {
+ return 0;
}
+ }
- Log.d(LOGTAG, "Stop Recording in mins: " + mins);
+ private void initiateRecordDurationTimer(long mins ) {
+ Log.d(LOGTAG, "Stop Recording in mins : " + mins);
initiateRecordThread();
}
private void initiateRecordThread() {
@@ -1775,11 +1731,27 @@
}
}
+ private void setRecordingStopImage() {
+ if(null != mRecordingMsgTV) {
+ mRecordingMsgTV.setCompoundDrawablesWithIntrinsicBounds
+ (R.drawable.recorder_stop, 0, 0, 0);
+ }
+ }
+
+ private void setRecordingStartImage() {
+ if(null != mRecordingMsgTV) {
+ mRecordingMsgTV.setCompoundDrawablesWithIntrinsicBounds
+ (R.drawable.recorder_start, 0, 0, 0);
+ }
+ }
+
private void startRecordingTimer() {
mRecording = true;
int durationInMins = FmSharedPreferences.getRecordDuration();
Log.e(LOGTAG, " Fected duration:" + durationInMins );
initiateRecordDurationTimer( durationInMins );
+ setRecordingStopImage();
+ invalidateOptionsMenu();
}
private void stopRecording() {
@@ -1790,8 +1762,7 @@
}
if(null != mRecordingMsgTV) {
mRecordingMsgTV.setText("");
- mRecordingMsgTV.setCompoundDrawablesWithIntrinsicBounds
- (R.drawable.recorder_start, 0, 0, 0);
+ setRecordingStartImage();
}
if (mService != null) {
try {
@@ -1800,7 +1771,7 @@
e.printStackTrace();
}
}
- mRecordDuration = 0;
+ invalidateOptionsMenu();
}
private boolean isRecording() {
@@ -1874,6 +1845,11 @@
if ((mRecordingMsgTV != null) && !isRecording()) {
mRecordingMsgTV.setText("");
}
+ if(isRecording()) {
+ setRecordingStopImage();
+ }else {
+ setRecordingStartImage();
+ }
}else {
if (mRadioTextScroller != null) {
mRadioTextScroller.stopScroll();
@@ -2376,13 +2352,11 @@
}
case RECORDTIMER_EXPIRED: {
Log.d(LOGTAG, "mUIUpdateHandlerHandler - RECORDTIMER_EXPIRED");
- mRecordDuration = 0;
//Clear the Recorder text
mRecordingMsgTV.setText("");
if (mRecording != false) {
DebugToasts("Stop Recording", Toast.LENGTH_SHORT);
stopRecording();
- invalidateOptionsMenu();
}
return;
}
@@ -2921,16 +2895,7 @@
e.printStackTrace();
}
if (isRecording()) {
- mRecordingMsgTV.setCompoundDrawablesWithIntrinsicBounds
- (R.drawable.recorder_stop, 0, 0, 0);
initiateRecordThread();
- }else if((mRecordDuration > 0) &&
- (mRecordUpdateHandlerThread != null)) {
- mRecordUpdateHandlerThread.interrupt();
- if(mRecordingMsgTV != null) {
- mRecordingMsgTV.setText("");
- }
- mRecordDuration = 0;
}
return;
}else {
diff --git a/fmapp2/src/com/caf/fmradio/FMRadioService.java b/fmapp2/src/com/caf/fmradio/FMRadioService.java
index f3b0a78..fb5147e 100644
--- a/fmapp2/src/com/caf/fmradio/FMRadioService.java
+++ b/fmapp2/src/com/caf/fmradio/FMRadioService.java
@@ -294,6 +294,7 @@
if (state == RECORD_START) {
Log.d(LOGTAG, "FM Recording started");
mFmRecordingOn = true;
+ mSampleStart = SystemClock.elapsedRealtime();
try {
if ((mServiceInUse) && (mCallbacks != null) ) {
Log.d(LOGTAG, "start recording thread");
@@ -312,6 +313,7 @@
} catch (RemoteException e) {
e.printStackTrace();
}
+ mSampleStart = 0;
}
}
}
@@ -688,6 +690,14 @@
private void sendRecordIntent(int action) {
Intent intent = new Intent(ACTION_FM_RECORDING);
intent.putExtra("state", action);
+ if(action == RECORD_START) {
+ int mRecordDuration = -1;
+ if(FmSharedPreferences.getRecordDuration() !=
+ FmSharedPreferences.RECORD_DUR_INDEX_3_VAL) {
+ mRecordDuration = (FmSharedPreferences.getRecordDuration() * 60 * 1000);
+ }
+ intent.putExtra("record_duration", mRecordDuration);
+ }
Log.d(LOGTAG, "Sending Recording intent for = " +action);
getApplicationContext().sendBroadcast(intent);
}
@@ -1468,6 +1478,10 @@
{
return (mService.get().setRxRepeatCount(count));
}
+ public long getRecordingStartTime()
+ {
+ return (mService.get().getRecordingStartTime());
+ }
}
private final IBinder mBinder = new ServiceStub(this);
@@ -2928,6 +2942,9 @@
return false;
}
+ public long getRecordingStartTime() {
+ return mSampleStart;
+ }
//handling the sleep and record stop when FM App not in focus
private void delayedStop(long duration, int nType) {
int whatId = (nType == STOP_SERVICE) ? STOPSERVICE_ONSLEEP: STOPRECORD_ONTIMEOUT;
diff --git a/fmapp2/src/com/caf/fmradio/FMStats.java b/fmapp2/src/com/caf/fmradio/FMStats.java
index 52b9caa..18ab71c 100644
--- a/fmapp2/src/com/caf/fmradio/FMStats.java
+++ b/fmapp2/src/com/caf/fmradio/FMStats.java
@@ -65,6 +65,9 @@
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MenuInflater;
import android.os.SystemClock;
import java.io.FileNotFoundException;
@@ -75,6 +78,8 @@
import android.os.SystemProperties;
import java.io.BufferedReader;
import java.io.FileReader;
+import java.util.Formatter;
+import java.util.Locale;
public class FMStats extends Activity {
@@ -177,6 +182,8 @@
private Thread mMultiUpdateThread = null;
private static final int STATUS_UPDATE = 1;
private static final int STATUS_DONE = 2;
+ private static final int RECORDTIMER_UPDATE = 3;
+ private static final int RECORDTIMER_EXPIRED = 4;
private static final int STOP_ROW_ID = 200;
private static final int NEW_ROW_ID = 300;
private int mStopIds = STOP_ROW_ID;
@@ -230,6 +237,15 @@
private int curSweepMthd = 0;
+ private Thread mRecordUpdateHandlerThread = null;
+ boolean mRecording = false;
+
+
+ private static StringBuilder sFormatBuilder = new StringBuilder();
+ private static Formatter sFormatter = new Formatter(sFormatBuilder, Locale
+ .getDefault());
+ private static final Object[] sTimeArgs = new Object[5];
+
private final String FREQ_LIST_FILE_NAME = "/freq_list_comma_separated.txt";
private static final String BAND_SWEEP_START_DELAY_TIMEOUT = "com.caf.fmradio.SWEEP_START_DELAY_EXP";
private static final String BAND_SWEEP_DWELL_DELAY_TIMEOUT = "com.caf.fmradio.SWEEP_DWELL_DELAY_EXP";
@@ -328,6 +344,30 @@
registerBandSweepDwellExprdListener();
}
+ @Override
+ public void onStart() {
+ super.onStart();
+ if(isRecording()) {
+ Log.d(LOGTAG, "onStart");
+ initiateRecordThread();
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ if(isRecording()) {
+ try {
+ if(null != mRecordUpdateHandlerThread) {
+ mRecordUpdateHandlerThread.interrupt();
+ }
+ }catch (NullPointerException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
public void onDestroy() {
stopCurTest();
@@ -1894,6 +1934,17 @@
case STATUS_DONE:
SetButtonState(true);
break;
+ case RECORDTIMER_EXPIRED:
+ Log.d(LOGTAG, "mUIUpdateHandlerHandler - RECORDTIMER_EXPIRED");
+ if(!isRecording()) {
+ Log.d(LOGTAG, "Stop Recording");
+ stopRecording();
+ }
+ break;
+ case RECORDTIMER_UPDATE:
+ Log.d(LOGTAG, "mUIUpdateHandlerHandler - RECORDTIMER_UPDATE");
+ updateExpiredRecordTime();
+ break;
}
}
};
@@ -1972,6 +2023,9 @@
{
e.printStackTrace();
}
+ if(isRecording()) {
+ initiateRecordThread();
+ }
return;
} else
{
@@ -1989,17 +2043,19 @@
public void onEnabled()
{
Log.d(LOGTAG, "mServiceCallbacks.onEnabled :");
+ invalidateOptionsMenu();
}
public void onDisabled()
{
Log.d(LOGTAG, "mServiceCallbacks.onDisabled :");
- stopCurTest();
+ stopAllOperations();
}
public void onRadioReset()
{
Log.d(LOGTAG, "mServiceCallbacks.onRadioReset :");
+ stopAllOperations();
}
public void onTuneStatusChanged()
@@ -2064,6 +2120,7 @@
public void onRecordingStopped()
{
Log.d(LOGTAG, "mServiceCallbacks.onDisabled :");
+ stopRecording();
}
public void onFinishActivity()
{
@@ -2072,6 +2129,10 @@
public void onRecordingStarted()
{
Log.d(LOGTAG, "mServiceCallbacks.onRecordingStarted:");
+ int durationInMins = FmSharedPreferences.getRecordDuration();
+ Log.e(LOGTAG, " Fected duration: " + durationInMins);
+ initiateRecordDurationTimer(durationInMins);
+ invalidateOptionsMenu();
}
};
/* Radio Vars */
@@ -2314,4 +2375,187 @@
mNextFreqInterface = null;
}
}
- }
+
+ public boolean isRecording() {
+ if(mService == null)
+ return false;
+ try {
+ return mService.isFmRecordingOn();
+ }catch(RemoteException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.menu_rf_stats, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+ MenuItem item;
+
+ item = menu.findItem(R.id.menu_recording);
+ if(item != null && !isRecording()) {
+ item.setTitle(R.string.menu_record_start);
+ item.setEnabled(isFmOn());
+ }else if(item != null) {
+ item.setTitle(R.string.menu_record_stop);
+ setRecordDurationDisplay(menu, R.id.menu_record_duration);
+ }
+ return true;
+ }
+
+ private void setRecordDurationDisplay(Menu menu, int id) {
+ MenuItem item;
+ long timeNow;
+ long seconds;
+
+ if(menu == null)
+ return;
+ item = menu.findItem(id);
+ if(item != null) {
+ timeNow = SystemClock.elapsedRealtime();
+ seconds = (timeNow - getRecordingStartTime()) / 1000;
+ item.setTitle(makeTimeString(seconds));
+ }
+ }
+
+ private void startRecording() {
+ if(isFmOn()) {
+ try {
+ mService.startRecording();
+ }catch(RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private void stopRecording() {
+ if(null != mRecordUpdateHandlerThread) {
+ mRecordUpdateHandlerThread.interrupt();
+ }
+ if(mService != null) {
+ try {
+ mService.stopRecording();
+ }catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ invalidateOptionsMenu();
+ }
+
+ private long getRecordingStartTime() {
+ if(mService == null)
+ return 0;
+ try {
+ return mService.getRecordingStartTime();
+ }catch(RemoteException e) {
+ return 0;
+ }
+ }
+
+ private void initiateRecordDurationTimer(long mins ) {
+ Log.d(LOGTAG, "Stop Recording in mins : " + mins);
+ initiateRecordThread();
+ }
+
+ private void initiateRecordThread() {
+ if(mRecordUpdateHandlerThread == null) {
+ mRecordUpdateHandlerThread = new Thread(null, doRecordProcessing,
+ "RecordUpdateThread");
+ }
+ /* Launch the dummy thread to simulate the transfer progress */
+ Log.d(LOGTAG, "Thread State: " + mRecordUpdateHandlerThread.getState());
+ if(mRecordUpdateHandlerThread.getState() == Thread.State.TERMINATED) {
+ mRecordUpdateHandlerThread = new Thread(null, doRecordProcessing,
+ "RecordUpdateThread");
+ }
+ /* If the thread state is "new" then the thread has not yet started */
+ if(mRecordUpdateHandlerThread.getState() == Thread.State.NEW) {
+ mRecordUpdateHandlerThread.start();
+ }
+ }
+
+ /* Recorder Thread processing */
+ private Runnable doRecordProcessing = new Runnable() {
+ public void run() {
+ while(isRecording() &&
+ (!Thread.currentThread().isInterrupted())) {
+ try {
+ Thread.sleep(500);
+ Message statusUpdate = new Message();
+ statusUpdate.what = RECORDTIMER_UPDATE;
+ mUIUpdateHandlerHandler.sendMessage(statusUpdate);
+ }catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ if(!isRecording()) {
+ Message finished = new Message();
+ finished.what = RECORDTIMER_EXPIRED;
+ mUIUpdateHandlerHandler.sendMessage(finished);
+ }
+ }
+ }
+ };
+
+ private void updateExpiredRecordTime() {
+ int vis = View.VISIBLE;
+ if(isRecording()) {
+ invalidateOptionsMenu();
+ }
+ }
+
+ private String makeTimeString(long secs) {
+ String durationformat = getString(R.string.durationformat);
+
+ /** Provide multiple arguments so the format can be changed easily by
+ * modifying the xml.
+ **/
+ sFormatBuilder.setLength(0);
+
+ final Object[] timeArgs = sTimeArgs;
+ timeArgs[0] = secs / 3600;
+ timeArgs[1] = secs / 60;
+ timeArgs[2] = (secs / 60) % 60;
+ timeArgs[3] = secs;
+ timeArgs[4] = secs % 60;
+
+ return sFormatter.format(durationformat, timeArgs).toString();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId())
+ {
+ case R.id.menu_recording:
+ if(isRecording()) {
+ stopRecording();
+ }else {
+ startRecording();
+ }
+ break;
+ }
+ return true;
+ }
+
+ private boolean isFmOn() {
+ boolean status = false;
+
+ if(mService != null) {
+ try {
+ status = mService.isFmOn();
+ }catch(RemoteException e) {
+ }
+ }
+ return status;
+ }
+
+ private void stopAllOperations() {
+ stopCurTest();
+ stopRecording();
+ }
+}
diff --git a/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl b/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl
index c2dc7fb..fe54124 100644
--- a/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl
+++ b/fmapp2/src/com/caf/fmradio/IFMRadioService.aidl
@@ -70,5 +70,6 @@
int getGoodChRmssiTh();
int getAfJmpRmssiSamplesCnt();
boolean setRxRepeatCount(int count);
+ long getRecordingStartTime();
}