aboutsummaryrefslogtreecommitdiff
path: root/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestRouteDuringCallbackActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestRouteDuringCallbackActivity.java')
-rw-r--r--apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestRouteDuringCallbackActivity.java177
1 files changed, 177 insertions, 0 deletions
diff --git a/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestRouteDuringCallbackActivity.java b/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestRouteDuringCallbackActivity.java
new file mode 100644
index 00000000..4dfce073
--- /dev/null
+++ b/apps/OboeTester/app/src/main/java/com/mobileer/oboetester/TestRouteDuringCallbackActivity.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2023 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.mobileer.oboetester;
+
+import static com.mobileer.oboetester.TestAudioActivity.TAG;
+
+import android.app.Activity;
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.RadioButton;
+import android.widget.TextView;
+
+import java.util.Random;
+
+/**
+ * Try to crash in the native AAudio code by causing a routing change
+ * while playing audio. The buffer may get deleted while we are writing to it!
+ * See b/274815060
+ */
+public class TestRouteDuringCallbackActivity extends Activity {
+
+ private TextView mStatusView;
+ private MyStreamSniffer mStreamSniffer;
+ private AudioManager mAudioManager;
+ private RadioButton mOutputButton;
+ private RadioButton mInputButton;
+ private Button mStartButton;
+ private Button mStopButton;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_routing_crash);
+ mStatusView = (TextView) findViewById(R.id.text_callback_status);
+ mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+
+ mStartButton = (Button) findViewById(R.id.button_start_test);
+ mStopButton = (Button) findViewById(R.id.button_stop_test);
+ mOutputButton = (RadioButton) findViewById(R.id.direction_output);
+ mInputButton = (RadioButton) findViewById(R.id.direction_input);
+ setButtonsEnabled(false);
+ }
+
+ public void onStartRoutingTest(View view) {
+ startRoutingTest();
+ }
+
+ public void onStopRoutingTest(View view) {
+ stopRoutingTest();
+ }
+
+ private void setButtonsEnabled(boolean running) {
+ mStartButton.setEnabled(!running);
+ mStopButton.setEnabled(running);
+ mOutputButton.setEnabled(!running);
+ mInputButton.setEnabled(!running);
+ }
+
+ // Change routing while the stream is playing.
+ // Keep trying until we crash.
+ protected class MyStreamSniffer extends Thread {
+ boolean enabled = true;
+ int routingOption = 0;
+ StringBuffer statusBuffer = new StringBuffer();
+ int loopCount;
+
+ @Override
+ public void run() {
+ routingOption = 0;
+ changeRoute(routingOption);
+ int result;
+ Random random = new Random();
+ while (enabled) {
+ loopCount++;
+ if (routingOption == 0) {
+ statusBuffer = new StringBuffer();
+ }
+ try {
+ sleep(100);
+ boolean useInput = mInputButton.isChecked();
+ result = startStream(useInput);
+ sleep(100);
+ log("-------#" + loopCount + ", " + (useInput ? "IN" : "OUT")
+ + "\nstartStream() returned " + result);
+ int sleepTimeMillis = 500 + random.nextInt(500);
+ sleep(sleepTimeMillis);
+ routingOption = (routingOption == 0) ? 1 : 0;
+ log( "changeRoute " + routingOption);
+ changeRoute(routingOption);
+ sleep(50);
+ } catch (InterruptedException e) {
+ } finally {
+ result = stopStream();
+ log("stopStream() returned " + result);
+ }
+ }
+ changeRoute(0);
+ }
+
+ // Log to screen and logcat.
+ private void log(String text) {
+ Log.d(TAG, "RoutingCrash: " + text);
+ statusBuffer.append(text + ", sleep " + getSleepTimeMicros() + " us\n");
+ showStatus(statusBuffer.toString());
+ }
+
+ // Stop the test thread.
+ void finish() {
+ enabled = false;
+ interrupt();
+ try {
+ join(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected void showStatus(final String message) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mStatusView.setText(message);
+ }
+ });
+ }
+
+ private void changeRoute(int option) {
+ mAudioManager.setSpeakerphoneOn(option > 0);
+ }
+
+ private native int startStream(boolean useInput);
+ private native int getSleepTimeMicros();
+ private native int stopStream();
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ stopRoutingTest();
+ }
+
+ private void startRoutingTest() {
+ stopRoutingTest();
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ setButtonsEnabled(true);
+ mStreamSniffer = new MyStreamSniffer();
+ mStreamSniffer.start();
+ }
+
+ private void stopRoutingTest() {
+ if (mStreamSniffer != null) {
+ mStreamSniffer.finish();
+ mStreamSniffer = null;
+ getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ setButtonsEnabled(false);
+ }
+ }
+}