aboutsummaryrefslogtreecommitdiff
path: root/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java')
-rw-r--r--apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java241
1 files changed, 155 insertions, 86 deletions
diff --git a/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java b/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java
index f61873fa..9043f28d 100644
--- a/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java
+++ b/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestAudioActivity.java
@@ -16,34 +16,32 @@
package com.mobileer.oboetester;
-import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.media.AudioAttributes;
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.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
+import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
+import android.widget.Spinner;
import android.widget.Toast;
+import androidx.annotation.NonNull;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
import java.util.ArrayList;
+import java.util.Locale;
/**
* Base class for other Activities.
@@ -57,9 +55,11 @@ abstract class TestAudioActivity extends Activity {
public static final int AUDIO_STATE_OPEN = 0;
public static final int AUDIO_STATE_STARTED = 1;
public static final int AUDIO_STATE_PAUSED = 2;
- public static final int AUDIO_STATE_STOPPED = 3;
- public static final int AUDIO_STATE_CLOSING = 4;
- public static final int AUDIO_STATE_CLOSED = 5;
+ public static final int AUDIO_STATE_FLUSHED = 3;
+ public static final int AUDIO_STATE_STOPPED = 4;
+ public static final int AUDIO_STATE_RELEASED = 5;
+ public static final int AUDIO_STATE_CLOSING = 6;
+ public static final int AUDIO_STATE_CLOSED = 7;
public static final int COLOR_ACTIVE = 0xFFD0D0A0;
public static final int COLOR_IDLE = 0xFFD0D0D0;
@@ -75,8 +75,7 @@ abstract class TestAudioActivity extends Activity {
public static final int ACTIVITY_GLITCHES = 6;
public static final int ACTIVITY_TEST_DISCONNECT = 7;
public static final int ACTIVITY_DATA_PATHS = 8;
-
- private static final int MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE = 1001;
+ public static final int ACTIVITY_DYNAMIC_WORKLOAD = 9;
private int mAudioState = AUDIO_STATE_CLOSED;
@@ -84,10 +83,16 @@ abstract class TestAudioActivity extends Activity {
private Button mOpenButton;
private Button mStartButton;
private Button mPauseButton;
+ private Button mFlushButton;
private Button mStopButton;
+ private Button mReleaseButton;
private Button mCloseButton;
private MyStreamSniffer mStreamSniffer;
private CheckBox mCallbackReturnStopBox;
+ private Spinner mHangTimeSpinner;
+
+ // Only set in some activities
+ protected CommunicationDeviceView mCommunicationDeviceView;
private int mSampleRate;
private int mSingleTestIndex = -1;
private static boolean mBackgroundEnabled;
@@ -96,6 +101,7 @@ abstract class TestAudioActivity extends Activity {
protected boolean mTestRunningByIntent;
protected String mResultFileName;
private String mTestResults;
+ private ExternalFileWriter mExternalFileWriter = new ExternalFileWriter(this);
public String getTestName() {
return "TestAudio";
@@ -225,6 +231,10 @@ abstract class TestAudioActivity extends Activity {
super.onStart();
resetConfiguration();
setActivityType(getActivityType());
+ // TODO Use LifeCycleObserver instead of this.
+ if (mCommunicationDeviceView != null) {
+ mCommunicationDeviceView.onStart();
+ }
}
protected void resetConfiguration() {
@@ -289,6 +299,9 @@ abstract class TestAudioActivity extends Activity {
Log.i(TAG, "onStop() called so stop the test =========================");
onStopTest();
}
+ if (mCommunicationDeviceView != null) {
+ mCommunicationDeviceView.onStop();
+ }
super.onStop();
}
@@ -307,7 +320,9 @@ abstract class TestAudioActivity extends Activity {
mOpenButton.setBackgroundColor(mAudioState == AUDIO_STATE_OPEN ? COLOR_ACTIVE : COLOR_IDLE);
mStartButton.setBackgroundColor(mAudioState == AUDIO_STATE_STARTED ? COLOR_ACTIVE : COLOR_IDLE);
mPauseButton.setBackgroundColor(mAudioState == AUDIO_STATE_PAUSED ? COLOR_ACTIVE : COLOR_IDLE);
+ mFlushButton.setBackgroundColor(mAudioState == AUDIO_STATE_FLUSHED ? COLOR_ACTIVE : COLOR_IDLE);
mStopButton.setBackgroundColor(mAudioState == AUDIO_STATE_STOPPED ? COLOR_ACTIVE : COLOR_IDLE);
+ mReleaseButton.setBackgroundColor(mAudioState == AUDIO_STATE_RELEASED ? COLOR_ACTIVE : COLOR_IDLE);
mCloseButton.setBackgroundColor(mAudioState == AUDIO_STATE_CLOSED ? COLOR_ACTIVE : COLOR_IDLE);
}
setConfigViewsEnabled(mAudioState == AUDIO_STATE_CLOSED);
@@ -368,7 +383,6 @@ abstract class TestAudioActivity extends Activity {
if (streamContext.configurationView != null) {
streamContext.configurationView.setOutput(false);
}
- streamContext.tester = AudioInputTester.getInstance();
mStreamContexts.add(streamContext);
return streamContext;
}
@@ -407,7 +421,9 @@ abstract class TestAudioActivity extends Activity {
if (mOpenButton != null) {
mStartButton = (Button) findViewById(R.id.button_start);
mPauseButton = (Button) findViewById(R.id.button_pause);
+ mFlushButton = (Button) findViewById(R.id.button_flush);
mStopButton = (Button) findViewById(R.id.button_stop);
+ mReleaseButton = (Button) findViewById(R.id.button_release);
mCloseButton = (Button) findViewById(R.id.button_close);
}
mStreamContexts = new ArrayList<StreamContext>();
@@ -423,6 +439,24 @@ abstract class TestAudioActivity extends Activity {
}
OboeAudioStream.setCallbackReturnStop(false);
+ mHangTimeSpinner = (Spinner) findViewById(R.id.spinner_hang_time);
+ if (mHangTimeSpinner != null) {
+ mHangTimeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ String hangTimeText = (String) mHangTimeSpinner.getAdapter().getItem(position);
+ int hangTimeMillis = Integer.parseInt(hangTimeText);
+ Log.d(TAG, "Hang Time = " + hangTimeMillis + " msec");
+
+ OboeAudioStream.setHangTimeMillis(hangTimeMillis);
+ }
+
+ public void onNothingSelected(AdapterView<?> parent) {
+ OboeAudioStream.setHangTimeMillis(0);
+ }
+ });
+ }
+ OboeAudioStream.setHangTimeMillis(0);
+
mStreamSniffer = new MyStreamSniffer();
}
@@ -438,8 +472,8 @@ abstract class TestAudioActivity extends Activity {
}
protected void showErrorToast(String message) {
+ Log.e(TAG, "showErrorToast(\"" + message + "\")");
String text = "Error: " + message;
- Log.e(TAG, text);
showToast(text);
}
@@ -454,20 +488,39 @@ abstract class TestAudioActivity extends Activity {
});
}
+ private void onStartAllContexts() {
+ for (StreamContext streamContext : mStreamContexts) {
+ streamContext.tester.getCurrentAudioStream().onStart();
+ }
+ }
+ private void onStopAllContexts() {
+ for (StreamContext streamContext : mStreamContexts) {
+ streamContext.tester.getCurrentAudioStream().onStop();
+ }
+ }
+
public void openAudio(View view) {
try {
openAudio();
} catch (Exception e) {
- showErrorToast(e.getMessage());
+ showErrorToast("openAudio() caught " + e.getMessage());
+ }
+ }
+
+ void clearHangTime() {
+ OboeAudioStream.setHangTimeMillis(0);
+ if (mHangTimeSpinner != null) {
+ mHangTimeSpinner.setSelection(0);
}
}
public void startAudio(View view) {
Log.i(TAG, "startAudio() called =======================================");
+ clearHangTime(); // start running
try {
startAudio();
} catch (Exception e) {
- showErrorToast(e.getMessage());
+ showErrorToast("startAudio() caught " + e.getMessage());
}
keepScreenOn(true);
}
@@ -490,10 +543,18 @@ abstract class TestAudioActivity extends Activity {
keepScreenOn(false);
}
+ public void flushAudio(View view) {
+ flushAudio();
+ }
+
public void closeAudio(View view) {
closeAudio();
}
+ public void releaseAudio(View view) {
+ releaseAudio();
+ }
+
public int getSampleRate() {
return mSampleRate;
}
@@ -507,18 +568,25 @@ abstract class TestAudioActivity extends Activity {
applyConfigurationViewsToModels();
}
- int sampleRate = 0;
+ int sampleRate = 0; // Use the OUTPUT sample rate for INPUT
// Open output streams then open input streams.
// This is so that the capacity of input stream can be expanded to
// match the burst size of the output for full duplex.
for (StreamContext streamContext : mStreamContexts) {
- if (!streamContext.isInput()) {
+ if (!streamContext.isInput()) { // OUTPUT?
openStreamContext(streamContext);
int streamSampleRate = streamContext.tester.actualConfiguration.getSampleRate();
if (sampleRate == 0) {
sampleRate = streamSampleRate;
}
+
+ if (shouldSetStreamControlByAttributes()) {
+ // Associate volume keys with this output stream.
+ int actualUsage = streamContext.tester.actualConfiguration.getUsage();
+ int actualContentType = streamContext.tester.actualConfiguration.getContentType();
+ setStreamControlByAttributes(actualUsage, actualContentType);
+ }
}
}
for (StreamContext streamContext : mStreamContexts) {
@@ -530,9 +598,29 @@ abstract class TestAudioActivity extends Activity {
}
}
updateEnabledWidgets();
+ onStartAllContexts();
mStreamSniffer.startStreamSniffer();
}
+ protected boolean shouldSetStreamControlByAttributes() {
+ return true;
+ }
+
+ /**
+ * Associate the volume keys with the stream we are playing.
+ * @param usage usage for the stream
+ * @param contentType tupe of the stream
+ */
+ private void setStreamControlByAttributes(int usage, int contentType) {
+ AudioAttributes attributes = new AudioAttributes.Builder().setUsage(usage)
+ .setContentType(contentType).build();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ int volumeControlStream = attributes.getVolumeControlStream();
+ Log.i(TAG, "setVolumeControlStream(" + volumeControlStream + ")");
+ setVolumeControlStream(volumeControlStream);
+ }
+ }
+
/**
* @param deviceId
* @return true if the device is TYPE_BLUETOOTH_SCO
@@ -564,7 +652,7 @@ abstract class TestAudioActivity extends Activity {
try {
streamContext.configurationView.setupEffects(sessionId);
} catch (Exception e) {
- showErrorToast(e.getMessage());
+ showErrorToast("openStreamContext() caught " + e.getMessage());
}
}
streamContext.configurationView.updateDisplay(streamContext.tester.actualConfiguration);
@@ -576,21 +664,28 @@ abstract class TestAudioActivity extends Activity {
private native int pauseNative();
+ private native int flushNative();
+
private native int stopNative();
+ private native int releaseNative();
+
protected native void setActivityType(int activityType);
private native int getFramesPerCallback();
+ public native void setUseAlternativeAdpf(boolean enabled);
+
private static native void setDefaultAudioValues(int audioManagerSampleRate, int audioManagerFramesPerBurst);
public void startAudio() throws IOException {
Log.i(TAG, "startAudio() called =========================");
int result = startNative();
- if (result < 0) {
- showErrorToast("Start failed with " + result);
- throw new IOException("startNative returned " + result);
+ if (result != 0) {
+ showErrorToast("Start failed with " + result + ", " + StreamConfiguration.convertErrorToText(result));
+ throw new IOException("startNative returned " + result + ", " + StreamConfiguration.convertErrorToText(result));
} else {
+ onStartAllContexts();
for (StreamContext streamContext : mStreamContexts) {
StreamConfigurationView configView = streamContext.configurationView;
if (configView != null) {
@@ -603,26 +698,49 @@ abstract class TestAudioActivity extends Activity {
}
protected void toastPauseError(int result) {
- showErrorToast("Pause failed with " + result);
+ showErrorToast("Pause failed with " + result + ", " + StreamConfiguration.convertErrorToText(result));
}
public void pauseAudio() {
int result = pauseNative();
- if (result < 0) {
+ if (result != 0) {
toastPauseError(result);
} else {
mAudioState = AUDIO_STATE_PAUSED;
updateEnabledWidgets();
+ onStopAllContexts();
+ }
+ }
+
+ public void flushAudio() {
+ int result = flushNative();
+ if (result != 0) {
+ showErrorToast("Flush failed with " + result + ", " + StreamConfiguration.convertErrorToText(result));
+ } else {
+ mAudioState = AUDIO_STATE_FLUSHED;
+ updateEnabledWidgets();
}
}
public void stopAudio() {
int result = stopNative();
- if (result < 0) {
- showErrorToast("Stop failed with " + result);
+ if (result != 0) {
+ showErrorToast("Stop failed with " + result + ", " + StreamConfiguration.convertErrorToText(result));
} else {
mAudioState = AUDIO_STATE_STOPPED;
updateEnabledWidgets();
+ onStopAllContexts();
+ }
+ }
+
+ public void releaseAudio() {
+ int result = releaseNative();
+ if (result != 0) {
+ showErrorToast("Release failed with " + result + ", " + StreamConfiguration.convertErrorToText(result));
+ } else {
+ mAudioState = AUDIO_STATE_RELEASED;
+ updateEnabledWidgets();
+ onStopAllContexts();
}
}
@@ -684,24 +802,6 @@ abstract class TestAudioActivity extends Activity {
myAudioMgr.stopBluetoothSco();
}
- @Override
- public void onRequestPermissionsResult(int requestCode,
- String[] permissions,
- int[] grantResults) {
-
- if (MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE != requestCode) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- return;
- }
- // If request is cancelled, the result arrays are empty.
- if (grantResults.length > 0
- && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- writeTestResult(mTestResults);
- } else {
- showToast("Writing external storage needed for test results.");
- }
- }
-
@NonNull
protected String getCommonTestReport() {
StringBuffer report = new StringBuffer();
@@ -709,8 +809,8 @@ abstract class TestAudioActivity extends Activity {
report.append("build.fingerprint = " + Build.FINGERPRINT + "\n");
try {
PackageInfo pinfo = getPackageManager().getPackageInfo(getPackageName(), 0);
- report.append(String.format("test.version = %s\n", pinfo.versionName));
- report.append(String.format("test.version.code = %d\n", pinfo.versionCode));
+ report.append(String.format(Locale.getDefault(), "test.version = %s\n", pinfo.versionName));
+ report.append(String.format(Locale.getDefault(), "test.version.code = %d\n", pinfo.versionCode));
} catch (PackageManager.NameNotFoundException e) {
}
report.append("time.millis = " + System.currentTimeMillis() + "\n");
@@ -733,48 +833,17 @@ abstract class TestAudioActivity extends Activity {
return report.toString();
}
- void writeTestResultIfPermitted(String resultString) {
- // Here, thisActivity is the current activity
- if (ContextCompat.checkSelfPermission(this,
- Manifest.permission.WRITE_EXTERNAL_STORAGE)
- != PackageManager.PERMISSION_GRANTED) {
- mTestResults = resultString;
- ActivityCompat.requestPermissions(this,
- new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
- MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE);
- } else {
- // Permission has already been granted
- writeTestResult(resultString);
- }
- }
-
- void maybeWriteTestResult(String resultString) {
+ File maybeWriteTestResult(String resultString) {
+ File fileWritten = null;
if (mResultFileName != null) {
- writeTestResultIfPermitted(resultString);
- };
- }
-
- // Run this in a background thread.
- void writeTestResult(String resultString) {
- File resultFile = new File(mResultFileName);
- Writer writer = null;
- try {
- writer = new OutputStreamWriter(new FileOutputStream(resultFile));
- writer.write(resultString);
- } catch (
- IOException e) {
- e.printStackTrace();
- showErrorToast(" writing result file. " + e.getMessage());
- } finally {
- if (writer != null) {
- try {
- writer.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
+ try {
+ fileWritten = mExternalFileWriter.writeStringToExternalFile(resultString, mResultFileName);
+ } catch (IOException e) {
+ e.printStackTrace();
+ showErrorToast(" writing result file. " + e.getMessage());
}
+ mResultFileName = null;
}
-
- mResultFileName = null;
+ return fileWritten;
}
}