1 /* 2 * Copyright 2018 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.Manifest; 20 import android.content.pm.PackageInfo; 21 import android.content.pm.PackageManager; 22 import android.os.Build; 23 import android.os.Bundle; 24 import android.widget.Toast; 25 import androidx.annotation.NonNull; 26 import androidx.core.app.ActivityCompat; 27 import androidx.core.content.ContextCompat; 28 29 import java.io.File; 30 import java.io.FileOutputStream; 31 import java.io.IOException; 32 import java.io.OutputStreamWriter; 33 import java.io.Writer; 34 import java.util.Locale; 35 36 /** 37 * Activity to measure latency on a full duplex stream. 38 */ 39 public class AnalyzerActivity extends TestInputActivity { 40 41 AudioOutputTester mAudioOutTester; 42 protected BufferSizeView mBufferSizeView; 43 protected AutomatedTestRunner mAutomatedTestRunner; 44 45 // Note that these string must match the enum result_code in LatencyAnalyzer.h resultCodeToString(int resultCode)46 String resultCodeToString(int resultCode) { 47 switch (resultCode) { 48 case 0: 49 return "OK"; 50 case -99: 51 return "ERROR_NOISY"; 52 case -98: 53 return "ERROR_VOLUME_TOO_LOW"; 54 case -97: 55 return "ERROR_VOLUME_TOO_HIGH"; 56 case -96: 57 return "ERROR_CONFIDENCE"; 58 case -95: 59 return "ERROR_INVALID_STATE"; 60 case -94: 61 return "ERROR_GLITCHES"; 62 case -93: 63 return "ERROR_NO_LOCK"; 64 default: 65 return "UNKNOWN"; 66 } 67 } 68 getAnalyzerState()69 public native int getAnalyzerState(); isAnalyzerDone()70 public native boolean isAnalyzerDone(); getMeasuredResult()71 public native int getMeasuredResult(); getResetCount()72 public native int getResetCount(); 73 74 @Override 75 @NonNull getCommonTestReport()76 protected String getCommonTestReport() { 77 StringBuffer report = new StringBuffer(); 78 // Add some extra information for the remote tester. 79 report.append("build.fingerprint = " + Build.FINGERPRINT + "\n"); 80 try { 81 PackageInfo pinfo = getPackageManager().getPackageInfo(getPackageName(), 0); 82 report.append(String.format(Locale.getDefault(), "test.version = %s\n", pinfo.versionName)); 83 report.append(String.format(Locale.getDefault(), "test.version.code = %d\n", pinfo.versionCode)); 84 } catch (PackageManager.NameNotFoundException e) { 85 } 86 report.append("time.millis = " + System.currentTimeMillis() + "\n"); 87 88 // INPUT 89 report.append(mAudioInputTester.actualConfiguration.dump()); 90 AudioStreamBase inStream = mAudioInputTester.getCurrentAudioStream(); 91 report.append(String.format(Locale.getDefault(), "in.burst.frames = %d\n", inStream.getFramesPerBurst())); 92 report.append(String.format(Locale.getDefault(), "in.xruns = %d\n", inStream.getXRunCount())); 93 94 // OUTPUT 95 report.append(mAudioOutTester.actualConfiguration.dump()); 96 AudioStreamBase outStream = mAudioOutTester.getCurrentAudioStream(); 97 report.append(String.format(Locale.getDefault(), "out.burst.frames = %d\n", outStream.getFramesPerBurst())); 98 int bufferSize = outStream.getBufferSizeInFrames(); 99 report.append(String.format(Locale.getDefault(), "out.buffer.size.frames = %d\n", bufferSize)); 100 int bufferCapacity = outStream.getBufferCapacityInFrames(); 101 report.append(String.format(Locale.getDefault(), "out.buffer.capacity.frames = %d\n", bufferCapacity)); 102 report.append(String.format(Locale.getDefault(), "out.xruns = %d\n", outStream.getXRunCount())); 103 104 return report.toString(); 105 } 106 107 @Override onCreate(Bundle savedInstanceState)108 protected void onCreate(Bundle savedInstanceState) { 109 super.onCreate(savedInstanceState); 110 mAudioOutTester = addAudioOutputTester(); 111 mBufferSizeView = (BufferSizeView) findViewById(R.id.buffer_size_view); 112 } 113 114 @Override resetConfiguration()115 protected void resetConfiguration() { 116 super.resetConfiguration(); 117 mAudioOutTester.reset(); 118 119 StreamContext streamContext = getFirstInputStreamContext(); 120 if (streamContext != null) { 121 if (streamContext.configurationView != null) { 122 streamContext.configurationView.setFormat(StreamConfiguration.AUDIO_FORMAT_PCM_FLOAT); 123 streamContext.configurationView.setFormatConversionAllowed(true); 124 } 125 } 126 streamContext = getFirstOutputStreamContext(); 127 if (streamContext != null) { 128 if (streamContext.configurationView != null) { 129 streamContext.configurationView.setFormat(StreamConfiguration.AUDIO_FORMAT_PCM_FLOAT); 130 streamContext.configurationView.setFormatConversionAllowed(true); 131 } 132 } 133 } 134 135 @Override openAudio()136 public void openAudio() throws IOException { 137 super.openAudio(); 138 if (mBufferSizeView != null) { 139 mBufferSizeView.onStreamOpened((OboeAudioStream) mAudioOutTester.getCurrentAudioStream()); 140 } 141 } 142 onStreamClosed()143 public void onStreamClosed() { 144 Toast.makeText(getApplicationContext(), 145 "Stream was closed or disconnected!", 146 Toast.LENGTH_SHORT) 147 .show(); 148 stopAudioTest(); 149 } 150 stopAudioTest()151 public void stopAudioTest() { 152 } 153 154 @Override saveIntentLog()155 public void saveIntentLog() { 156 if (mTestRunningByIntent) { 157 String report = mAutomatedTestRunner.getFullLogs(); 158 maybeWriteTestResult(report); 159 mTestRunningByIntent = false; 160 mBundleFromIntent = null; 161 } 162 } 163 164 } 165