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