aboutsummaryrefslogtreecommitdiff
path: root/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestDataPathsActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestDataPathsActivity.java')
-rw-r--r--apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestDataPathsActivity.java901
1 files changed, 583 insertions, 318 deletions
diff --git a/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestDataPathsActivity.java b/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestDataPathsActivity.java
index b0aea932..74879f14 100644
--- a/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestDataPathsActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestDataPathsActivity.java
@@ -17,49 +17,74 @@
package com.mobileer.oboetester;
import static com.mobileer.oboetester.IntentBasedTestSupport.configureStreamsFromBundle;
+import static com.mobileer.oboetester.StreamConfiguration.convertChannelMaskToText;
-import android.app.Activity;
-import android.content.Context;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
+import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.CheckBox;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
import com.mobileer.audio_device.AudioDeviceInfoConverter;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Locale;
/**
- * Play a recognizable tone on each channel of each speaker device
- * and listen for the result through a microphone.
- * Also test each microphone channel and device.
- * Try each InputPreset.
+ * Play a recognizable tone on each channel of an output device
+ * and listen for the result through an input.
+ * Test various channels, InputPresets, ChannelMasks and SampleRates.
+ *
+ * Select device types based on priority of attached peripherals.
+ * Print devices types being tested.
*
* The analysis is based on a cosine transform of a single
* frequency. The magnitude indicates the level.
* The variations in phase, "jitter" indicate how noisy the
- * signal is or whether it is corrupted. A noisy room may have
- * energy at the target frequency but the phase will be random.
+ * signal is or whether it is corrupted. A very noisy room may have
+ * lots of energy at the target frequency but the phase will be random.
*
- * This test requires a quiet room but no other hardware.
+ * This test requires a quiet room if you are testing speaker/mic pairs.
+ * It can also be used to test using analog loopback adapters
+ * or USB devices configured in loopback mode.
*/
public class TestDataPathsActivity extends BaseAutoGlitchActivity {
public static final String KEY_USE_INPUT_PRESETS = "use_input_presets";
public static final boolean VALUE_DEFAULT_USE_INPUT_PRESETS = true;
- public static final String KEY_USE_INPUT_DEVICES = "use_input_devices";
- public static final boolean VALUE_DEFAULT_USE_INPUT_DEVICES = true;
+ public static final String KEY_USE_ALL_SAMPLE_RATES = "use_all_sample_rates";
+ public static final boolean VALUE_DEFAULT_USE_ALL_SAMPLE_RATES = false;
+
+ public static final String KEY_SINGLE_TEST_INDEX = "single_test_index";
+ public static final int VALUE_DEFAULT_SINGLE_TEST_INDEX = -1;
+ public static final String KEY_USE_ALL_CHANNEL_COUNTS = "use_all_channel_counts";
+ public static final boolean VALUE_DEFAULT_USE_ALL_CHANNEL_COUNTS = true;
+ public static final String KEY_USE_INPUT_CHANNEL_MASKS = "use_input_channel_masks";
+ public static final boolean VALUE_DEFAULT_USE_INPUT_CHANNEL_MASKS = false;
+ public static final String KEY_OUTPUT_CHANNEL_MASKS_LEVEL = "output_channel_masks_level";
+
+ // The following KEYs are for old deprecated commands.
+ public static final String KEY_USE_ALL_OUTPUT_CHANNEL_MASKS = "use_all_output_channel_masks";
+ public static final boolean VALUE_DEFAULT_USE_ALL_OUTPUT_CHANNEL_MASKS = false;
+
+ // How many tests should be run in a specific category, eg. channel masks?
+ private static final int COVERAGE_LEVEL_NONE = 0;
+ private static final int COVERAGE_LEVEL_SOME = 1;
+ private static final int COVERAGE_LEVEL_ALL = 2;
+ public static final String KEY_USE_INPUT_DEVICES = "use_input_devices";
+ public static final boolean VALUE_DEFAULT_USE_INPUT_DEVICES = false;
public static final String KEY_USE_OUTPUT_DEVICES = "use_output_devices";
public static final boolean VALUE_DEFAULT_USE_OUTPUT_DEVICES = true;
- public static final String KEY_SINGLE_TEST_INDEX = "single_test_index";
- public static final int VALUE_DEFAULT_SINGLE_TEST_INDEX = -1;
public static final int DURATION_SECONDS = 3;
private final static double MIN_REQUIRED_MAGNITUDE = 0.001;
@@ -70,6 +95,42 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
private final static double MAX_ALLOWED_JITTER = 2.0 * PHASE_PER_BIN;
private final static String MAGNITUDE_FORMAT = "%7.5f";
+ // These define the values returned by the Java API deviceInfo.getChannelMasks().
+ public static final int JAVA_CHANNEL_IN_LEFT = 1 << 2; // AudioFormat.CHANNEL_IN_LEFT
+ public static final int JAVA_CHANNEL_IN_RIGHT = 1 << 3; // AudioFormat.CHANNEL_IN_RIGHT
+ public static final int JAVA_CHANNEL_IN_FRONT = 1 << 4; // AudioFormat.CHANNEL_IN_FRONT
+ public static final int JAVA_CHANNEL_IN_BACK = 1 << 5; // AudioFormat.CHANNEL_IN_BACK
+
+ // These do not have corresponding Java definitions.
+ // They match definitions in system/media/audio/include/system/audio-hal-enums.h
+ public static final int JAVA_CHANNEL_IN_BACK_LEFT = 1 << 16;
+ public static final int JAVA_CHANNEL_IN_BACK_RIGHT = 1 << 17;
+ public static final int JAVA_CHANNEL_IN_CENTER = 1 << 18;
+ public static final int JAVA_CHANNEL_IN_LOW_FREQUENCY = 1 << 20;
+ public static final int JAVA_CHANNEL_IN_TOP_LEFT = 1 << 21;
+ public static final int JAVA_CHANNEL_IN_TOP_RIGHT = 1 << 22;
+
+ public static final int JAVA_CHANNEL_IN_MONO = JAVA_CHANNEL_IN_FRONT;
+ public static final int JAVA_CHANNEL_IN_STEREO = JAVA_CHANNEL_IN_LEFT | JAVA_CHANNEL_IN_RIGHT;
+ public static final int JAVA_CHANNEL_IN_FRONT_BACK = JAVA_CHANNEL_IN_FRONT | JAVA_CHANNEL_IN_BACK;
+ public static final int JAVA_CHANNEL_IN_2POINT0POINT2 = JAVA_CHANNEL_IN_LEFT |
+ JAVA_CHANNEL_IN_RIGHT |
+ JAVA_CHANNEL_IN_TOP_LEFT |
+ JAVA_CHANNEL_IN_TOP_RIGHT;
+ public static final int JAVA_CHANNEL_IN_2POINT1POINT2 =
+ JAVA_CHANNEL_IN_2POINT0POINT2 | JAVA_CHANNEL_IN_LOW_FREQUENCY;
+ public static final int JAVA_CHANNEL_IN_3POINT0POINT2 =
+ JAVA_CHANNEL_IN_2POINT0POINT2 | JAVA_CHANNEL_IN_CENTER;
+ public static final int JAVA_CHANNEL_IN_3POINT1POINT2 =
+ JAVA_CHANNEL_IN_3POINT0POINT2 | JAVA_CHANNEL_IN_LOW_FREQUENCY;
+ public static final int JAVA_CHANNEL_IN_5POINT1 = JAVA_CHANNEL_IN_LEFT |
+ JAVA_CHANNEL_IN_CENTER |
+ JAVA_CHANNEL_IN_RIGHT |
+ JAVA_CHANNEL_IN_BACK_LEFT |
+ JAVA_CHANNEL_IN_BACK_RIGHT |
+ JAVA_CHANNEL_IN_LOW_FREQUENCY;
+ public static final int JAVA_CHANNEL_UNDEFINED = -1;
+
final int TYPE_BUILTIN_SPEAKER_SAFE = 0x18; // API 30
private double mMagnitude;
@@ -79,22 +140,73 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
private double mPhaseErrorSum;
private double mPhaseErrorCount;
- AudioManager mAudioManager;
private CheckBox mCheckBoxInputPresets;
- private CheckBox mCheckBoxInputDevices;
- private CheckBox mCheckBoxOutputDevices;
+ private CheckBox mCheckBoxAllChannels;
+ private CheckBox mCheckBoxInputChannelMasks;
+ private RadioGroup mRadioGroupOutputChannelMasks;
+ private RadioButton mRadioOutputChannelMasksNone;
+ private RadioButton mRadioOutputChannelMasksSome;
+ private RadioButton mRadioOutputChannelMasksAll;
+ private CheckBox mCheckBoxAllSampleRates;
+ private TextView mInstructionsTextView;
private static final int[] INPUT_PRESETS = {
- // VOICE_RECOGNITION gets tested in testInputs()
- // StreamConfiguration.INPUT_PRESET_VOICE_RECOGNITION,
StreamConfiguration.INPUT_PRESET_GENERIC,
StreamConfiguration.INPUT_PRESET_CAMCORDER,
- // TODO Resolve issue with echo cancellation killing the signal.
- StreamConfiguration.INPUT_PRESET_VOICE_COMMUNICATION,
StreamConfiguration.INPUT_PRESET_UNPROCESSED,
+ // Do not use INPUT_PRESET_VOICE_COMMUNICATION because AEC kills the signal.
+ StreamConfiguration.INPUT_PRESET_VOICE_RECOGNITION,
StreamConfiguration.INPUT_PRESET_VOICE_PERFORMANCE,
};
+ private static final int[] SHORT_OUTPUT_CHANNEL_MASKS = {
+ StreamConfiguration.CHANNEL_MONO,
+ StreamConfiguration.CHANNEL_STEREO,
+ StreamConfiguration.CHANNEL_2POINT1, // Smallest mask with more than two channels.
+ StreamConfiguration.CHANNEL_5POINT1, // This mask is very common.
+ StreamConfiguration.CHANNEL_7POINT1POINT4, // More than 8 channels might break.
+ };
+
+ private static final int[] ALL_OUTPUT_CHANNEL_MASKS = {
+ StreamConfiguration.CHANNEL_MONO,
+ StreamConfiguration.CHANNEL_STEREO,
+ StreamConfiguration.CHANNEL_2POINT1,
+ StreamConfiguration.CHANNEL_TRI,
+ StreamConfiguration.CHANNEL_TRI_BACK,
+ StreamConfiguration.CHANNEL_3POINT1,
+ StreamConfiguration.CHANNEL_2POINT0POINT2,
+ StreamConfiguration.CHANNEL_2POINT1POINT2,
+ StreamConfiguration.CHANNEL_3POINT0POINT2,
+ StreamConfiguration.CHANNEL_3POINT1POINT2,
+ StreamConfiguration.CHANNEL_QUAD,
+ StreamConfiguration.CHANNEL_QUAD_SIDE,
+ StreamConfiguration.CHANNEL_SURROUND,
+ StreamConfiguration.CHANNEL_PENTA,
+ StreamConfiguration.CHANNEL_5POINT1,
+ StreamConfiguration.CHANNEL_5POINT1_SIDE,
+ StreamConfiguration.CHANNEL_6POINT1,
+ StreamConfiguration.CHANNEL_7POINT1,
+ StreamConfiguration.CHANNEL_5POINT1POINT2,
+ StreamConfiguration.CHANNEL_5POINT1POINT4,
+ StreamConfiguration.CHANNEL_7POINT1POINT2,
+ StreamConfiguration.CHANNEL_7POINT1POINT4,
+ };
+
+ private static final int[] SAMPLE_RATES = {
+ 8000,
+ 11025,
+ 12000,
+ 16000,
+ 22050,
+ 24000,
+ 32000,
+ 44100,
+ 48000,
+ 64000,
+ 88200,
+ 96000,
+ };
+
@NonNull
public static String comparePassedField(String prefix, Object failed, Object passed, String name) {
try {
@@ -109,16 +221,25 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
return "ERROR - cannot access " + name;
}
}
+ public static String comparePassedInputPreset(String prefix, TestResult failed, TestResult passed) {
+ int failedValue = failed.inputPreset;
+ int passedValue = passed.inputPreset;
+ return (failedValue == passedValue) ? ""
+ : (prefix + " inPreset: passed = "
+ + StreamConfiguration.convertInputPresetToText(passedValue)
+ + ", failed = "
+ + StreamConfiguration.convertInputPresetToText(failedValue)
+ + "\n");
+ }
public static double calculatePhaseError(double p1, double p2) {
- double diff = Math.abs(p1 - p2);
+ double diff = p1 - p2;
// Wrap around the circle.
- while (diff > (2 * Math.PI)) {
- diff -= (2 * Math.PI);
+ while (diff > Math.PI) {
+ diff -= 2 * Math.PI;
}
- // A phase error close to 2*PI is actually a small phase error.
- if (diff > Math.PI) {
- diff = (2 * Math.PI) - diff;
+ while (diff < -Math.PI) {
+ diff += 2 * Math.PI;
}
return diff;
}
@@ -126,10 +247,6 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
// Periodically query for magnitude and phase from the native detector.
protected class DataPathSniffer extends NativeSniffer {
- public DataPathSniffer(Activity activity) {
- super(activity);
- }
-
@Override
public void startSniffer() {
mMagnitude = -1.0;
@@ -141,30 +258,28 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
super.startSniffer();
}
- @Override
- public void run() {
+ private void gatherData() {
mMagnitude = getMagnitude();
mMaxMagnitude = getMaxMagnitude();
- Log.d(TAG, String.format("magnitude = %7.4f, maxMagnitude = %7.4f",
+ Log.d(TAG, String.format(Locale.getDefault(), "magnitude = %7.4f, maxMagnitude = %7.4f",
mMagnitude, mMaxMagnitude));
// Only look at the phase if we have a signal.
if (mMagnitude >= MIN_REQUIRED_MAGNITUDE) {
- double phase = getPhase();
+ double phase = getPhaseDataPaths();
// Wait for the analyzer to get a lock on the signal.
// Arbitrary number of phase measurements before we start measuring jitter.
final int kMinPhaseMeasurementsRequired = 4;
if (mPhaseCount >= kMinPhaseMeasurementsRequired) {
- double phaseError = calculatePhaseError(phase, mPhase);
- // low pass filter
+ double phaseError = Math.abs(calculatePhaseError(phase, mPhase));
+ // collect average error
mPhaseErrorSum += phaseError;
mPhaseErrorCount++;
- Log.d(TAG, String.format("phase = %7.4f, diff = %7.4f, jitter = %7.4f",
- phase, phaseError, getAveragePhaseError()));
+ Log.d(TAG, String.format(Locale.getDefault(), "phase = %7.4f, mPhase = %7.4f, phaseError = %7.4f, jitter = %7.4f",
+ phase, mPhase, phaseError, getAveragePhaseError()));
}
mPhase = phase;
mPhaseCount++;
}
- reschedule();
}
public String getCurrentStatusReport() {
@@ -179,7 +294,6 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
return message.toString();
}
- @Override
public String getShortReport() {
return "maxMag = " + getMagnitudeText(mMaxMagnitude)
+ ", jitter = " + getJitterText();
@@ -187,6 +301,7 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
@Override
public void updateStatusText() {
+ gatherData();
mLastGlitchReport = getCurrentStatusReport();
runOnUiThread(() -> {
setAnalyzerText(mLastGlitchReport);
@@ -194,18 +309,34 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
}
}
+ // Write to status and command view
+ private void setInstructionsText(final String text) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mInstructionsTextView.setText(text);
+ }
+ });
+ }
+
private String getJitterText() {
return isPhaseJitterValid() ? getMagnitudeText(getAveragePhaseError()) : "?";
}
@Override
NativeSniffer createNativeSniffer() {
- return new TestDataPathsActivity.DataPathSniffer(this);
+ return new TestDataPathsActivity.DataPathSniffer();
+ }
+
+ @Override
+ public String getShortReport() {
+ return ((DataPathSniffer) mNativeSniffer).getShortReport();
}
native double getMagnitude();
native double getMaxMagnitude();
- native double getPhase();
+
+ native double getPhaseDataPaths();
@Override
protected void inflateActivity() {
@@ -215,10 +346,18 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mCheckBoxInputPresets = (CheckBox)findViewById(R.id.checkbox_paths_input_presets);
- mCheckBoxInputDevices = (CheckBox)findViewById(R.id.checkbox_paths_input_devices);
- mCheckBoxOutputDevices = (CheckBox)findViewById(R.id.checkbox_paths_output_devices);
+ mCheckBoxAllChannels = (CheckBox)findViewById(R.id.checkbox_paths_all_channels);
+ mCheckBoxInputChannelMasks = (CheckBox)findViewById(R.id.checkbox_paths_in_channel_masks);
+ mCheckBoxAllSampleRates =
+ (CheckBox)findViewById(R.id.checkbox_paths_all_sample_rates);
+
+ mInstructionsTextView = (TextView) findViewById(R.id.text_instructions);
+
+ mRadioGroupOutputChannelMasks = (RadioGroup) findViewById(R.id.group_ch_mask_options);
+ mRadioOutputChannelMasksNone = (RadioButton) findViewById(R.id.radio_out_ch_masks_none);
+ mRadioOutputChannelMasksSome = (RadioButton) findViewById(R.id.radio_out_ch_masks_some);
+ mRadioOutputChannelMasksAll = (RadioButton) findViewById(R.id.radio_out_ch_masks_all);
}
@Override
@@ -232,7 +371,7 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
}
static String getMagnitudeText(double value) {
- return String.format(MAGNITUDE_FORMAT, value);
+ return String.format(Locale.getDefault(), MAGNITUDE_FORMAT, value);
}
protected String getConfigText(StreamConfiguration config) {
@@ -244,35 +383,27 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
}
@Override
- protected String shouldTestBeSkipped() {
- String why = "";
+ protected String whyShouldTestBeSkipped() {
+ String why = super.whyShouldTestBeSkipped();
StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
StreamConfiguration requestedOutConfig = mAudioOutTester.requestedConfiguration;
StreamConfiguration actualInConfig = mAudioInputTester.actualConfiguration;
StreamConfiguration actualOutConfig = mAudioOutTester.actualConfiguration;
- // No point running the test if we don't get the data path we requested.
- if (actualInConfig.isMMap() != requestedInConfig.isMMap()) {
- log("Did not get requested MMap input stream");
- why += "mmap";
- }
- if (actualOutConfig.isMMap() != requestedOutConfig.isMMap()) {
- log("Did not get requested MMap output stream");
- why += "mmap";
- }
+
// Did we request a device and not get that device?
if (requestedInConfig.getDeviceId() != 0
&& (requestedInConfig.getDeviceId() != actualInConfig.getDeviceId())) {
- why += ", inDev(" + requestedInConfig.getDeviceId()
- + "!=" + actualInConfig.getDeviceId() + ")";
+ why += "inDev(" + requestedInConfig.getDeviceId()
+ + "!=" + actualInConfig.getDeviceId() + "),";
}
if (requestedOutConfig.getDeviceId() != 0
&& (requestedOutConfig.getDeviceId() != actualOutConfig.getDeviceId())) {
why += ", outDev(" + requestedOutConfig.getDeviceId()
- + "!=" + actualOutConfig.getDeviceId() + ")";
+ + "!=" + actualOutConfig.getDeviceId() + "),";
}
if ((requestedInConfig.getInputPreset() != actualInConfig.getInputPreset())) {
why += ", inPre(" + requestedInConfig.getInputPreset()
- + "!=" + actualInConfig.getInputPreset() + ")";
+ + "!=" + actualInConfig.getInputPreset() + "),";
}
return why;
}
@@ -288,10 +419,6 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
@Override
public String didTestFail() {
String why = "";
- StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
- StreamConfiguration requestedOutConfig = mAudioOutTester.requestedConfiguration;
- StreamConfiguration actualInConfig = mAudioInputTester.actualConfiguration;
- StreamConfiguration actualOutConfig = mAudioOutTester.actualConfiguration;
if (mMaxMagnitude <= MIN_REQUIRED_MAGNITUDE) {
why += ", mag";
}
@@ -322,280 +449,387 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
+ ", IN" + (actualInConfig.isMMap() ? "-M" : "-L")
+ " D=" + actualInConfig.getDeviceId()
+ ", ch=" + channelText(getInputChannel(), actualInConfig.getChannelCount())
+ + ", SR=" + actualInConfig.getSampleRate()
+ ", OUT" + (actualOutConfig.isMMap() ? "-M" : "-L")
+ " D=" + actualOutConfig.getDeviceId()
+ ", ch=" + channelText(getOutputChannel(), actualOutConfig.getChannelCount())
+ + ", SR=" + actualOutConfig.getSampleRate()
+ ", mag = " + getMagnitudeText(mMaxMagnitude);
}
- void setupDeviceCombo(int numInputChannels,
- int inputChannel,
- int numOutputChannels,
- int outputChannel) throws InterruptedException {
- // Configure settings
- StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
- StreamConfiguration requestedOutConfig = mAudioOutTester.requestedConfiguration;
-
- requestedInConfig.reset();
- requestedOutConfig.reset();
-
- requestedInConfig.setPerformanceMode(StreamConfiguration.PERFORMANCE_MODE_LOW_LATENCY);
- requestedOutConfig.setPerformanceMode(StreamConfiguration.PERFORMANCE_MODE_LOW_LATENCY);
-
- requestedInConfig.setSharingMode(StreamConfiguration.SHARING_MODE_SHARED);
- requestedOutConfig.setSharingMode(StreamConfiguration.SHARING_MODE_SHARED);
-
- requestedInConfig.setChannelCount(numInputChannels);
- requestedOutConfig.setChannelCount(numOutputChannels);
-
- requestedInConfig.setMMap(false);
- requestedOutConfig.setMMap(false);
-
- setInputChannel(inputChannel);
- setOutputChannel(outputChannel);
- }
-
- private TestResult testConfigurationsAddMagJitter() throws InterruptedException {
- TestResult testResult = testConfigurations();
+ @Override
+ protected TestResult testCurrentConfigurations() throws InterruptedException {
+ TestResult testResult = super.testCurrentConfigurations();
if (testResult != null) {
testResult.addComment("mag = " + TestDataPathsActivity.getMagnitudeText(mMagnitude)
+ ", jitter = " + getJitterText());
- }
- return testResult;
- }
-
- void testPresetCombo(int inputPreset,
- int numInputChannels,
- int inputChannel,
- int numOutputChannels,
- int outputChannel,
- boolean mmapEnabled
- ) throws InterruptedException {
- setupDeviceCombo(numInputChannels, inputChannel, numOutputChannels, outputChannel);
- StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
- requestedInConfig.setInputPreset(inputPreset);
- requestedInConfig.setMMap(mmapEnabled);
-
- mMagnitude = -1.0;
- TestResult testResult = testConfigurationsAddMagJitter();
- if (testResult != null) {
+ logOneLineSummary(testResult);
int result = testResult.result;
- String summary = getOneLineSummary()
- + ", inPre = "
- + StreamConfiguration.convertInputPresetToText(inputPreset)
- + "\n";
- appendSummary(summary);
if (result == TEST_RESULT_FAILED) {
- if (getMagnitude() < 0.000001) {
- testResult.addComment("The input is completely SILENT!");
- } else if (inputPreset == StreamConfiguration.INPUT_PRESET_VOICE_COMMUNICATION) {
- testResult.addComment("Maybe sine wave blocked by Echo Cancellation!");
+ int id = mAudioOutTester.actualConfiguration.getDeviceId();
+ int deviceType = getDeviceInfoById(id).getType();
+ int channelCount = mAudioOutTester.actualConfiguration.getChannelCount();
+ if (deviceType == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
+ && channelCount == 2
+ && getOutputChannel() == 1) {
+ testResult.addComment("Maybe EARPIECE does not mix stereo to mono!");
+ }
+ if (deviceType == TYPE_BUILTIN_SPEAKER_SAFE
+ && channelCount == 2
+ && getOutputChannel() == 0) {
+ testResult.addComment("Maybe SPEAKER_SAFE dropped channel zero!");
}
}
}
+ return testResult;
}
- void testPresetCombo(int inputPreset,
- int numInputChannels,
- int inputChannel,
- int numOutputChannels,
- int outputChannel
- ) throws InterruptedException {
- if (NativeEngine.isMMapSupported()) {
- testPresetCombo(inputPreset, numInputChannels, inputChannel,
- numOutputChannels, outputChannel, true);
- }
- testPresetCombo(inputPreset, numInputChannels, inputChannel,
- numOutputChannels, outputChannel, false);
- }
-
- void testPresetCombo(int inputPreset) throws InterruptedException {
- setTestName("Test InPreset = " + StreamConfiguration.convertInputPresetToText(inputPreset));
- testPresetCombo(inputPreset, 1, 0, 1, 0);
+ private void logSection(String name) {
+ logBoth("\n#" + (getTestCount() + 1) + " ########### " + name + "\n");
}
private void testInputPresets() throws InterruptedException {
- logBoth("\nTest InputPreset -------");
-
+ logSection("InputPreset");
+ StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
+ int originalPreset = requestedInConfig.getInputPreset();
for (int inputPreset : INPUT_PRESETS) {
- testPresetCombo(inputPreset);
+ requestedInConfig.setInputPreset(inputPreset);
+ testPerformancePaths();
+ }
+ requestedInConfig.setInputPreset(originalPreset);
+ }
+
+ // The native out channel mask is its channel mask shifted right by 2 bits.
+ // See AudioFormat.convertChannelOutMaskToNativeMask()
+ int convertJavaOutChannelMaskToNativeChannelMask(int javaChannelMask) {
+ return javaChannelMask >> 2;
+ }
+
+ // The native channel mask in AAudio and Oboe is different than the Java IN channel mask.
+ // See AAudioConvert_aaudioToAndroidChannelLayoutMask()
+ int convertJavaInChannelMaskToNativeChannelMask(int javaChannelMask) {
+ switch (javaChannelMask) {
+ case JAVA_CHANNEL_IN_MONO:
+ return StreamConfiguration.CHANNEL_MONO;
+ case JAVA_CHANNEL_IN_STEREO:
+ return StreamConfiguration.CHANNEL_STEREO;
+ case JAVA_CHANNEL_IN_FRONT_BACK:
+ return StreamConfiguration.CHANNEL_FRONT_BACK;
+ case JAVA_CHANNEL_IN_2POINT0POINT2:
+ return StreamConfiguration.CHANNEL_2POINT0POINT2;
+ case JAVA_CHANNEL_IN_2POINT1POINT2:
+ return StreamConfiguration.CHANNEL_2POINT1POINT2;
+ case JAVA_CHANNEL_IN_3POINT0POINT2:
+ return StreamConfiguration.CHANNEL_3POINT0POINT2;
+ case JAVA_CHANNEL_IN_3POINT1POINT2:
+ return StreamConfiguration.CHANNEL_3POINT1POINT2;
+ case JAVA_CHANNEL_IN_5POINT1:
+ return StreamConfiguration.CHANNEL_5POINT1;
+ default:
+ log("Unimplemented java channel mask: " + javaChannelMask + "\n");
+ return JAVA_CHANNEL_UNDEFINED;
}
-// TODO Resolve issue with echo cancellation killing the signal.
-// testPresetCombo(StreamConfiguration.INPUT_PRESET_VOICE_COMMUNICATION,
-// 1, 0, 2, 0);
-// testPresetCombo(StreamConfiguration.INPUT_PRESET_VOICE_COMMUNICATION,
-// 1, 0, 2, 1);
-// testPresetCombo(StreamConfiguration.INPUT_PRESET_VOICE_COMMUNICATION,
-// 2, 0, 2, 0);
-// testPresetCombo(StreamConfiguration.INPUT_PRESET_VOICE_COMMUNICATION,
-// 2, 0, 2, 1);
- }
-
- void testInputDeviceCombo(int deviceId,
- int numInputChannels,
- int inputChannel,
- boolean mmapEnabled) throws InterruptedException {
- final int numOutputChannels = 2;
- setupDeviceCombo(numInputChannels, inputChannel, numOutputChannels, 0);
+ }
- StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
- requestedInConfig.setInputPreset(StreamConfiguration.INPUT_PRESET_VOICE_RECOGNITION);
- requestedInConfig.setDeviceId(deviceId);
- requestedInConfig.setMMap(mmapEnabled);
+ void logOneLineSummary(TestResult testResult) {
+ logOneLineSummary(testResult, "");
+ }
- mMagnitude = -1.0;
- TestResult testResult = testConfigurationsAddMagJitter();
- if (testResult != null) {
- appendSummary(getOneLineSummary() + "\n");
+ void logOneLineSummary(TestResult testResult, String extra) {
+ int result = testResult.result;
+ String oneLineSummary;
+ if (result == TEST_RESULT_SKIPPED) {
+ oneLineSummary = "#" + mAutomatedTestRunner.getTestCount() + extra + ", SKIP";
+ } else if (result == TEST_RESULT_FAILED) {
+ oneLineSummary = getOneLineSummary() + extra + ", FAIL";
+ } else {
+ oneLineSummary = getOneLineSummary() + extra;
}
+ appendSummary(oneLineSummary + "\n");
}
- void testInputDeviceCombo(int deviceId,
- int deviceType,
- int numInputChannels,
- int inputChannel) throws InterruptedException {
+ void logBoth(String text) {
+ log(text);
+ appendSummary(text + "\n");
+ }
- String typeString = AudioDeviceInfoConverter.typeToString(deviceType);
- setTestName("Test InDev: #" + deviceId + " " + typeString
- + "_" + inputChannel + "/" + numInputChannels);
- if (NativeEngine.isMMapSupported()) {
- testInputDeviceCombo(deviceId, numInputChannels, inputChannel, true);
- }
- testInputDeviceCombo(deviceId, numInputChannels, inputChannel, false);
- }
-
- void testInputDevices() throws InterruptedException {
- logBoth("\nTest Input Devices -------");
-
- AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
- int numTested = 0;
- for (AudioDeviceInfo deviceInfo : devices) {
- log("----\n"
- + AudioDeviceInfoConverter.toString(deviceInfo) + "\n");
- if (!deviceInfo.isSource()) continue; // FIXME log as error?!
- int deviceType = deviceInfo.getType();
- if (deviceType == AudioDeviceInfo.TYPE_BUILTIN_MIC) {
- int id = deviceInfo.getId();
- int[] channelCounts = deviceInfo.getChannelCounts();
- numTested++;
- // Always test mono and stereo.
- testInputDeviceCombo(id, deviceType, 1, 0);
- testInputDeviceCombo(id, deviceType, 2, 0);
- testInputDeviceCombo(id, deviceType, 2, 1);
- if (channelCounts.length > 0) {
- for (int numChannels : channelCounts) {
- // Test higher channel counts.
- if (numChannels > 2) {
- log("numChannels = " + numChannels + "\n");
- for (int channel = 0; channel < numChannels; channel++) {
- testInputDeviceCombo(id, deviceType, numChannels, channel);
- }
- }
- }
- }
- } else {
- log("Device skipped for type.");
- }
+ void logFailed(String text) {
+ log(text);
+ logAnalysis(text + "\n");
+ }
+
+ private void testDeviceOutputInfo(AudioDeviceInfo outputDeviceInfo) throws InterruptedException {
+ AudioDeviceInfo inputDeviceInfo = findCompatibleInputDevice(outputDeviceInfo.getType());
+ showDeviceInfo(outputDeviceInfo, inputDeviceInfo);
+ if (inputDeviceInfo == null) {
+ return;
+ }
+
+ StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
+ StreamConfiguration requestedOutConfig = mAudioOutTester.requestedConfiguration;
+ requestedInConfig.reset();
+ requestedOutConfig.reset();
+ requestedInConfig.setDeviceId(inputDeviceInfo.getId());
+ requestedOutConfig.setDeviceId(outputDeviceInfo.getId());
+ resetChannelConfigurations(requestedInConfig, requestedOutConfig);
+
+ if (mCheckBoxAllChannels.isChecked()) {
+ runOnUiThread(() -> mCheckBoxAllChannels.setEnabled(false));
+ testOutputChannelCounts(inputDeviceInfo, outputDeviceInfo);
+ }
+
+ if (mCheckBoxInputPresets.isChecked()) {
+ runOnUiThread(() -> mCheckBoxInputPresets.setEnabled(false));
+ testInputPresets();
+ }
+
+ if (mCheckBoxAllSampleRates.isChecked()) {
+ logSection("Sample Rates");
+ runOnUiThread(() -> mCheckBoxAllSampleRates.setEnabled(false));
+ for (int sampleRate : SAMPLE_RATES) {
+ requestedInConfig.setSampleRate(sampleRate);
+ requestedOutConfig.setSampleRate(sampleRate);
+ testPerformancePaths();
+ }
+ }
+ requestedInConfig.setSampleRate(0);
+ requestedOutConfig.setSampleRate(0);
+
+ // Channel Masks added to AAudio API in S_V2
+ if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2
+ && isDeviceTypeMixedForLoopback(outputDeviceInfo.getType())) {
+
+ if (mCheckBoxInputChannelMasks.isChecked()) { // INPUT?
+ logSection("Input Channel Masks");
+ runOnUiThread(() -> mCheckBoxInputChannelMasks.setEnabled(false));
+
+ resetChannelConfigurations(requestedInConfig, requestedOutConfig);
+ requestedInConfig.setChannelCount(0);
+ // Test the reported channel masks.
+ int[] channelMasks = inputDeviceInfo.getChannelMasks();
+ if (channelMasks.length > 0) {
+ for (int channelMask : channelMasks) {
+ int nativeChannelMask =
+ convertJavaInChannelMaskToNativeChannelMask(channelMask);
+ if (nativeChannelMask == JAVA_CHANNEL_UNDEFINED) {
+ log("channelMask: " + channelMask + " not supported. Skipping.\n");
+ continue;
+ }
+ log("\n#### nativeChannelMask = "
+ + convertChannelMaskToText(nativeChannelMask) + "\n");
+ int channelCount = Integer.bitCount(nativeChannelMask);
+ requestedInConfig.setChannelMask(nativeChannelMask);
+ for (int channel = 0; channel < channelCount; channel++) {
+ setInputChannel(channel);
+ testPerformancePaths();
+ }
+ }
+ }
+ resetChannelConfigurations(requestedInConfig, requestedOutConfig);
+ }
+
+ runOnUiThread(() -> mRadioGroupOutputChannelMasks.setEnabled(false));
+ if (!mRadioOutputChannelMasksNone.isChecked()) { // OUTPUT?
+ logSection("Output Channel Masks");
+ requestedInConfig.setChannelCount(1);
+ for (int channelMask : mRadioOutputChannelMasksAll.isChecked() ?
+ ALL_OUTPUT_CHANNEL_MASKS : SHORT_OUTPUT_CHANNEL_MASKS) {
+ int channelCount = Integer.bitCount(channelMask);
+ requestedOutConfig.setChannelMask(channelMask);
+ for (int channel = 0; channel < channelCount; channel++) {
+ setOutputChannel(channel);
+ testPerformancePaths();
+ }
+ }
+ resetChannelConfigurations(requestedInConfig, requestedOutConfig);
+ }
+ }
+ }
+
+ private void resetChannelConfigurations(StreamConfiguration requestedInConfig, StreamConfiguration requestedOutConfig) {
+ requestedInConfig.setChannelMask(0);
+ requestedOutConfig.setChannelMask(0);
+ requestedInConfig.setChannelCount(1);
+ requestedOutConfig.setChannelCount(1);
+ setInputChannel(0);
+ setOutputChannel(0);
+ }
+
+ private void showDeviceInfo(AudioDeviceInfo outputDeviceInfo, AudioDeviceInfo inputDeviceInfo) {
+ String deviceText = "OUT: type = "
+ + AudioDeviceInfoConverter.typeToString(outputDeviceInfo.getType())
+ + ", #ch = " + findLargestChannelCount(outputDeviceInfo.getChannelCounts());
+
+ setInstructionsText(deviceText);
+
+ if (inputDeviceInfo == null) {
+ deviceText += "ERROR - cannot find compatible device type for input!";
+ } else {
+ deviceText = "IN: type = "
+ + AudioDeviceInfoConverter.typeToString(inputDeviceInfo.getType())
+ + ", #ch = " + findLargestChannelCount(inputDeviceInfo.getChannelCounts())
+ + "\n" + deviceText;
}
+ setInstructionsText(deviceText);
+ }
- if (numTested == 0) {
- log("NO INPUT DEVICE FOUND!\n");
+ public static int findLargestChannelCount(int[] arr) {
+ if (arr == null || arr.length == 0) {
+ return 2;
}
+ return findLargestInt(arr);
}
- void testOutputDeviceCombo(int deviceId,
- int deviceType,
- int numOutputChannels,
- int outputChannel,
- boolean mmapEnabled) throws InterruptedException {
- final int numInputChannels = 2; // TODO review, done because of mono problems on some devices
- setupDeviceCombo(numInputChannels, 0, numOutputChannels, outputChannel);
+ public static int findLargestInt(int[] arr) {
+ if (arr == null || arr.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty");
+ }
+
+ int max = arr[0];
+ for (int i = 1; i < arr.length; i++) {
+ if (arr[i] > max) {
+ max = arr[i];
+ }
+ }
+ return max;
+ }
+ private void testOutputChannelCounts(AudioDeviceInfo inputDeviceInfo, AudioDeviceInfo outputDeviceInfo) throws InterruptedException {
+ logSection("Output Channel Counts");
+ ArrayList<Integer> channelCountsTested =new ArrayList<Integer>();
+ StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
StreamConfiguration requestedOutConfig = mAudioOutTester.requestedConfiguration;
- requestedOutConfig.setDeviceId(deviceId);
- requestedOutConfig.setMMap(mmapEnabled);
- mMagnitude = -1.0;
- TestResult testResult = testConfigurationsAddMagJitter();
- if (testResult != null) {
- int result = testResult.result;
- appendSummary(getOneLineSummary() + "\n");
- if (result == TEST_RESULT_FAILED) {
- if (deviceType == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
- && numOutputChannels == 2
- && outputChannel == 1) {
- testResult.addComment("Maybe EARPIECE does not mix stereo to mono!");
+ int[] outputChannelCounts = outputDeviceInfo.getChannelCounts();
+ if (isDeviceTypeMixedForLoopback(outputDeviceInfo.getType())) {
+ requestedInConfig.setChannelCount(1);
+ setInputChannel(0);
+ // test mono
+ requestedOutConfig.setChannelCount(1);
+ channelCountsTested.add(1);
+ setOutputChannel(0);
+ testPerformancePaths();
+ // test stereo
+ requestedOutConfig.setChannelCount(2);
+ channelCountsTested.add(2);
+ setOutputChannel(0);
+ testPerformancePaths();
+ setOutputChannel(1);
+ testPerformancePaths();
+ // Test channels for each channelCount above 2
+ for (int numChannels : outputChannelCounts) {
+ log("numChannels = " + numChannels);
+ if (numChannels > 4) {
+ log("numChannels forced to 4!");
}
- if (deviceType == TYPE_BUILTIN_SPEAKER_SAFE
- && numOutputChannels == 2
- && outputChannel == 0) {
- testResult.addComment("Maybe SPEAKER_SAFE dropped channel zero!");
+ if (!channelCountsTested.contains(numChannels)) {
+ requestedOutConfig.setChannelCount(numChannels);
+ channelCountsTested.add(numChannels);
+ for (int channel = 0; channel < numChannels; channel++) {
+ setOutputChannel(channel);
+ testPerformancePaths();
+ }
+ }
+ }
+ } else {
+ // test mono
+ testMatchingChannels(1);
+ channelCountsTested.add(1);
+ // Test two matching stereo channels.
+ testMatchingChannels(2);
+ channelCountsTested.add(2);
+ // Test matching channels for each channelCount above 2
+ for (int numChannels : outputChannelCounts) {
+ log("numChannels = " + numChannels);
+ if (numChannels > 4) {
+ log("numChannels forced to 4!");
+ numChannels = 4;
+ }
+ if (!channelCountsTested.contains(numChannels)) {
+ testMatchingChannels(numChannels);
+ channelCountsTested.add(numChannels);
}
}
}
+ // Restore defaults.
+ requestedInConfig.setChannelCount(1);
+ setInputChannel(0);
+ requestedOutConfig.setChannelCount(1);
+ setOutputChannel(0);
+ }
+
+ private void testMatchingChannels(int numChannels) throws InterruptedException {
+ mAudioInputTester.requestedConfiguration.setChannelCount(numChannels);
+ mAudioOutTester.requestedConfiguration.setChannelCount(numChannels);
+ for (int channel = 0; channel < numChannels; channel++) {
+ setInputChannel(channel);
+ setOutputChannel(channel);
+ testPerformancePaths();
+ }
}
- void testOutputDeviceCombo(int deviceId,
- int deviceType,
- int numOutputChannels,
- int outputChannel) throws InterruptedException {
- String typeString = AudioDeviceInfoConverter.typeToString(deviceType);
- setTestName("Test OutDev: #" + deviceId + " " + typeString
- + "_" + outputChannel + "/" + numOutputChannels);
+ private void testPerformancePaths() throws InterruptedException {
+ StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration;
+ StreamConfiguration requestedOutConfig = mAudioOutTester.requestedConfiguration;
+
+ requestedInConfig.setSharingMode(StreamConfiguration.SHARING_MODE_SHARED);
+ requestedOutConfig.setSharingMode(StreamConfiguration.SHARING_MODE_SHARED);
+
+ // Legacy NONE
+ requestedInConfig.setMMap(false);
+ requestedOutConfig.setMMap(false);
+ requestedInConfig.setPerformanceMode(StreamConfiguration.PERFORMANCE_MODE_NONE);
+ requestedOutConfig.setPerformanceMode(StreamConfiguration.PERFORMANCE_MODE_NONE);
+ testCurrentConfigurations();
+
+ // Legacy LOW_LATENCY
+ requestedInConfig.setPerformanceMode(StreamConfiguration.PERFORMANCE_MODE_LOW_LATENCY);
+ requestedOutConfig.setPerformanceMode(StreamConfiguration.PERFORMANCE_MODE_LOW_LATENCY);
+ testCurrentConfigurations();
+
+ // MMAP LowLatency
if (NativeEngine.isMMapSupported()) {
- testOutputDeviceCombo(deviceId, deviceType, numOutputChannels, outputChannel, true);
+ requestedInConfig.setMMap(true);
+ requestedOutConfig.setMMap(true);
+ testCurrentConfigurations();
}
- testOutputDeviceCombo(deviceId, deviceType, numOutputChannels, outputChannel, false);
- }
-
- void logBoth(String text) {
- log(text);
- appendSummary(text + "\n");
- }
+ requestedInConfig.setMMap(false);
+ requestedOutConfig.setMMap(false);
- void logFailed(String text) {
- log(text);
- logAnalysis(text + "\n");
}
- void testOutputDevices() throws InterruptedException {
- logBoth("\nTest Output Devices -------");
-
- AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
- int numTested = 0;
- for (AudioDeviceInfo deviceInfo : devices) {
- log("----\n"
- + AudioDeviceInfoConverter.toString(deviceInfo) + "\n");
- if (!deviceInfo.isSink()) continue;
- int deviceType = deviceInfo.getType();
- if (deviceType == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
- || deviceType == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
- || deviceType == TYPE_BUILTIN_SPEAKER_SAFE) {
- int id = deviceInfo.getId();
- int[] channelCounts = deviceInfo.getChannelCounts();
- numTested++;
- // Always test mono and stereo.
- testOutputDeviceCombo(id, deviceType, 1, 0);
- testOutputDeviceCombo(id, deviceType, 2, 0);
- testOutputDeviceCombo(id, deviceType, 2, 1);
- if (channelCounts.length > 0) {
- for (int numChannels : channelCounts) {
- // Test higher channel counts.
- if (numChannels > 2) {
- log("numChannels = " + numChannels + "\n");
- for (int channel = 0; channel < numChannels; channel++) {
- testOutputDeviceCombo(id, deviceType, numChannels, channel);
- }
- }
- }
- }
- } else {
- log("Device skipped for type.");
- }
+ private void testOutputDeviceTypes() throws InterruptedException {
+ // Determine which output device type to test based on priorities.
+ AudioDeviceInfo info = getDeviceInfoByType(AudioDeviceInfo.TYPE_USB_DEVICE,
+ AudioManager.GET_DEVICES_OUTPUTS);
+ if (info != null) {
+ testDeviceOutputInfo(info);
+ return;
+ }
+ info = getDeviceInfoByType(AudioDeviceInfo.TYPE_USB_HEADSET,
+ AudioManager.GET_DEVICES_OUTPUTS);
+ if (info != null) {
+ testDeviceOutputInfo(info);
+ return;
}
- if (numTested == 0) {
- log("NO OUTPUT DEVICE FOUND!\n");
+ info = getDeviceInfoByType(AudioDeviceInfo.TYPE_WIRED_HEADSET,
+ AudioManager.GET_DEVICES_OUTPUTS);
+ if (info != null) {
+ testDeviceOutputInfo(info);
+ return;
+ }
+ // Test both SPEAKER and SPEAKER_SAFE
+ info = getDeviceInfoByType(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
+ AudioManager.GET_DEVICES_OUTPUTS);
+ if (info != null) {
+ testDeviceOutputInfo(info);
+ // Continue on to SPEAKER_SAFE
+ }
+ info = getDeviceInfoByType(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER_SAFE,
+ AudioManager.GET_DEVICES_OUTPUTS);
+ if (info != null) {
+ testDeviceOutputInfo(info);
}
}
@@ -610,31 +844,25 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
mTestResults.clear();
mDurationSeconds = DURATION_SECONDS;
- if (mCheckBoxInputPresets.isChecked()) {
- runOnUiThread(() -> mCheckBoxInputPresets.setEnabled(false));
- testInputPresets();
- }
- if (mCheckBoxInputDevices.isChecked()) {
- runOnUiThread(() -> mCheckBoxInputDevices.setEnabled(false));
- testInputDevices();
- }
- if (mCheckBoxOutputDevices.isChecked()) {
- runOnUiThread(() -> mCheckBoxOutputDevices.setEnabled(false));
- testOutputDevices();
- }
+ runOnUiThread(() -> keepScreenOn(true));
- analyzeTestResults();
+ testOutputDeviceTypes();
+
+ compareFailedTestsWithNearestPassingTest();
} catch (InterruptedException e) {
- analyzeTestResults();
+ compareFailedTestsWithNearestPassingTest();
} catch (Exception e) {
log(e.getMessage());
showErrorToast(e.getMessage());
} finally {
runOnUiThread(() -> {
mCheckBoxInputPresets.setEnabled(true);
- mCheckBoxInputDevices.setEnabled(true);
- mCheckBoxOutputDevices.setEnabled(true);
+ mCheckBoxAllChannels.setEnabled(true);
+ mCheckBoxInputChannelMasks.setEnabled(true);
+ mRadioGroupOutputChannelMasks.setEnabled(true);
+ mCheckBoxAllSampleRates.setEnabled(true);
+ keepScreenOn(false);
});
}
}
@@ -645,22 +873,59 @@ public class TestDataPathsActivity extends BaseAutoGlitchActivity {
StreamConfiguration requestedOutConfig = mAudioOutTester.requestedConfiguration;
configureStreamsFromBundle(mBundleFromIntent, requestedInConfig, requestedOutConfig);
- boolean shouldUseInputPresets = mBundleFromIntent.getBoolean(KEY_USE_INPUT_PRESETS,
+ // These are the current supported options.
+ final boolean shouldUseInputPresets = mBundleFromIntent.getBoolean(KEY_USE_INPUT_PRESETS,
VALUE_DEFAULT_USE_INPUT_PRESETS);
- boolean shouldUseInputDevices = mBundleFromIntent.getBoolean(KEY_USE_INPUT_DEVICES,
- VALUE_DEFAULT_USE_INPUT_DEVICES);
- boolean shouldUseOutputDevices = mBundleFromIntent.getBoolean(KEY_USE_OUTPUT_DEVICES,
- VALUE_DEFAULT_USE_OUTPUT_DEVICES);
- int singleTestIndex = mBundleFromIntent.getInt(KEY_SINGLE_TEST_INDEX,
+ final boolean shouldUseAllSampleRates =
+ mBundleFromIntent.getBoolean(KEY_USE_ALL_SAMPLE_RATES,
+ VALUE_DEFAULT_USE_ALL_SAMPLE_RATES);
+
+ final int singleTestIndex = mBundleFromIntent.getInt(KEY_SINGLE_TEST_INDEX,
VALUE_DEFAULT_SINGLE_TEST_INDEX);
+ // The old deprecated commands will get mapped to the closest new options.
+ final boolean shouldUseInputDevices = mBundleFromIntent.getBoolean(KEY_USE_INPUT_DEVICES,
+ VALUE_DEFAULT_USE_INPUT_CHANNEL_MASKS);
+ final boolean shouldUseInputChannelMasks =
+ mBundleFromIntent.getBoolean(KEY_USE_INPUT_CHANNEL_MASKS,
+ shouldUseInputDevices);
+
+ final boolean shouldUseOutputDevices = mBundleFromIntent.getBoolean(KEY_USE_OUTPUT_DEVICES,
+ VALUE_DEFAULT_USE_ALL_CHANNEL_COUNTS);
+ final boolean shouldUseAllChannelCounts =
+ mBundleFromIntent.getBoolean(KEY_USE_ALL_CHANNEL_COUNTS,
+ shouldUseOutputDevices);
+
+ final boolean shouldUseAllOutputChannelMasks =
+ mBundleFromIntent.getBoolean(KEY_USE_ALL_OUTPUT_CHANNEL_MASKS,
+ VALUE_DEFAULT_USE_ALL_OUTPUT_CHANNEL_MASKS);
+ final int defaultOutputChannelMasksLevel = shouldUseAllOutputChannelMasks
+ ? COVERAGE_LEVEL_ALL : COVERAGE_LEVEL_SOME;
+ final int outputChannelMasksLevel = mBundleFromIntent.getInt(KEY_OUTPUT_CHANNEL_MASKS_LEVEL,
+ defaultOutputChannelMasksLevel);
+
runOnUiThread(() -> {
mCheckBoxInputPresets.setChecked(shouldUseInputPresets);
- mCheckBoxInputDevices.setChecked(shouldUseInputDevices);
- mCheckBoxOutputDevices.setChecked(shouldUseOutputDevices);
+ mCheckBoxAllSampleRates.setChecked(shouldUseAllSampleRates);
mAutomatedTestRunner.setTestIndexText(singleTestIndex);
+ mCheckBoxAllChannels.setChecked(shouldUseAllChannelCounts);
+ mCheckBoxInputChannelMasks.setChecked(shouldUseInputChannelMasks);
+ switch(outputChannelMasksLevel) {
+ case COVERAGE_LEVEL_ALL:
+ mRadioOutputChannelMasksAll.setChecked(true);
+ break;
+ case COVERAGE_LEVEL_SOME:
+ mRadioOutputChannelMasksSome.setChecked(true);
+ break;
+ case COVERAGE_LEVEL_NONE:
+ default:
+ mRadioOutputChannelMasksNone.setChecked(true);
+ break;
+ }
});
+ // This will sync with the above checkbox code because it will log on the UI
+ // thread before running any tests.
mAutomatedTestRunner.startTest();
}
}