Merge pull request #636 from google/clearvu2

OboeTester: clear VU meters when restarting
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AutoGlitchActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AutoGlitchActivity.java
index 61f8adc..b587d82 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AutoGlitchActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/AutoGlitchActivity.java
@@ -27,6 +27,7 @@
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import java.io.IOException;
 import java.util.Date;
 
 public class AutoGlitchActivity extends GlitchActivity implements Runnable {
@@ -187,54 +188,77 @@
 
         // Give previous stream time to close and release resources. Avoid race conditions.
         Thread.sleep(1000);
-        super.startAudioTest(); // this will fill in actualConfig
-        log("Actual:");
-        log(getConfigText(actualInConfig));
-        log(getConfigText(actualOutConfig));
+        boolean openFailed = false;
+        try {
+            super.startAudioTest(); // this will fill in actualConfig
+            log("Actual:");
+            log(getConfigText(actualInConfig));
+            log(getConfigText(actualOutConfig));
+            // Set output size to a level that will avoid glitches.
+            int sizeFrames = mAudioOutTester.getCurrentAudioStream().getBufferCapacityInFrames();
+            mAudioOutTester.getCurrentAudioStream().setBufferSizeInFrames(sizeFrames);
+        } catch (IOException e) {
+            openFailed = true;
+            log(e.getMessage());
+        }
 
-        // Set output size to a level that will avoid glitches.
-        int sizeFrames = mAudioOutTester.getCurrentAudioStream().getBufferCapacityInFrames();
-        mAudioOutTester.getCurrentAudioStream().setBufferSizeInFrames(sizeFrames);
 
         // The test would only be worth running if we got the configuration we requested on input or output.
         boolean valid = true;
         // No point running the test if we don't get the sharing mode we requested.
-        if (actualInConfig.getSharingMode() != sharingMode
-            && actualOutConfig.getSharingMode() != sharingMode) {
+        if (!openFailed && actualInConfig.getSharingMode() != sharingMode
+                && actualOutConfig.getSharingMode() != sharingMode) {
             log("did not get requested sharing mode");
             valid = false;
         }
         // We don't skip based on performance mode because if you request LOW_LATENCY you might
         // get a smaller burst than if you request NONE.
 
-        if (valid) {
+        if (!openFailed && valid) {
             Thread.sleep(mDurationSeconds * 1000);
         }
+        int inXRuns = 0;
+        int outXRuns = 0;
 
-        int inXRuns = mAudioInputTester.getCurrentAudioStream().getXRunCount();
-        int outXRuns = mAudioOutTester.getCurrentAudioStream().getXRunCount();
+        if (!openFailed) {
+            // get xRuns before closing the streams.
+            inXRuns = mAudioInputTester.getCurrentAudioStream().getXRunCount();
+            outXRuns = mAudioOutTester.getCurrentAudioStream().getXRunCount();
 
-        super.stopAudioTest();
+            super.stopAudioTest();
+        }
+
         if (valid) {
-            boolean passed = (getMaxSecondsWithNoGlitch()
-                    > (mDurationSeconds - SETUP_TIME_SECONDS));
-            String resultText = "#gl = " + getLastGlitchCount()
-                    + ", time no glitch = " + getMaxSecondsWithNoGlitch() + " secs"
-                    + ", xruns = " + inXRuns + "/" + outXRuns;
-            log(resultText + ", " + (passed ? TEXT_PASS : TEXT_FAIL)
-            );
-            if (!passed) {
+            if (openFailed) {
                 mFailedSummary.append("------ #" + mTestCount);
                 mFailedSummary.append("\n");
-                mFailedSummary.append("  ");
                 mFailedSummary.append(getConfigText(requestedInConfig));
                 mFailedSummary.append("\n");
-                mFailedSummary.append("    ");
-                mFailedSummary.append(resultText);
+                mFailedSummary.append(getConfigText(requestedOutConfig));
                 mFailedSummary.append("\n");
+                mFailedSummary.append("Open failed!\n");
                 mFailCount++;
             } else {
-                mPassCount++;
+                log("Result:");
+                boolean passed = (getMaxSecondsWithNoGlitch()
+                        > (mDurationSeconds - SETUP_TIME_SECONDS));
+                String resultText = getShortReport();
+                resultText += ", xruns = " + inXRuns + "/" + outXRuns;
+                resultText += ", " + (passed ? TEXT_PASS : TEXT_FAIL);
+                log(resultText);
+                if (!passed) {
+                    mFailedSummary.append("------ #" + mTestCount);
+                    mFailedSummary.append("\n");
+                    mFailedSummary.append("  ");
+                    mFailedSummary.append(getConfigText(actualInConfig));
+                    mFailedSummary.append("\n");
+                    mFailedSummary.append("    ");
+                    mFailedSummary.append(resultText);
+                    mFailedSummary.append("\n");
+                    mFailCount++;
+                } else {
+                    mPassCount++;
+                }
             }
         } else {
             log(TEXT_SKIP);
@@ -287,7 +311,7 @@
             super.stopAudioTest();
             log("\n==== SUMMARY ========");
             if (mFailCount > 0) {
-                log("# Passed = " + mPassCount + ", # Failed = " + mFailCount);
+                log(mPassCount + " passed. " + mFailCount + " failed.");
                 log("These tests FAILED:");
                 log(mFailedSummary.toString());
             } else {
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/EchoActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/EchoActivity.java
index 5f430c9..688d1ab 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/EchoActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/EchoActivity.java
@@ -22,6 +22,8 @@
 import android.widget.SeekBar;
 import android.widget.TextView;
 
+import java.io.IOException;
+
 /**
  * Activity to capture audio and then send a delayed copy to output.
  * There is a fader for setting delay time
@@ -107,12 +109,16 @@
     }
 
     public void onStartEcho(View view) {
-        openAudio();
-        startAudio();
-        setDelayTime(mDelayTime);
-        mStartButton.setEnabled(false);
-        mStopButton.setEnabled(true);
-        keepScreenOn(true);
+        try {
+            openAudio();
+            startAudio();
+            setDelayTime(mDelayTime);
+            mStartButton.setEnabled(false);
+            mStopButton.setEnabled(true);
+            keepScreenOn(true);
+        } catch (IOException e) {
+            showErrorToast(e.getMessage());
+        }
     }
 
     public void onStopEcho(View view) {
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/GlitchActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/GlitchActivity.java
index 9274885..c9374e8 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/GlitchActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/GlitchActivity.java
@@ -23,6 +23,8 @@
 import android.widget.Button;
 import android.widget.TextView;
 
+import java.io.IOException;
+
 /**
  * Activity to measure the number of glitches.
  */
@@ -187,6 +189,15 @@
             return message.toString();
         }
 
+        public String getShortReport() {
+            String resultText = "#glitches = " + getLastGlitchCount()
+                    + ", #resets = " + getLastResetCount()
+                    + ", max no glitch = " + getMaxSecondsWithNoGlitch() + " secs\n";
+            resultText += String.format("SNR = %5.1f db", mSignalToNoiseDB);
+            resultText += ", #locked = " + mLastLockedFrames;
+            return resultText;
+        }
+
         private void updateStatusText() {
             mLastGlitchReport = getCurrentStatusReport();
             setAnalyzerText(mLastGlitchReport);
@@ -196,9 +207,12 @@
             return mMaxSecondsWithoutGlitches;
         }
 
-        public int geMLastGlitchCount() {
+        public int getLastGlitchCount() {
             return mLastGlitchCount;
         }
+        public int getLastResetCount() {
+            return mLastResetCount;
+        }
     }
 
     private GlitchSniffer mGlitchSniffer = new GlitchSniffer();
@@ -243,7 +257,7 @@
     }
 
     // Called on UI thread
-    public void onStartAudioTest(View view) {
+    public void onStartAudioTest(View view) throws IOException {
         startAudioTest();
         mStartButton.setEnabled(false);
         mStopButton.setEnabled(true);
@@ -251,7 +265,7 @@
         keepScreenOn(true);
     }
 
-    public void startAudioTest() {
+    public void startAudioTest() throws IOException {
         openAudio();
         startAudio();
         mGlitchSniffer.startSniffer();
@@ -295,8 +309,8 @@
         return mGlitchSniffer.getMaxSecondsWithNoGlitch();
     }
 
-    public int getLastGlitchCount() {
-        return mGlitchSniffer.geMLastGlitchCount();
+    public String getShortReport() {
+        return mGlitchSniffer.getShortReport();
     }
 
     @Override
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/ManualGlitchActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/ManualGlitchActivity.java
index cdb71eb..1465dcb 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/ManualGlitchActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/ManualGlitchActivity.java
@@ -22,6 +22,7 @@
 import android.os.Handler;
 import android.os.Looper;
 
+import java.io.IOException;
 import java.util.Date;
 
 public class ManualGlitchActivity extends GlitchActivity {
@@ -159,19 +160,25 @@
         int numBursts = mBundleFromIntent.getInt(KEY_BUFFER_BURSTS, VALUE_DEFAULT_BUFFER_BURSTS);
         mBundleFromIntent = null;
 
-        onStartAudioTest(null);
+        try {
+            onStartAudioTest(null);
+            int sizeFrames = mAudioOutTester.getCurrentAudioStream().getFramesPerBurst() * numBursts;
+            mAudioOutTester.getCurrentAudioStream().setBufferSizeInFrames(sizeFrames);
 
-        int sizeFrames = mAudioOutTester.getCurrentAudioStream().getFramesPerBurst() * numBursts;
-        mAudioOutTester.getCurrentAudioStream().setBufferSizeInFrames(sizeFrames);
+            // Schedule the end of the test.
+            Handler handler = new Handler(Looper.getMainLooper()); // UI thread
+            handler.postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    stopAutomaticTest();
+                }
+            }, durationSeconds * 1000);
+        } catch (IOException e) {
+            String report = "Open failed: " + e.getMessage();
+            maybeWriteTestResult(report);
+            mTestRunningByIntent = false;
+        }
 
-        // Schedule the end of the test.
-        Handler handler = new Handler(Looper.getMainLooper()); // UI thread
-        handler.postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                stopAutomaticTest();
-            }
-        }, durationSeconds * 1000);
     }
 
     void stopAutomaticTest() {
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RecorderActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RecorderActivity.java
index eb75662..c59b66a 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RecorderActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RecorderActivity.java
@@ -26,6 +26,7 @@
 import android.widget.Button;
 
 import java.io.File;
+import java.io.IOException;
 
 /**
  * Activity to record and play back audio.
@@ -66,11 +67,15 @@
     }
 
     public void onStartRecording(View view) {
-        openAudio();
-        startAudio();
-        mRecorderState = STATE_RECORDING;
-        mGotRecording = true;
-        updateButtons();
+        try {
+            openAudio();
+            startAudio();
+            mRecorderState = STATE_RECORDING;
+            mGotRecording = true;
+            updateButtons();
+        } catch (IOException e) {
+            showErrorToast(e.getMessage());
+        }
     }
 
     public void onStopRecordPlay(View view) {
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RoundTripLatencyActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RoundTripLatencyActivity.java
index 0a8fb45..1a4428b 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RoundTripLatencyActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/RoundTripLatencyActivity.java
@@ -29,6 +29,8 @@
 import android.widget.SeekBar;
 import android.widget.TextView;
 
+import java.io.IOException;
+
 /**
  * Activity to measure latency on a full duplex stream.
  */
@@ -225,20 +227,24 @@
     }
 
     public void onMeasure(View view) {
-        openAudio();
-        if (mBufferBursts >= 0) {
-            AudioStreamBase stream = mAudioOutTester.getCurrentAudioStream();
-            int framesPerBurst = stream.getFramesPerBurst();
-            stream.setBufferSizeInFrames(framesPerBurst * mBufferBursts);
-            // override buffer size fader
-            mBufferSizeView.setEnabled(false);
-            mBufferBursts = -1;
+        try {
+            openAudio();
+            if (mBufferBursts >= 0) {
+                AudioStreamBase stream = mAudioOutTester.getCurrentAudioStream();
+                int framesPerBurst = stream.getFramesPerBurst();
+                stream.setBufferSizeInFrames(framesPerBurst * mBufferBursts);
+                // override buffer size fader
+                mBufferSizeView.setEnabled(false);
+                mBufferBursts = -1;
+            }
+            startAudio();
+            mLatencySniffer.startSniffer();
+            mMeasureButton.setEnabled(false);
+            mCancelButton.setEnabled(true);
+            mShareButton.setEnabled(false);
+        } catch (IOException e) {
+            showErrorToast(e.getMessage());
         }
-        startAudio();
-        mLatencySniffer.startSniffer();
-        mMeasureButton.setEnabled(false);
-        mCancelButton.setEnabled(true);
-        mShareButton.setEnabled(false);
     }
 
     public void onCancel(View view) {
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestAudioActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestAudioActivity.java
index d68fc80..c56be24 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestAudioActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestAudioActivity.java
@@ -330,7 +330,11 @@
     }
 
     public void openAudio(View view) {
-        openAudio();
+        try {
+            openAudio();
+        } catch (Exception e) {
+            showErrorToast(e.getMessage());
+        }
     }
 
     public void startAudio(View view) {
@@ -365,37 +369,33 @@
         return mSampleRate;
     }
     
-    public void openAudio() {
+    public void openAudio() throws IOException {
         closeAudio();
 
         int sampleRate = 0;
-        try {
-            // Open output streams then open input streams.
-            // This is so that the capacity of input stream can be expanded to
-            // match the burst size of the output for full duplex.
-            for (StreamContext streamContext : mStreamContexts) {
-                if (!streamContext.isInput()) {
-                    openStreamContext(streamContext);
-                    int streamSampleRate = streamContext.tester.actualConfiguration.getSampleRate();
-                    if (sampleRate == 0) {
-                        sampleRate = streamSampleRate;
-                    }
+
+        // Open output streams then open input streams.
+        // This is so that the capacity of input stream can be expanded to
+        // match the burst size of the output for full duplex.
+        for (StreamContext streamContext : mStreamContexts) {
+            if (!streamContext.isInput()) {
+                openStreamContext(streamContext);
+                int streamSampleRate = streamContext.tester.actualConfiguration.getSampleRate();
+                if (sampleRate == 0) {
+                    sampleRate = streamSampleRate;
                 }
             }
-            for (StreamContext streamContext : mStreamContexts) {
-                if (streamContext.isInput()) {
-                    if (sampleRate != 0) {
-                        streamContext.tester.requestedConfiguration.setSampleRate(sampleRate);
-                    }
-                    openStreamContext(streamContext);
-                }
-            }
-            updateEnabledWidgets();
-            mStreamSniffer.startStreamSniffer();
-        } catch (Exception e) {
-            e.printStackTrace();
-            showErrorToast(e.getMessage());
         }
+        for (StreamContext streamContext : mStreamContexts) {
+            if (streamContext.isInput()) {
+                if (sampleRate != 0) {
+                    streamContext.tester.requestedConfiguration.setSampleRate(sampleRate);
+                }
+                openStreamContext(streamContext);
+            }
+        }
+        updateEnabledWidgets();
+        mStreamSniffer.startStreamSniffer();
     }
 
     private void openStreamContext(StreamContext streamContext) throws IOException {
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestInputActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestInputActivity.java
index 24d2bdb..0f42e9e 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestInputActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestInputActivity.java
@@ -36,6 +36,7 @@
 import com.google.sample.oboe.manualtest.R;
 
 import java.io.File;
+import java.io.IOException;
 
 /**
  * Test Oboe Capture
@@ -117,7 +118,7 @@
     }
 
     @Override
-    public void openAudio() {
+    public void openAudio() throws IOException {
         if (!isRecordPermissionGranted()){
             requestRecordPermission();
             return;
@@ -163,7 +164,11 @@
                     .show();
         } else {
             // Permission was granted
-            super.openAudio();
+            try {
+                super.openAudio();
+            } catch (IOException e) {
+                showErrorToast(e.getMessage());
+            }
         }
     }
 
diff --git a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivity.java b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivity.java
index 092fe03..1f623f2 100644
--- a/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/google/sample/oboe/manualtest/TestOutputActivity.java
@@ -23,6 +23,8 @@
 import android.widget.CheckBox;
 import android.widget.Spinner;
 
+import java.io.IOException;
+
 /**
  * Base class for output test activities
  */
@@ -81,7 +83,7 @@
         setActivityType(ACTIVITY_TEST_OUTPUT);
     }
 
-    public void openAudio() {
+    public void openAudio() throws IOException {
         super.openAudio();
         int channelCount = mAudioOutTester.getCurrentAudioStream().getChannelCount();
         configureChannelBoxes(channelCount);
diff --git a/apps/OboeTester/app/src/main/res/values/strings.xml b/apps/OboeTester/app/src/main/res/values/strings.xml
index 72d3cba..0e6844a 100644
--- a/apps/OboeTester/app/src/main/res/values/strings.xml
+++ b/apps/OboeTester/app/src/main/res/values/strings.xml
@@ -73,8 +73,10 @@
 
     <string-array name="glitch_times">
         <item>10</item>
+        <item>25</item>
         <item>70</item>
-        <item>310</item>
+        <item>200</item>
+        <item>600</item>
     </string-array>
 
     <string name="performance_prompt">Perf:</string>