diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
index b321c60..4bd642d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
@@ -70,10 +70,7 @@
     private static final String INFO_DIALOG_MESSAGE_ID = "infoDialogMessageId";
 
     // ReportLog file for CTS-Verifier. The "stream" name gets mapped to the test class name.
-    public static final String GENERAL_TESTS_REPORT_LOG_NAME = "CtsVerifierGeneralTestCases";
-    public static final String AUDIO_TESTS_REPORT_LOG_NAME = "CtsVerifierAudioTestCases";
-
-    private static final String SECTION_UNDEFINED = "undefined_section_name";
+    private static final String REPORT_LOG_NAME = "CTS-Verifier-Log";
 
     // Interface mostly for making documentation and refactoring easier...
     public interface PassFailActivity {
@@ -115,16 +112,10 @@
         void setTestResultAndFinish(boolean passed);
 
         /**
-         * @return The name of the file to store the (suite of) ReportLog information.
+         * @return A unique name (derived from the test class name) to serve as a section
+         * header in the CtsVerifierReportLog file.
          */
-        public String getReportFileName();
-
-        /**
-         * @return A unique name to serve as a section header in the CtsVerifierReportLog file.
-         * Tests need to conform to the underscore_delineated_name standard for use with
-         * the protobuff/json ReportLog parsing in Google3
-         */
-        public String getReportSectionName();
+        String getReportSectionName();
 
         /**
          * Test subclasses can override this to record their CtsVerifierReportLogs.
@@ -147,7 +138,7 @@
         private final TestResultHistoryCollection mHistoryCollection;
 
         public Activity() {
-            this.mReportLog = new CtsVerifierReportLog(getReportFileName(), getReportSectionName());
+            this.mReportLog = new CtsVerifierReportLog(REPORT_LOG_NAME, getReportSectionName());
             this.mHistoryCollection = new TestResultHistoryCollection();
         }
 
@@ -211,15 +202,9 @@
             return mReportLog;
         }
 
-        /**
-         * @return The name of the file to store the (suite of) ReportLog information.
-         */
         @Override
-        public String getReportFileName() { return GENERAL_TESTS_REPORT_LOG_NAME; }
-
-        @Override
-        public String getReportSectionName() {
-            return setTestNameSuffix(sCurrentDisplayMode, SECTION_UNDEFINED);
+        public final String getReportSectionName() {
+            return setTestNameSuffix(sCurrentDisplayMode, getClass().getName());
         }
 
         @Override
@@ -255,7 +240,7 @@
         private final TestResultHistoryCollection mHistoryCollection;
 
         public ListActivity() {
-            this.mReportLog = new CtsVerifierReportLog(getReportFileName(), getReportSectionName());
+            this.mReportLog = new CtsVerifierReportLog(REPORT_LOG_NAME, getReportSectionName());
             this.mHistoryCollection = new TestResultHistoryCollection();
         }
 
@@ -301,15 +286,9 @@
             return mReportLog;
         }
 
-        /**
-         * @return The name of the file to store the (suite of) ReportLog information.
-         */
         @Override
-        public String getReportFileName() { return GENERAL_TESTS_REPORT_LOG_NAME; }
-
-        @Override
-        public String getReportSectionName() {
-            return setTestNameSuffix(sCurrentDisplayMode, SECTION_UNDEFINED);
+        public final String getReportSectionName() {
+            return setTestNameSuffix(sCurrentDisplayMode, getClass().getName());
         }
 
         @Override
@@ -347,7 +326,9 @@
         public TestListActivity() {
             // TODO(b/186555602): temporary hack^H^H^H^H workaround to fix crash
             // This DOES NOT in fact fix that bug.
-            this.mReportLog = new CtsVerifierReportLog(getReportFileName(), getReportSectionName());
+            // if (true) this.mReportLog = new CtsVerifierReportLog(REPORT_LOG_NAME, "42"); else
+
+            this.mReportLog = new CtsVerifierReportLog(REPORT_LOG_NAME, getReportSectionName());
         }
 
         @Override
@@ -392,18 +373,11 @@
             return mReportLog;
         }
 
-        /**
-         * @return The name of the file to store the (suite of) ReportLog information.
-         */
         @Override
-        public String getReportFileName() { return GENERAL_TESTS_REPORT_LOG_NAME; }
-
-        @Override
-        public String getReportSectionName() {
-            return setTestNameSuffix(sCurrentDisplayMode, SECTION_UNDEFINED);
+        public final String getReportSectionName() {
+            return setTestNameSuffix(sCurrentDisplayMode, getClass().getName());
         }
 
-
         /**
          * Get existing test history to aggregate.
          */
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
index 495c3ef..fe314c4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
@@ -23,7 +23,6 @@
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
-import android.util.Log;
 
 import com.android.compatibility.common.util.FileUtil;
 import com.android.compatibility.common.util.IInvocationResult;
@@ -50,8 +49,6 @@
  * Background task to generate a report and save it to external storage.
  */
 class ReportExporter extends AsyncTask<Void, Void, String> {
-    private static final String TAG = ReportExporter.class.getSimpleName();
-    private static final boolean DEBUG = true;
 
     public static final String REPORT_DIRECTORY = "VerifierReports";
     public static final String LOGS_DIRECTORY = "ReportLogFiles";
@@ -79,15 +76,11 @@
     // so that they will get ZIPped into the transmitted file.
     //
     private void copyReportFiles(File tempDir) {
-        if (DEBUG) {
-            Log.d(TAG, "copyReportFiles(" + tempDir.getAbsolutePath() + ")");
-        }
-
         File externalStorageDirectory = Environment.getExternalStorageDirectory();
         File reportLogFolder =
                 new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                         + File.separator
-                        + LOGS_DIRECTORY);
+                        + REPORT_DIRECTORY);
         File[] reportLogFiles = reportLogFolder.listFiles();
 
         // if no ReportLog files have been created (i.e. the folder doesn't exist)
@@ -163,9 +156,6 @@
     }
 
     private void saveReportOnInternalStorage(File reportZipFile) {
-        if (DEBUG) {
-            Log.d(TAG, "---- saveReportOnInternalStorage(" + reportZipFile.getAbsolutePath() + ")");
-        }
         try {
             ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
                     reportZipFile, ParcelFileDescriptor.MODE_READ_ONLY);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
index 6233f2c..4ce2a12 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
@@ -400,8 +400,6 @@
             }
         }
 
