1 /* 2 * Copyright 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.mobileer.oboetester; 18 19 import android.content.Intent; 20 import android.net.Uri; 21 import android.os.Bundle; 22 import android.os.Environment; 23 import android.os.Handler; 24 import android.os.Looper; 25 import android.view.View; 26 import android.widget.RadioButton; 27 import androidx.annotation.NonNull; 28 import androidx.core.content.FileProvider; 29 30 import java.io.File; 31 import java.io.IOException; 32 33 /** 34 * Test Oboe Capture 35 */ 36 37 public class TestInputActivity extends TestAudioActivity { 38 39 protected AudioInputTester mAudioInputTester; 40 // Note that this must match the number of volume bars defined in the layout file. 41 private static final int NUM_VOLUME_BARS = 8; 42 private VolumeBarView[] mVolumeBars = new VolumeBarView[NUM_VOLUME_BARS]; 43 private InputMarginView mInputMarginView; 44 private int mInputMarginBursts = 0; 45 private WorkloadView mWorkloadView; 46 setMinimumFramesBeforeRead(int frames)47 public native void setMinimumFramesBeforeRead(int frames); saveWaveFile(String absolutePath)48 public native int saveWaveFile(String absolutePath); 49 isOutput()50 @Override boolean isOutput() { return false; } 51 52 @Override inflateActivity()53 protected void inflateActivity() { 54 setContentView(R.layout.activity_test_input); 55 56 BufferSizeView bufferSizeView = findViewById(R.id.buffer_size_view); 57 bufferSizeView.setVisibility(View.GONE); 58 } 59 60 @Override onCreate(Bundle savedInstanceState)61 protected void onCreate(Bundle savedInstanceState) { 62 super.onCreate(savedInstanceState); 63 64 mVolumeBars[0] = (VolumeBarView) findViewById(R.id.volumeBar0); 65 mVolumeBars[1] = (VolumeBarView) findViewById(R.id.volumeBar1); 66 mVolumeBars[2] = (VolumeBarView) findViewById(R.id.volumeBar2); 67 mVolumeBars[3] = (VolumeBarView) findViewById(R.id.volumeBar3); 68 mVolumeBars[4] = (VolumeBarView) findViewById(R.id.volumeBar4); 69 mVolumeBars[5] = (VolumeBarView) findViewById(R.id.volumeBar5); 70 mVolumeBars[6] = (VolumeBarView) findViewById(R.id.volumeBar6); 71 mVolumeBars[7] = (VolumeBarView) findViewById(R.id.volumeBar7); 72 73 mInputMarginView = (InputMarginView) findViewById(R.id.input_margin_view); 74 75 updateEnabledWidgets(); 76 77 mAudioInputTester = addAudioInputTester(); 78 79 mWorkloadView = (WorkloadView) findViewById(R.id.workload_view); 80 if (mWorkloadView != null) { 81 mWorkloadView.setWorkloadReceiver((w) -> mAudioInputTester.setWorkload(w)); 82 } 83 84 mCommunicationDeviceView = (CommunicationDeviceView) findViewById(R.id.comm_device_view); 85 } 86 87 @Override getActivityType()88 int getActivityType() { 89 return ACTIVITY_TEST_INPUT; 90 } 91 92 @Override resetConfiguration()93 protected void resetConfiguration() { 94 super.resetConfiguration(); 95 mAudioInputTester.reset(); 96 } 97 98 @Override updateStreamDisplay()99 void updateStreamDisplay() { 100 int numChannels = mAudioInputTester.getCurrentAudioStream().getChannelCount(); 101 if (numChannels > NUM_VOLUME_BARS) { 102 numChannels = NUM_VOLUME_BARS; 103 } 104 for (int i = 0; i < numChannels; i++) { 105 if (mVolumeBars[i] == null) break; 106 double level = mAudioInputTester.getPeakLevel(i); 107 mVolumeBars[i].setAmplitude((float) level); 108 } 109 } 110 resetVolumeBars()111 void resetVolumeBars() { 112 for (int i = 0; i < mVolumeBars.length; i++) { 113 if (mVolumeBars[i] == null) break; 114 mVolumeBars[i].setAmplitude((float) 0.0); 115 } 116 } 117 setMinimumBurstsBeforeRead(int numBursts)118 void setMinimumBurstsBeforeRead(int numBursts) { 119 int framesPerBurst = mAudioInputTester.getCurrentAudioStream().getFramesPerBurst(); 120 if (framesPerBurst > 0) { 121 setMinimumFramesBeforeRead(numBursts * framesPerBurst); 122 } 123 } 124 125 @Override openAudio(View view)126 public void openAudio(View view) { 127 try { 128 openAudio(); 129 } catch (Exception e) { 130 showErrorToast(e.getMessage()); 131 } 132 } 133 134 @Override openAudio()135 public void openAudio() throws IOException { 136 super.openAudio(); 137 setMinimumBurstsBeforeRead(mInputMarginBursts); 138 resetVolumeBars(); 139 } 140 141 @Override stopAudio()142 public void stopAudio() { 143 super.stopAudio(); 144 resetVolumeBars(); 145 } 146 saveWaveFile(File file)147 protected int saveWaveFile(File file) { 148 // Pass filename to native to write WAV file 149 int result = saveWaveFile(file.getAbsolutePath()); 150 if (result < 0) { 151 showErrorToast("Save returned " + result); 152 } else { 153 showToast("Saved " + result + " bytes."); 154 } 155 return result; 156 } 157 getWaveTag()158 String getWaveTag() { 159 return "input"; 160 } 161 162 @NonNull createFileName()163 private File createFileName() { 164 // Get directory and filename 165 File dir = getExternalFilesDir(Environment.DIRECTORY_MUSIC); 166 return new File(dir, "oboe_" + getWaveTag() + "_" + AutomatedTestRunner.getTimestampString() + ".wav"); 167 } 168 shareWaveFile()169 public void shareWaveFile() { 170 // Share WAVE file via GMail, Drive or other method. 171 File file = createFileName(); 172 int result = saveWaveFile(file); 173 if (result > 0) { 174 Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); 175 sharingIntent.setType("audio/wav"); 176 String subjectText = file.getName(); 177 sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subjectText); 178 Uri uri = FileProvider.getUriForFile(this, 179 BuildConfig.APPLICATION_ID + ".provider", 180 file); 181 sharingIntent.putExtra(Intent.EXTRA_STREAM, uri); 182 sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 183 startActivity(Intent.createChooser(sharingIntent, "Share WAV using:")); 184 } 185 } 186 onShareFile(View view)187 public void onShareFile(View view) { 188 shareWaveFile(); 189 } 190 onMarginBoxClicked(View view)191 public void onMarginBoxClicked(View view) { 192 RadioButton radioButton = (RadioButton) view; 193 String text = (String) radioButton.getText(); 194 mInputMarginBursts = Integer.parseInt(text); 195 setMinimumBurstsBeforeRead(mInputMarginBursts); 196 } 197 198 @Override startTestUsingBundle()199 public void startTestUsingBundle() { 200 try { 201 StreamConfiguration requestedInConfig = mAudioInputTester.requestedConfiguration; 202 IntentBasedTestSupport.configureInputStreamFromBundle(mBundleFromIntent, requestedInConfig); 203 204 openAudio(); 205 startAudio(); 206 207 int durationSeconds = IntentBasedTestSupport.getDurationSeconds(mBundleFromIntent); 208 if (durationSeconds > 0) { 209 // Schedule the end of the test. 210 Handler handler = new Handler(Looper.getMainLooper()); // UI thread 211 handler.postDelayed(new Runnable() { 212 @Override 213 public void run() { 214 stopAutomaticTest(); 215 } 216 }, durationSeconds * 1000); 217 } 218 } catch (Exception e) { 219 showErrorToast(e.getMessage()); 220 } finally { 221 mBundleFromIntent = null; 222 } 223 } 224 stopAutomaticTest()225 void stopAutomaticTest() { 226 String report = getCommonTestReport(); 227 stopAudio(); 228 maybeWriteTestResult(report); 229 mTestRunningByIntent = false; 230 } 231 } 232