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