-        reportHeadsetPort(mHeadsetDeviceInfo != null);
-
         showConnectedDevice();
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackBaseActivity.java
new file mode 100644
index 0000000..78e34d3
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackBaseActivity.java
@@ -0,0 +1,686 @@
+/*
+ * Copyright (C) 2015 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.cts.verifier.audio;
+
+import android.app.AlertDialog;
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.MediaRecorder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.cts.verifier.audio.audiolib.AudioSystemFlags;
+import com.android.cts.verifier.audio.audiolib.StatUtils;
+import com.android.cts.verifier.audio.audiolib.AudioUtils;
+import com.android.cts.verifier.CtsVerifierReportLog;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode;
+import static com.android.cts.verifier.TestListAdapter.setTestNameSuffix;
+
+/**
+ * Base class for testing activitiees that require audio loopback hardware..
+ */
+public class AudioLoopbackBaseActivity extends PassFailButtons.Activity {
+    private static final String TAG = "AudioLoopbackBaseActivity";
+
+    // JNI load
+    static {
+        try {
+            System.loadLibrary("audioloopback_jni");
+        } catch (UnsatisfiedLinkError e) {
+            Log.e(TAG, "Error loading Audio Loopback JNI library");
+            Log.e(TAG, "e: " + e);
+            e.printStackTrace();
+        }
+
+        /* TODO: gracefully fail/notify if the library can't be loaded */
+    }
+    protected AudioManager mAudioManager;
+
+    // UI
+    TextView mInputDeviceTxt;
+    TextView mOutputDeviceTxt;
+
+    TextView mAudioLevelText;
+    SeekBar mAudioLevelSeekbar;
+
+    TextView mTestPathTxt;
+
+    TextView mResultText;
+    ProgressBar mProgressBar;
+    int mMaxLevel;
+
+    OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+    protected Button mTestButton;
+
+    String mYesString;
+    String mNoString;
+
+    // These flags determine the maximum allowed latency
+    private boolean mClaimsProAudio;
+    private boolean mClaimsOutput;
+    private boolean mClaimsInput;
+
+    // Useful info
+    private boolean mSupportsMMAP = AudioUtils.isMMapSupported();
+    private boolean mSupportsMMAPExclusive = AudioUtils.isMMapExclusiveSupported();
+
+    // Peripheral(s)
+    boolean mIsPeripheralAttached;  // CDD ProAudio section C-1-3
+    AudioDeviceInfo mOutputDevInfo;
+    AudioDeviceInfo mInputDevInfo;
+
+    protected static final int TESTPERIPHERAL_INVALID       = -1;
+    protected static final int TESTPERIPHERAL_NONE          = 0;
+    protected static final int TESTPERIPHERAL_ANALOG_JACK   = 1;
+    protected static final int TESTPERIPHERAL_USB           = 2;
+    protected static final int TESTPERIPHERAL_DEVICE        = 3; // device speaker + mic
+    protected int mTestPeripheral = TESTPERIPHERAL_NONE;
+
+    // Loopback Logic
+    NativeAnalyzerThread mNativeAnalyzerThread = null;
+
+    protected static final int NUM_TEST_PHASES = 5;
+    protected int mTestPhase = 0;
+
+    protected double[] mLatencyMillis = new double[NUM_TEST_PHASES];
+    protected double[] mConfidence = new double[NUM_TEST_PHASES];
+
+    protected double mMeanLatencyMillis;
+    protected double mMeanAbsoluteDeviation;
+    protected double mMeanConfidence;
+
+    protected static final double CONFIDENCE_THRESHOLD = 0.6;
+    // impossibly low latencies (indicating something in the test went wrong).
+    protected static final float EPSILON = 1.0f;
+    protected static final double PROAUDIO_RECOMMENDED_LATENCY_MS = 20.0;
+    protected static final double PROAUDIO_RECOMMENDED_USB_LATENCY_MS = 25.0;
+    protected static final double PROAUDIO_MUST_LATENCY_MS = 20.0;
+    protected static final double BASIC_RECOMMENDED_LATENCY_MS = 50.0;
+    protected static final double BASIC_MUST_LATENCY_MS = 800.0;
+    protected double mMustLatency;
+    protected double mRecommendedLatency;
+
+    // The audio stream callback threads should stop and close
+    // in less than a few hundred msec. This is a generous timeout value.
+    private static final int STOP_TEST_TIMEOUT_MSEC = 2 * 1000;
+
+    //
+    // Common UI Handling
+    //
+    private void connectLoopbackUI() {
+        // Connected Device
+        mInputDeviceTxt = ((TextView)findViewById(R.id.audioLoopbackInputLbl));
+        mOutputDeviceTxt = ((TextView)findViewById(R.id.audioLoopbackOutputLbl));
+
+        mAudioLevelText = (TextView)findViewById(R.id.audio_loopback_level_text);
+        mAudioLevelSeekbar = (SeekBar)findViewById(R.id.audio_loopback_level_seekbar);
+        mMaxLevel = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+        mAudioLevelSeekbar.setMax(mMaxLevel);
+        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(0.7 * mMaxLevel), 0);
+        refreshLevel();
+
+        mAudioLevelSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {}
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {}
+
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
+                        progress, 0);
+                Log.i(TAG,"Level set to: " + progress);
+                refreshLevel();
+            }
+        });
+
+        mResultText = (TextView)findViewById(R.id.audio_loopback_results_text);
+        mProgressBar = (ProgressBar)findViewById(R.id.audio_loopback_progress_bar);
+        showWait(false);
+    }
+
+    //
+    // Peripheral Connection Logic
+    //
+    protected void scanPeripheralList(AudioDeviceInfo[] devices) {
+        // CDD Section C-1-3: USB port, host-mode support
+
+        // Can't just use the first record because then we will only get
+        // Source OR sink, not both even on devices that are both.
+        mOutputDevInfo = null;
+        mInputDevInfo = null;
+
+        // Any valid peripherals
+        // Do we leave in the Headset test to support a USB-Dongle?
+        for (AudioDeviceInfo devInfo : devices) {
+            if (devInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE || // USB Peripheral
+                    devInfo.getType() == AudioDeviceInfo.TYPE_USB_HEADSET || // USB dongle+LBPlug
+                    devInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET || // Loopback Plug?
+                    devInfo.getType() == AudioDeviceInfo.TYPE_AUX_LINE) { // Aux-cable loopback?
+                if (devInfo.isSink()) {
+                    mOutputDevInfo = devInfo;
+                }
+                if (devInfo.isSource()) {
+                    mInputDevInfo = devInfo;
+                }
+            }  else {
+                handleDeviceConnection(devInfo);
+            }
+        }
+
+        // need BOTH input and output to test
+        mIsPeripheralAttached = mOutputDevInfo != null && mInputDevInfo != null;
+        calculateTestPeripheral();
+        showConnectedAudioPeripheral();
+        calculateLatencyThresholds();
+        displayLatencyThresholds();
+    }
+
+    protected void handleDeviceConnection(AudioDeviceInfo deviceInfo) {
+        // NOP
+    }
+
+    private class ConnectListener extends AudioDeviceCallback {
+        /*package*/ ConnectListener() {}
+
+        //
+        // AudioDevicesManager.OnDeviceConnectionListener
+        //
+        @Override
+        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+            scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
+        }
+
+        @Override
+        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+            scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
+        }
+    }
+
+    private void calculateTestPeripheral() {
+        if (!mIsPeripheralAttached) {
+            if ((mOutputDevInfo != null && mInputDevInfo == null)
+                || (mOutputDevInfo == null && mInputDevInfo != null)) {
+                mTestPeripheral = TESTPERIPHERAL_INVALID;
+            } else {
+                mTestPeripheral = TESTPERIPHERAL_DEVICE;
+            }
+        } else if (!areIODevicesOnePeripheral()) {
+            mTestPeripheral = TESTPERIPHERAL_INVALID;
+        } else if (mInputDevInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE ||
+                mInputDevInfo.getType() == AudioDeviceInfo.TYPE_USB_HEADSET) {
+            mTestPeripheral = TESTPERIPHERAL_USB;
+        } else if (mInputDevInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET ||
+                mInputDevInfo.getType() == AudioDeviceInfo.TYPE_AUX_LINE) {
+            mTestPeripheral = TESTPERIPHERAL_ANALOG_JACK;
+        } else {
+            // Huh?
+            Log.e(TAG, "No valid peripheral found!?");
+            mTestPeripheral = TESTPERIPHERAL_NONE;
+        }
+    }
+
+    private boolean isPeripheralValidForTest() {
+        return mTestPeripheral == TESTPERIPHERAL_ANALOG_JACK
+                    || mTestPeripheral == TESTPERIPHERAL_USB;
+    }
+
+    private void showConnectedAudioPeripheral() {
+        mInputDeviceTxt.setText(
+                mInputDevInfo != null ? mInputDevInfo.getProductName().toString()
+                        : "Not connected");
+        mOutputDeviceTxt.setText(
+                mOutputDevInfo != null ? mOutputDevInfo.getProductName().toString()
+                        : "Not connected");
+
+        String pathName;
+        switch (mTestPeripheral) {
+            case TESTPERIPHERAL_INVALID:
+                pathName = "Invalid Test Peripheral";
+                break;
+
+            case TESTPERIPHERAL_ANALOG_JACK:
+                pathName = "Headset Jack";
+                break;
+
+            case TESTPERIPHERAL_USB:
+                pathName = "USB";
+                break;
+
+            case TESTPERIPHERAL_DEVICE:
+                pathName = "Device Speaker + Microphone";
+                break;
+
+            case TESTPERIPHERAL_NONE:
+            default:
+                pathName = "Error. Unknown Test Path";
+                break;
+        }
+        mTestPathTxt.setText(pathName);
+        mTestButton.setEnabled(
+                mTestPeripheral != TESTPERIPHERAL_INVALID && mTestPeripheral != TESTPERIPHERAL_NONE);
+
+    }
+
+    private boolean areIODevicesOnePeripheral() {
+        if (mOutputDevInfo == null || mInputDevInfo == null) {
+            return false;
+        }
+
+        return mOutputDevInfo.getProductName().toString().equals(
+                mInputDevInfo.getProductName().toString());
+    }
+
+    private void calculateLatencyThresholds() {
+        switch (mTestPeripheral) {
+            case TESTPERIPHERAL_ANALOG_JACK:
+                mRecommendedLatency = mClaimsProAudio
+                        ? PROAUDIO_RECOMMENDED_LATENCY_MS : BASIC_RECOMMENDED_LATENCY_MS;
+                mMustLatency =  mClaimsProAudio
+                        ? PROAUDIO_RECOMMENDED_LATENCY_MS : BASIC_MUST_LATENCY_MS;
+                break;
+
+            case TESTPERIPHERAL_USB:
+                mRecommendedLatency = mClaimsProAudio
+                        ? PROAUDIO_RECOMMENDED_USB_LATENCY_MS : BASIC_RECOMMENDED_LATENCY_MS;
+                mMustLatency = mClaimsProAudio
+                        ? PROAUDIO_RECOMMENDED_USB_LATENCY_MS : BASIC_MUST_LATENCY_MS;
+                break;
+
+            case TESTPERIPHERAL_DEVICE:
+                // This isn't a valid case so we won't pass it, but it can be run
+                mRecommendedLatency = mClaimsProAudio
+                        ? PROAUDIO_RECOMMENDED_LATENCY_MS : BASIC_RECOMMENDED_LATENCY_MS;
+                mMustLatency = mClaimsProAudio
+                        ? PROAUDIO_RECOMMENDED_LATENCY_MS :BASIC_MUST_LATENCY_MS;
+                break;
+
+            case TESTPERIPHERAL_NONE:
+            default:
+                mRecommendedLatency = BASIC_RECOMMENDED_LATENCY_MS;
+                mMustLatency = BASIC_MUST_LATENCY_MS;
+                break;
+        }
+    }
+
+    private void displayLatencyThresholds() {
+        if (isPeripheralValidForTest()) {
+            ((TextView) findViewById(R.id.audio_loopback_must_latency)).setText("" + mMustLatency);
+            ((TextView) findViewById(R.id.audio_loopback_recommended_latency)).setText(
+                    "" + mRecommendedLatency);
+        } else {
+            String naStr = getResources().getString(R.string.audio_proaudio_NA);
+            ((TextView) findViewById(R.id.audio_loopback_must_latency)).setText(naStr);
+            ((TextView) findViewById(R.id.audio_loopback_recommended_latency)).setText(naStr);
+        }
+    }
+
+    /**
+     * refresh Audio Level seekbar and text
+     */
+    private void refreshLevel() {
+        int currentLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+        mAudioLevelSeekbar.setProgress(currentLevel);
+
+        String levelText = String.format("%s: %d/%d",
+                getResources().getString(R.string.audio_loopback_level_text),
+                currentLevel, mMaxLevel);
+        mAudioLevelText.setText(levelText);
+    }
+
+    //
+    // show active progress bar
+    //
+    protected void showWait(boolean show) {
+        mProgressBar.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+    }
+
+    //
+    // Common loging
+    //
+    // Schema
+    private static final String KEY_LATENCY = "latency";
+    private static final String KEY_CONFIDENCE = "confidence";
+    private static final String KEY_SAMPLE_RATE = "sample_rate";
+    private static final String KEY_IS_PRO_AUDIO = "is_pro_audio";
+    private static final String KEY_IS_LOW_LATENCY = "is_low_latency";
+    private static final String KEY_IS_PERIPHERAL_ATTACHED = "is_peripheral_attached";
+    private static final String KEY_INPUT_PERIPHERAL_NAME = "input_peripheral";
+    private static final String KEY_OUTPUT_PERIPHERAL_NAME = "output_peripheral";
+    private static final String KEY_TEST_PERIPHERAL = "test_peripheral";
+    private static final String KEY_TEST_MMAP = "supports_mmap";
+    private static final String KEY_TEST_MMAPEXCLUSIVE = "supports_mmap_exclusive";
+    private static final String KEY_LEVEL = "level";
+    private static final String KEY_BUFFER_SIZE = "buffer_size_in_frames";
+
+    @Override
+    public String getTestId() {
+        return setTestNameSuffix(sCurrentDisplayMode, getClass().getName());
+    }
+
+    //
+    // Subclasses should call this explicitly. SubClasses should call submit() after their logs
+    //
+    @Override
+    public void recordTestResults() {
+        if (mNativeAnalyzerThread == null) {
+            return; // no results to report
+        }
+
+        CtsVerifierReportLog reportLog = getReportLog();
+        reportLog.addValue(
+                KEY_LATENCY,
+                mMeanLatencyMillis,
+                ResultType.LOWER_BETTER,
+                ResultUnit.MS);
+
+        reportLog.addValue(
+                KEY_CONFIDENCE,
+                mMeanConfidence,
+                ResultType.HIGHER_BETTER,
+                ResultUnit.NONE);
+
+        reportLog.addValue(
+                KEY_SAMPLE_RATE,
+                mNativeAnalyzerThread.getSampleRate(),
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        reportLog.addValue(
+                KEY_IS_LOW_LATENCY,
+                mNativeAnalyzerThread.isLowLatencyStream(),
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        reportLog.addValue(
+                KEY_IS_PERIPHERAL_ATTACHED,
+                mIsPeripheralAttached,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        reportLog.addValue(
+                KEY_IS_PRO_AUDIO,
+                mClaimsProAudio,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        reportLog.addValue(
+                KEY_TEST_PERIPHERAL,
+                mTestPeripheral,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        reportLog.addValue(
+                KEY_TEST_MMAP,
+                mSupportsMMAP,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        reportLog.addValue(
+                KEY_TEST_MMAPEXCLUSIVE ,
+                mSupportsMMAPExclusive,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        if (mIsPeripheralAttached) {
+            reportLog.addValue(
+                    KEY_INPUT_PERIPHERAL_NAME,
+                    mInputDevInfo != null ? mInputDevInfo.getProductName().toString() : "None",
+                    ResultType.NEUTRAL,
+                    ResultUnit.NONE);
+
+            reportLog.addValue(
+                    KEY_OUTPUT_PERIPHERAL_NAME,
+                    mOutputDevInfo != null ? mOutputDevInfo.getProductName().toString() : "None",
+                    ResultType.NEUTRAL,
+                    ResultUnit.NONE);
+        }
+
+        int audioLevel = mAudioLevelSeekbar.getProgress();
+        reportLog.addValue(
+                KEY_LEVEL,
+                audioLevel,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        reportLog.submit();
+    }
+
+    private void startAudioTest(Handler messageHandler) {
+        getPassButton().setEnabled(false);
+
+        mTestPhase = 0;
+        java.util.Arrays.fill(mLatencyMillis, 0.0);
+        java.util.Arrays.fill(mConfidence, 0.0);
+
+        mNativeAnalyzerThread = new NativeAnalyzerThread(this);
+        if (mNativeAnalyzerThread != null) {
+            mNativeAnalyzerThread.setMessageHandler(messageHandler);
+            // This value matches AAUDIO_INPUT_PRESET_VOICE_RECOGNITION
+            mNativeAnalyzerThread.setInputPreset(MediaRecorder.AudioSource.VOICE_RECOGNITION);
+            startTestPhase();
+        } else {
+            Log.e(TAG, "Couldn't allocate native analyzer thread");
+            mResultText.setText(getResources().getString(R.string.audio_loopback_failure));
+        }
+    }
+
+    private void startTestPhase() {
+        if (mNativeAnalyzerThread != null) {
+            mNativeAnalyzerThread.startTest();
+
+            // what is this for?
+            try {
+                Thread.sleep(200);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private void handleTestCompletion() {
+        mMeanLatencyMillis = StatUtils.calculateMean(mLatencyMillis);
+        mMeanAbsoluteDeviation =
+                StatUtils.calculateMeanAbsoluteDeviation(mMeanLatencyMillis, mLatencyMillis);
+        mMeanConfidence = StatUtils.calculateMean(mConfidence);
+
+        boolean pass = isPeripheralValidForTest()
+                && mMeanConfidence >= CONFIDENCE_THRESHOLD
+                && mMeanLatencyMillis > EPSILON
+                && mMeanLatencyMillis < mMustLatency;
+
+        getPassButton().setEnabled(pass);
+
+        String result;
+        if (mMeanConfidence < CONFIDENCE_THRESHOLD) {
+            result = String.format(
+                    "Test Finished\nInsufficient Confidence (%.2f < %.2f). No Results.",
+                    mMeanConfidence, CONFIDENCE_THRESHOLD);
+        } else {
+            result = String.format(
+                    "Test Finished - %s\nMean Latency:%.2f ms (required:%.2f)\n" +
+                            "Mean Absolute Deviation: %.2f\n" +
+                            " Confidence: %.2f\n" +
+                            " Low Latency Path: %s",
+                    (pass ? "PASS" : "FAIL"),
+                    mMeanLatencyMillis,
+                    mMustLatency,
+                    mMeanAbsoluteDeviation,
+                    mMeanConfidence,
+                    mNativeAnalyzerThread.isLowLatencyStream() ? mYesString : mNoString);
+        }
+
+        // Make sure the test thread is finished. It should already be done.
+        if (mNativeAnalyzerThread != null) {
+            try {
+                mNativeAnalyzerThread.stopTest(STOP_TEST_TIMEOUT_MSEC);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        mResultText.setText(result);
+
+        recordTestResults();
+
+        showWait(false);
+        mTestButton.setEnabled(true);
+    }
+
+    private void handleTestPhaseCompletion() {
+        if (mNativeAnalyzerThread != null && mTestPhase < NUM_TEST_PHASES) {
+            mLatencyMillis[mTestPhase] = mNativeAnalyzerThread.getLatencyMillis();
+            mConfidence[mTestPhase] = mNativeAnalyzerThread.getConfidence();
+
+            String result = String.format(
+                    "Test %d Finished\nLatency: %.2f ms\nConfidence: %.2f\n",
+                    mTestPhase,
+                    mLatencyMillis[mTestPhase],
+                    mConfidence[mTestPhase]);
+
+            mResultText.setText(result);
+            try {
+                mNativeAnalyzerThread.stopTest(STOP_TEST_TIMEOUT_MSEC);
+                // Thread.sleep(/*STOP_TEST_TIMEOUT_MSEC*/500);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            mTestPhase++;
+            if (mTestPhase >= NUM_TEST_PHASES) {
+                handleTestCompletion();
+            } else {
+                startTestPhase();
+            }
+        }
+    }
+
+    /**
+     * handler for messages from audio thread
+     */
+    private Handler mMessageHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            super.handleMessage(msg);
+            switch(msg.what) {
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED:
+                    Log.v(TAG,"got message native rec started!!");
+                    showWait(true);
+                    mResultText.setText(String.format("[phase: %d] - Test Running...",
+                            (mTestPhase + 1)));
+                    break;
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_OPEN_ERROR:
+                    Log.v(TAG,"got message native rec can't start!!");
+                    mResultText.setText("Test Error opening streams.");
+                    handleTestCompletion();
+                    break;
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR:
+                    Log.v(TAG,"got message native rec can't start!!");
+                    mResultText.setText("Test Error while recording.");
+                    handleTestCompletion();
+                    break;
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS:
+                    mResultText.setText("Test FAILED due to errors.");
+                    handleTestCompletion();
+                    break;
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_ANALYZING:
+                    Log.i(TAG, "NATIVE_AUDIO_THREAD_MESSAGE_ANALYZING");
+                    mResultText.setText(String.format("[phase: %d] - Analyzing ...",
+                            mTestPhase + 1));
+                    break;
+                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE:
+                    Log.i(TAG, "NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE");
+                    handleTestPhaseCompletion();
+                    break;
+                default:
+                    break;
+            }
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.audio_loopback_latency_activity);
+
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+        setInfoResources(R.string.audio_loopback_latency_test, R.string.audio_loopback_info, -1);
+
+        mClaimsOutput = AudioSystemFlags.claimsOutput(this);
+        mClaimsInput = AudioSystemFlags.claimsInput(this);
+        mClaimsProAudio = AudioSystemFlags.claimsProAudio(this);
+
+        mYesString = getResources().getString(R.string.audio_general_yes);
+        mNoString = getResources().getString(R.string.audio_general_no);
+
+        // Pro Audio
+        ((TextView)findViewById(R.id.audio_loopback_pro_audio)).setText(
+                "" + (mClaimsProAudio ? mYesString : mNoString));
+
+        // MMAP
+        ((TextView)findViewById(R.id.audio_loopback_mmap)).setText(
+                "" + (mSupportsMMAP ? mYesString : mNoString));
+        ((TextView)findViewById(R.id.audio_loopback_mmap_exclusive)).setText(
+                "" + (mSupportsMMAPExclusive ? mYesString : mNoString));
+
+        // Low Latency
+        ((TextView)findViewById(R.id.audio_loopback_low_latency)).setText(
+                "" + (AudioSystemFlags.claimsLowLatencyAudio(this) ? mYesString : mNoString));
+
+        mTestPathTxt = ((TextView)findViewById(R.id.audio_loopback_testpath));
+
+        mTestButton = (Button)findViewById(R.id.audio_loopback_test_btn);
+        mTestButton.setOnClickListener(mBtnClickListener);
+
+        mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
+
+        mAudioManager.registerAudioDeviceCallback(new ConnectListener(), new Handler());
+
+        connectLoopbackUI();
+
+        calculateLatencyThresholds();
+        displayLatencyThresholds();
+    }
+
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.audio_loopback_test_btn:
+                    Log.i(TAG, "audio loopback test");
+                    startAudioTest(mMessageHandler);
+                    break;
+            }
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
index 8ee3446..9490091 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackLatencyActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -16,679 +16,9 @@
 
 package com.android.cts.verifier.audio;
 
-import android.app.AlertDialog;
-import android.media.AudioDeviceCallback;
-import android.media.AudioDeviceInfo;
-import android.media.AudioManager;
-import android.media.MediaRecorder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.ProgressBar;
-import android.widget.SeekBar;
-import android.widget.TextView;
-
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-import com.android.cts.verifier.audio.audiolib.AudioSystemFlags;
-import com.android.cts.verifier.audio.audiolib.StatUtils;
-import com.android.cts.verifier.audio.audiolib.AudioUtils;
-import com.android.cts.verifier.CtsVerifierReportLog;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-import static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode;
-import static com.android.cts.verifier.TestListAdapter.setTestNameSuffix;
-
 /**
- * CtsVerifier Audio Loopback Latency Test
+ * Tests Audio Device roundtrip latency by using a loopback plug.
  */
-public class AudioLoopbackLatencyActivity extends PassFailButtons.Activity {
-    private static final String TAG = "AudioLoopbackLatencyActivity";
-
-    // JNI load
-    static {
-        try {
-            System.loadLibrary("audioloopback_jni");
-        } catch (UnsatisfiedLinkError e) {
-            Log.e(TAG, "Error loading Audio Loopback JNI library");
-            Log.e(TAG, "e: " + e);
-            e.printStackTrace();
-        }
-
-        /* TODO: gracefully fail/notify if the library can't be loaded */
-    }
-    protected AudioManager mAudioManager;
-
-    // UI
-    TextView mInputDeviceTxt;
-    TextView mOutputDeviceTxt;
-
-    TextView mAudioLevelText;
-    SeekBar mAudioLevelSeekbar;
-
-    TextView mTestPathTxt;
-
-    TextView mResultText;
-    ProgressBar mProgressBar;
-    int mMaxLevel;
-
-    OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
-    protected Button mTestButton;
-
-    String mYesString;
-    String mNoString;
-
-    // These flags determine the maximum allowed latency
-    private boolean mClaimsProAudio;
-    private boolean mClaimsOutput;
-    private boolean mClaimsInput;
-
-    // Useful info
-    private boolean mSupportsMMAP = AudioUtils.isMMapSupported();
-    private boolean mSupportsMMAPExclusive = AudioUtils.isMMapExclusiveSupported();
-
-    // Peripheral(s)
-    boolean mIsPeripheralAttached;  // CDD ProAudio section C-1-3
-    AudioDeviceInfo mOutputDevInfo;
-    AudioDeviceInfo mInputDevInfo;
-
-    protected static final int TESTPERIPHERAL_INVALID       = -1;
-    protected static final int TESTPERIPHERAL_NONE          = 0;
-    protected static final int TESTPERIPHERAL_ANALOG_JACK   = 1;
-    protected static final int TESTPERIPHERAL_USB           = 2;
-    protected static final int TESTPERIPHERAL_DEVICE        = 3; // device speaker + mic
-    protected int mTestPeripheral = TESTPERIPHERAL_NONE;
-
-    // Loopback Logic
-    NativeAnalyzerThread mNativeAnalyzerThread = null;
-
-    protected static final int NUM_TEST_PHASES = 5;
-    protected int mTestPhase = 0;
-
-    protected double[] mLatencyMillis = new double[NUM_TEST_PHASES];
-    protected double[] mConfidence = new double[NUM_TEST_PHASES];
-
-    protected double mMeanLatencyMillis;
-    protected double mMeanAbsoluteDeviation;
-    protected double mMeanConfidence;
-
-    protected static final double CONFIDENCE_THRESHOLD = 0.6;
-    // impossibly low latencies (indicating something in the test went wrong).
-    protected static final float EPSILON = 1.0f;
-    protected static final double PROAUDIO_RECOMMENDED_LATENCY_MS = 20.0;
-    protected static final double PROAUDIO_RECOMMENDED_USB_LATENCY_MS = 25.0;
-    protected static final double PROAUDIO_MUST_LATENCY_MS = 20.0;
-    protected static final double BASIC_RECOMMENDED_LATENCY_MS = 50.0;
-    protected static final double BASIC_MUST_LATENCY_MS = 800.0;
-    protected double mMustLatency;
-    protected double mRecommendedLatency;
-
-    // The audio stream callback threads should stop and close
-    // in less than a few hundred msec. This is a generous timeout value.
-    private static final int STOP_TEST_TIMEOUT_MSEC = 2 * 1000;
-
-    //
-    // Common UI Handling
-    //
-    private void connectLoopbackUI() {
-        // Connected Device
-        mInputDeviceTxt = ((TextView)findViewById(R.id.audioLoopbackInputLbl));
-        mOutputDeviceTxt = ((TextView)findViewById(R.id.audioLoopbackOutputLbl));
-
-        mAudioLevelText = (TextView)findViewById(R.id.audio_loopback_level_text);
-        mAudioLevelSeekbar = (SeekBar)findViewById(R.id.audio_loopback_level_seekbar);
-        mMaxLevel = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
-        mAudioLevelSeekbar.setMax(mMaxLevel);
-        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(0.7 * mMaxLevel), 0);
-        refreshLevel();
-
-        mAudioLevelSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
-            @Override
-            public void onStopTrackingTouch(SeekBar seekBar) {}
-
-            @Override
-            public void onStartTrackingTouch(SeekBar seekBar) {}
-
-            @Override
-            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-                mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
-                        progress, 0);
-                Log.i(TAG,"Level set to: " + progress);
-                refreshLevel();
-            }
-        });
-
-        mResultText = (TextView)findViewById(R.id.audio_loopback_results_text);
-        mProgressBar = (ProgressBar)findViewById(R.id.audio_loopback_progress_bar);
-        showWait(false);
-    }
-
-    //
-    // Peripheral Connection Logic
-    //
-    protected void scanPeripheralList(AudioDeviceInfo[] devices) {
-        // CDD Section C-1-3: USB port, host-mode support
-
-        // Can't just use the first record because then we will only get
-        // Source OR sink, not both even on devices that are both.
-        mOutputDevInfo = null;
-        mInputDevInfo = null;
-
-        // Any valid peripherals
-        // Do we leave in the Headset test to support a USB-Dongle?
-        for (AudioDeviceInfo devInfo : devices) {
-            if (devInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE || // USB Peripheral
-                    devInfo.getType() == AudioDeviceInfo.TYPE_USB_HEADSET || // USB dongle+LBPlug
-                    devInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET || // Loopback Plug?
-                    devInfo.getType() == AudioDeviceInfo.TYPE_AUX_LINE) { // Aux-cable loopback?
-                if (devInfo.isSink()) {
-                    mOutputDevInfo = devInfo;
-                }
-                if (devInfo.isSource()) {
-                    mInputDevInfo = devInfo;
-                }
-            }  else {
-                handleDeviceConnection(devInfo);
-            }
-        }
-
-        // need BOTH input and output to test
-        mIsPeripheralAttached = mOutputDevInfo != null && mInputDevInfo != null;
-        calculateTestPeripheral();
-        showConnectedAudioPeripheral();
-        calculateLatencyThresholds();
-        displayLatencyThresholds();
-    }
-
-    protected void handleDeviceConnection(AudioDeviceInfo deviceInfo) {
-        // NOP
-    }
-
-    private class ConnectListener extends AudioDeviceCallback {
-        /*package*/ ConnectListener() {}
-
-        //
-        // AudioDevicesManager.OnDeviceConnectionListener
-        //
-        @Override
-        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
-            scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
-        }
-
-        @Override
-        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
-            scanPeripheralList(mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL));
-        }
-    }
-
-    private void calculateTestPeripheral() {
-        if (!mIsPeripheralAttached) {
-            if ((mOutputDevInfo != null && mInputDevInfo == null)
-                || (mOutputDevInfo == null && mInputDevInfo != null)) {
-                mTestPeripheral = TESTPERIPHERAL_INVALID;
-            } else {
-                mTestPeripheral = TESTPERIPHERAL_DEVICE;
-            }
-        } else if (!areIODevicesOnePeripheral()) {
-            mTestPeripheral = TESTPERIPHERAL_INVALID;
-        } else if (mInputDevInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE ||
-                mInputDevInfo.getType() == AudioDeviceInfo.TYPE_USB_HEADSET) {
-            mTestPeripheral = TESTPERIPHERAL_USB;
-        } else if (mInputDevInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET ||
-                mInputDevInfo.getType() == AudioDeviceInfo.TYPE_AUX_LINE) {
-            mTestPeripheral = TESTPERIPHERAL_ANALOG_JACK;
-        } else {
-            // Huh?
-            Log.e(TAG, "No valid peripheral found!?");
-            mTestPeripheral = TESTPERIPHERAL_NONE;
-        }
-    }
-
-    private boolean isPeripheralValidForTest() {
-        return mTestPeripheral == TESTPERIPHERAL_ANALOG_JACK
-                    || mTestPeripheral == TESTPERIPHERAL_USB;
-    }
-
-    private void showConnectedAudioPeripheral() {
-        mInputDeviceTxt.setText(
-                mInputDevInfo != null ? mInputDevInfo.getProductName().toString()
-                        : "Not connected");
-        mOutputDeviceTxt.setText(
-                mOutputDevInfo != null ? mOutputDevInfo.getProductName().toString()
-                        : "Not connected");
-
-        String pathName;
-        switch (mTestPeripheral) {
-            case TESTPERIPHERAL_INVALID:
-                pathName = "Invalid Test Peripheral";
-                break;
-
-            case TESTPERIPHERAL_ANALOG_JACK:
-                pathName = "Headset Jack";
-                break;
-
-            case TESTPERIPHERAL_USB:
-                pathName = "USB";
-                break;
-
-            case TESTPERIPHERAL_DEVICE:
-                pathName = "Device Speaker + Microphone";
-                break;
-
-            case TESTPERIPHERAL_NONE:
-            default:
-                pathName = "Error. Unknown Test Path";
-                break;
-        }
-        mTestPathTxt.setText(pathName);
-        mTestButton.setEnabled(
-                mTestPeripheral != TESTPERIPHERAL_INVALID && mTestPeripheral != TESTPERIPHERAL_NONE);
-
-    }
-
-    private boolean areIODevicesOnePeripheral() {
-        if (mOutputDevInfo == null || mInputDevInfo == null) {
-            return false;
-        }
-
-        return mOutputDevInfo.getProductName().toString().equals(
-                mInputDevInfo.getProductName().toString());
-    }
-
-    private void calculateLatencyThresholds() {
-        switch (mTestPeripheral) {
-            case TESTPERIPHERAL_ANALOG_JACK:
-                mRecommendedLatency = mClaimsProAudio
-                        ? PROAUDIO_RECOMMENDED_LATENCY_MS : BASIC_RECOMMENDED_LATENCY_MS;
-                mMustLatency =  mClaimsProAudio
-                        ? PROAUDIO_RECOMMENDED_LATENCY_MS : BASIC_MUST_LATENCY_MS;
-                break;
-
-            case TESTPERIPHERAL_USB:
-                mRecommendedLatency = mClaimsProAudio
-                        ? PROAUDIO_RECOMMENDED_USB_LATENCY_MS : BASIC_RECOMMENDED_LATENCY_MS;
-                mMustLatency = mClaimsProAudio
-                        ? PROAUDIO_RECOMMENDED_USB_LATENCY_MS : BASIC_MUST_LATENCY_MS;
-                break;
-
-            case TESTPERIPHERAL_DEVICE:
-                // This isn't a valid case so we won't pass it, but it can be run
-                mRecommendedLatency = mClaimsProAudio
-                        ? PROAUDIO_RECOMMENDED_LATENCY_MS : BASIC_RECOMMENDED_LATENCY_MS;
-                mMustLatency = mClaimsProAudio
-                        ? PROAUDIO_RECOMMENDED_LATENCY_MS :BASIC_MUST_LATENCY_MS;
-                break;
-
-            case TESTPERIPHERAL_NONE:
-            default:
-                mRecommendedLatency = BASIC_RECOMMENDED_LATENCY_MS;
-                mMustLatency = BASIC_MUST_LATENCY_MS;
-                break;
-        }
-    }
-
-    private void displayLatencyThresholds() {
-        if (isPeripheralValidForTest()) {
-            ((TextView) findViewById(R.id.audio_loopback_must_latency)).setText("" + mMustLatency);
-            ((TextView) findViewById(R.id.audio_loopback_recommended_latency)).setText(
-                    "" + mRecommendedLatency);
-        } else {
-            String naStr = getResources().getString(R.string.audio_proaudio_NA);
-            ((TextView) findViewById(R.id.audio_loopback_must_latency)).setText(naStr);
-            ((TextView) findViewById(R.id.audio_loopback_recommended_latency)).setText(naStr);
-        }
-    }
-
-    /**
-     * refresh Audio Level seekbar and text
-     */
-    private void refreshLevel() {
-        int currentLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
-        mAudioLevelSeekbar.setProgress(currentLevel);
-
-        String levelText = String.format("%s: %d/%d",
-                getResources().getString(R.string.audio_loopback_level_text),
-                currentLevel, mMaxLevel);
-        mAudioLevelText.setText(levelText);
-    }
-
-    //
-    // show active progress bar
-    //
-    protected void showWait(boolean show) {
-        mProgressBar.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
-    }
-
-    //
-    // Common logging
-    //
-    // Schema
-    private static final String KEY_LATENCY = "latency";
-    private static final String KEY_CONFIDENCE = "confidence";
-    private static final String KEY_SAMPLE_RATE = "sample_rate";
-    private static final String KEY_IS_PRO_AUDIO = "is_pro_audio";
-    private static final String KEY_IS_LOW_LATENCY = "is_low_latency";
-    private static final String KEY_IS_PERIPHERAL_ATTACHED = "is_peripheral_attached";
-    private static final String KEY_INPUT_PERIPHERAL_NAME = "input_peripheral";
-    private static final String KEY_OUTPUT_PERIPHERAL_NAME = "output_peripheral";
-    private static final String KEY_TEST_PERIPHERAL = "test_peripheral";
-    private static final String KEY_TEST_MMAP = "supports_mmap";
-    private static final String KEY_TEST_MMAPEXCLUSIVE = "supports_mmap_exclusive";
-    private static final String KEY_LEVEL = "level";
-    private static final String KEY_BUFFER_SIZE = "buffer_size_in_frames";
-
-    @Override
-    public String getTestId() {
-        return setTestNameSuffix(sCurrentDisplayMode, getClass().getName());
-    }
-
-    @Override
-    public String getReportFileName() { return PassFailButtons.AUDIO_TESTS_REPORT_LOG_NAME; }
-
-    @Override
-    public final String getReportSectionName() {
-        return setTestNameSuffix(sCurrentDisplayMode, "audio_loopback_latency_activity");
-    }
-
-    //
-    // Subclasses should call this explicitly. SubClasses should call submit() after their logs
-    //
-    @Override
-    public void recordTestResults() {
-        if (mNativeAnalyzerThread == null) {
-            return; // no results to report
-        }
-
-        CtsVerifierReportLog reportLog = getReportLog();
-        reportLog.addValue(
-                KEY_LATENCY,
-                mMeanLatencyMillis,
-                ResultType.LOWER_BETTER,
-                ResultUnit.MS);
-
-        reportLog.addValue(
-                KEY_CONFIDENCE,
-                mMeanConfidence,
-                ResultType.HIGHER_BETTER,
-                ResultUnit.NONE);
-
-        reportLog.addValue(
-                KEY_SAMPLE_RATE,
-                mNativeAnalyzerThread.getSampleRate(),
-                ResultType.NEUTRAL,
-                ResultUnit.NONE);
-
-        reportLog.addValue(
-                KEY_IS_LOW_LATENCY,
-                mNativeAnalyzerThread.isLowLatencyStream(),
-                ResultType.NEUTRAL,
-                ResultUnit.NONE);
-
-        reportLog.addValue(
-                KEY_IS_PERIPHERAL_ATTACHED,
-                mIsPeripheralAttached,
-                ResultType.NEUTRAL,
-                ResultUnit.NONE);
-
-        reportLog.addValue(
-                KEY_IS_PRO_AUDIO,
-                mClaimsProAudio,
-                ResultType.NEUTRAL,
-                ResultUnit.NONE);
-
-        reportLog.addValue(
-                KEY_TEST_PERIPHERAL,
-                mTestPeripheral,
-                ResultType.NEUTRAL,
-                ResultUnit.NONE);
-
-        reportLog.addValue(
-                KEY_TEST_MMAP,
-                mSupportsMMAP,
-                ResultType.NEUTRAL,
-                ResultUnit.NONE);
-
-        reportLog.addValue(
-                KEY_TEST_MMAPEXCLUSIVE ,
-                mSupportsMMAPExclusive,
-                ResultType.NEUTRAL,
-                ResultUnit.NONE);
-
-        if (mIsPeripheralAttached) {
-            reportLog.addValue(
-                    KEY_INPUT_PERIPHERAL_NAME,
-                    mInputDevInfo != null ? mInputDevInfo.getProductName().toString() : "None",
-                    ResultType.NEUTRAL,
-                    ResultUnit.NONE);
-
-            reportLog.addValue(
-                    KEY_OUTPUT_PERIPHERAL_NAME,
-                    mOutputDevInfo != null ? mOutputDevInfo.getProductName().toString() : "None",
-                    ResultType.NEUTRAL,
-                    ResultUnit.NONE);
-        }
-
-        int audioLevel = mAudioLevelSeekbar.getProgress();
-        reportLog.addValue(
-                KEY_LEVEL,
-                audioLevel,
-                ResultType.NEUTRAL,
-                ResultUnit.NONE);
-
-        reportLog.submit();
-    }
-
-    private void startAudioTest(Handler messageHandler) {
-        getPassButton().setEnabled(false);
-
-        mTestPhase = 0;
-        java.util.Arrays.fill(mLatencyMillis, 0.0);
-        java.util.Arrays.fill(mConfidence, 0.0);
-
-        mNativeAnalyzerThread = new NativeAnalyzerThread(this);
-        if (mNativeAnalyzerThread != null) {
-            mNativeAnalyzerThread.setMessageHandler(messageHandler);
-            // This value matches AAUDIO_INPUT_PRESET_VOICE_RECOGNITION
-            mNativeAnalyzerThread.setInputPreset(MediaRecorder.AudioSource.VOICE_RECOGNITION);
-            startTestPhase();
-        } else {
-            Log.e(TAG, "Couldn't allocate native analyzer thread");
-            mResultText.setText(getResources().getString(R.string.audio_loopback_failure));
-        }
-    }
-
-    private void startTestPhase() {
-        if (mNativeAnalyzerThread != null) {
-            mNativeAnalyzerThread.startTest();
-
-            // what is this for?
-            try {
-                Thread.sleep(200);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    private void handleTestCompletion() {
-        mMeanLatencyMillis = StatUtils.calculateMean(mLatencyMillis);
-        mMeanAbsoluteDeviation =
-                StatUtils.calculateMeanAbsoluteDeviation(mMeanLatencyMillis, mLatencyMillis);
-        mMeanConfidence = StatUtils.calculateMean(mConfidence);
-
-        boolean pass = isPeripheralValidForTest()
-                && mMeanConfidence >= CONFIDENCE_THRESHOLD
-                && mMeanLatencyMillis > EPSILON
-                && mMeanLatencyMillis < mMustLatency;
-
-        getPassButton().setEnabled(pass);
-
-        String result;
-        if (mMeanConfidence < CONFIDENCE_THRESHOLD) {
-            result = String.format(
-                    "Test Finished\nInsufficient Confidence (%.2f < %.2f). No Results.",
-                    mMeanConfidence, CONFIDENCE_THRESHOLD);
-        } else {
-            result = String.format(
-                    "Test Finished - %s\nMean Latency:%.2f ms (required:%.2f)\n" +
-                            "Mean Absolute Deviation: %.2f\n" +
-                            " Confidence: %.2f\n" +
-                            " Low Latency Path: %s",
-                    (pass ? "PASS" : "FAIL"),
-                    mMeanLatencyMillis,
-                    mMustLatency,
-                    mMeanAbsoluteDeviation,
-                    mMeanConfidence,
-                    mNativeAnalyzerThread.isLowLatencyStream() ? mYesString : mNoString);
-        }
-
-        // Make sure the test thread is finished. It should already be done.
-        if (mNativeAnalyzerThread != null) {
-            try {
-                mNativeAnalyzerThread.stopTest(STOP_TEST_TIMEOUT_MSEC);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-        mResultText.setText(result);
-
-        recordTestResults();
-
-        showWait(false);
-        mTestButton.setEnabled(true);
-    }
-
-    private void handleTestPhaseCompletion() {
-        if (mNativeAnalyzerThread != null && mTestPhase < NUM_TEST_PHASES) {
-            mLatencyMillis[mTestPhase] = mNativeAnalyzerThread.getLatencyMillis();
-            mConfidence[mTestPhase] = mNativeAnalyzerThread.getConfidence();
-
-            String result = String.format(
-                    "Test %d Finished\nLatency: %.2f ms\nConfidence: %.2f\n",
-                    mTestPhase,
-                    mLatencyMillis[mTestPhase],
-                    mConfidence[mTestPhase]);
-
-            mResultText.setText(result);
-            try {
-                mNativeAnalyzerThread.stopTest(STOP_TEST_TIMEOUT_MSEC);
-                // Thread.sleep(/*STOP_TEST_TIMEOUT_MSEC*/500);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-
-            mTestPhase++;
-            if (mTestPhase >= NUM_TEST_PHASES) {
-                handleTestCompletion();
-            } else {
-                startTestPhase();
-            }
-        }
-    }
-
-    /**
-     * handler for messages from audio thread
-     */
-    private Handler mMessageHandler = new Handler() {
-        public void handleMessage(Message msg) {
-            super.handleMessage(msg);
-            switch(msg.what) {
-                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED:
-                    Log.v(TAG,"got message native rec started!!");
-                    showWait(true);
-                    mResultText.setText(String.format("[phase: %d] - Test Running...",
-                            (mTestPhase + 1)));
-                    break;
-                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_OPEN_ERROR:
-                    Log.v(TAG,"got message native rec can't start!!");
-                    mResultText.setText("Test Error opening streams.");
-                    handleTestCompletion();
-                    break;
-                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR:
-                    Log.v(TAG,"got message native rec can't start!!");
-                    mResultText.setText("Test Error while recording.");
-                    handleTestCompletion();
-                    break;
-                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS:
-                    mResultText.setText("Test FAILED due to errors.");
-                    handleTestCompletion();
-                    break;
-                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_ANALYZING:
-                    Log.i(TAG, "NATIVE_AUDIO_THREAD_MESSAGE_ANALYZING");
-                    mResultText.setText(String.format("[phase: %d] - Analyzing ...",
-                            mTestPhase + 1));
-                    break;
-                case NativeAnalyzerThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE:
-                    Log.i(TAG, "NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE");
-                    handleTestPhaseCompletion();
-                    break;
-                default:
-                    break;
-            }
-        }
-    };
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        setContentView(R.layout.audio_loopback_latency_activity);
-
-        setPassFailButtonClickListeners();
-        getPassButton().setEnabled(false);
-        setInfoResources(R.string.audio_loopback_latency_test, R.string.audio_loopback_info, -1);
-
-        mClaimsOutput = AudioSystemFlags.claimsOutput(this);
-        mClaimsInput = AudioSystemFlags.claimsInput(this);
-        mClaimsProAudio = AudioSystemFlags.claimsProAudio(this);
-
-        mYesString = getResources().getString(R.string.audio_general_yes);
-        mNoString = getResources().getString(R.string.audio_general_no);
-
-        // Pro Audio
-        ((TextView)findViewById(R.id.audio_loopback_pro_audio)).setText(
-                "" + (mClaimsProAudio ? mYesString : mNoString));
-
-        // MMAP
-        ((TextView)findViewById(R.id.audio_loopback_mmap)).setText(
-                "" + (mSupportsMMAP ? mYesString : mNoString));
-        ((TextView)findViewById(R.id.audio_loopback_mmap_exclusive)).setText(
-                "" + (mSupportsMMAPExclusive ? mYesString : mNoString));
-
-        // Low Latency
-        ((TextView)findViewById(R.id.audio_loopback_low_latency)).setText(
-                "" + (AudioSystemFlags.claimsLowLatencyAudio(this) ? mYesString : mNoString));
-
-        mTestPathTxt = ((TextView)findViewById(R.id.audio_loopback_testpath));
-
-        mTestButton = (Button)findViewById(R.id.audio_loopback_test_btn);
-        mTestButton.setOnClickListener(mBtnClickListener);
-
-        mAudioManager = getSystemService(AudioManager.class);
-
-        mAudioManager.registerAudioDeviceCallback(new ConnectListener(), new Handler());
-
-        connectLoopbackUI();
-
-        calculateLatencyThresholds();
-        displayLatencyThresholds();
-    }
-
-    private class OnBtnClickListener implements OnClickListener {
-        @Override
-        public void onClick(View v) {
-            switch (v.getId()) {
-                case R.id.audio_loopback_test_btn:
-                    Log.i(TAG, "audio loopback test");
-                    startAudioTest(mMessageHandler);
-                    break;
-            }
-        }
-    }
+public class AudioLoopbackLatencyActivity extends AudioLoopbackBaseActivity {
+    private static final String TAG = AudioLoopbackLatencyActivity.class.getSimpleName();
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
index 9804cd3..d32749f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/ProAudioActivity.java
@@ -67,7 +67,6 @@
     private static final String INFO_DIALOG_MESSAGE_ID = "infoDialogMessageId";
 
     // ReportLog Schema
-    private static final String SECTION_PRO_AUDIO_ACTIVITY = "pro_audio_activity";
     private static final String KEY_CLAIMS_PRO = "claims_pro_audio";
     private static final String KEY_CLAIMS_LOW_LATENCY = "claims_low_latency_audio";
     private static final String KEY_CLAIMS_MIDI = "claims_midi";
@@ -233,14 +232,6 @@
     // PassFailButtons Overrides
     //
     @Override
-    public String getReportFileName() { return PassFailButtons.AUDIO_TESTS_REPORT_LOG_NAME; }
-
-    @Override
-    public final String getReportSectionName() {
-        return setTestNameSuffix(sCurrentDisplayMode, SECTION_PRO_AUDIO_ACTIVITY);
-    }
-
-    @Override
     public void recordTestResults() {
 
         CtsVerifierReportLog reportLog = getReportLog();
