1 package com.google.oboe.tests.unittestrunner; 2 3 import androidx.annotation.NonNull; 4 import androidx.appcompat.app.AppCompatActivity; 5 import androidx.core.app.ActivityCompat; 6 7 import android.Manifest; 8 import android.content.pm.PackageManager; 9 import android.content.res.AssetManager; 10 import android.os.Build; 11 import android.os.Bundle; 12 import android.text.method.ScrollingMovementMethod; 13 import android.util.Log; 14 import android.view.View; 15 import android.widget.Button; 16 import android.widget.ScrollView; 17 import android.widget.TextView; 18 import android.widget.Toast; 19 20 import java.io.BufferedReader; 21 import java.io.File; 22 import java.io.FileOutputStream; 23 import java.io.IOException; 24 import java.io.InputStream; 25 import java.io.InputStreamReader; 26 import java.io.OutputStream; 27 28 public class MainActivity extends AppCompatActivity { 29 30 private final String TAG = MainActivity.class.getName(); 31 private static final String TEST_BINARY_FILEANAME = "testOboe"; 32 private static final int APP_PERMISSION_REQUEST = 0; 33 34 private TextView outputText; 35 private ScrollView scrollView; 36 37 @Override onCreate(Bundle savedInstanceState)38 protected void onCreate(Bundle savedInstanceState) { 39 super.onCreate(savedInstanceState); 40 setContentView(R.layout.activity_main); 41 42 outputText = findViewById(R.id.output_view_text); 43 scrollView = findViewById(R.id.scroll_view); 44 runCommand(); 45 } 46 runCommand()47 private void runCommand(){ 48 if (!isRecordPermissionGranted()){ 49 requestPermissions(); 50 } else { 51 52 Thread commandThread = new Thread(new UnitTestCommand()); 53 commandThread.start(); 54 } 55 } 56 executeBinary()57 private String executeBinary() { 58 59 AssetManager assetManager = getAssets(); 60 61 StringBuffer output = new StringBuffer(); 62 String abi = Build.CPU_ABI; 63 String filesDir = getFilesDir().getPath(); 64 String testBinaryPath = abi + "/" + TEST_BINARY_FILEANAME; 65 66 try { 67 InputStream inStream = assetManager.open(testBinaryPath); 68 Log.d(TAG, "Opened " + testBinaryPath); 69 70 // Copy this file to an executable location 71 File outFile = new File(filesDir, TEST_BINARY_FILEANAME); 72 73 OutputStream outStream = new FileOutputStream(outFile); 74 75 byte[] buffer = new byte[1024]; 76 int read; 77 while ((read = inStream.read(buffer)) != -1) { 78 outStream.write(buffer, 0, read); 79 } 80 inStream.close(); 81 outStream.flush(); 82 outStream.close(); 83 Log.d(TAG, "Copied " + testBinaryPath + " to " + filesDir); 84 85 String executablePath = filesDir + "/" + TEST_BINARY_FILEANAME; 86 Log.d(TAG, "Attempting to execute " + executablePath); 87 88 new File(executablePath).setExecutable(true, false); 89 Log.d(TAG, "Setting execute permission on " + executablePath); 90 91 Process process = Runtime.getRuntime().exec(executablePath); 92 93 BufferedReader stdInput = new BufferedReader(new 94 InputStreamReader(process.getInputStream())); 95 96 BufferedReader stdError = new BufferedReader(new 97 InputStreamReader(process.getErrorStream())); 98 99 // read the output from the command 100 String s = null; 101 while ((s = stdInput.readLine()) != null) { 102 Log.d(TAG, s); 103 output.append(s + "\n"); 104 } 105 106 // read any errors from the attempted command 107 while ((s = stdError.readLine()) != null) { 108 Log.e(TAG, "ERROR: " + s); 109 output.append("ERROR: " + s + "\n"); 110 } 111 112 process.waitFor(); 113 Log.d(TAG, "Finished executing binary"); 114 } catch (IOException e){ 115 Log.e(TAG, "Could not execute binary ", e); 116 } catch (InterruptedException e) { 117 Log.e(TAG, "Interrupted", e); 118 } 119 120 return output.toString(); 121 } 122 isRecordPermissionGranted()123 private boolean isRecordPermissionGranted() { 124 return (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == 125 PackageManager.PERMISSION_GRANTED); 126 } 127 requestPermissions()128 private void requestPermissions(){ 129 ActivityCompat.requestPermissions( 130 this, 131 new String[]{Manifest.permission.RECORD_AUDIO}, 132 APP_PERMISSION_REQUEST); 133 } 134 135 @Override onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)136 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 137 @NonNull int[] grantResults) { 138 139 if (APP_PERMISSION_REQUEST != requestCode) { 140 super.onRequestPermissionsResult(requestCode, permissions, grantResults); 141 return; 142 } 143 144 if (grantResults.length != 1 || 145 grantResults[0] != PackageManager.PERMISSION_GRANTED) { 146 147 // User denied the permission, without this we cannot record audio 148 // Show a toast and update the status accordingly 149 outputText.setText(R.string.status_record_audio_denied); 150 Toast.makeText(getApplicationContext(), 151 getString(R.string.need_record_audio_permission), 152 Toast.LENGTH_SHORT) 153 .show(); 154 } else { 155 // Permission was granted, run the command 156 runCommand(); 157 } 158 } 159 160 class UnitTestCommand implements Runnable { 161 162 @Override run()163 public void run() { 164 final String output = executeBinary(); 165 166 runOnUiThread(new Runnable() { 167 @Override 168 public void run() { 169 outputText.setText(output); 170 171 // Scroll to the bottom so we can see the test result 172 scrollView.postDelayed(new Runnable() { 173 @Override 174 public void run() { 175 scrollView.scrollTo(0, outputText.getBottom()); 176 } 177 }, 100); 178 } 179 }); 180 } 181 } 182 } 183