1 /* 2 * Copyright 2019 The Chromium OS Authors. All rights reserved. 3 * Use of this source code is governed by a BSD-style license that can be 4 * found in the LICENSE file. 5 */ 6 7 package org.chromium.c2.test; 8 9 import android.app.Activity; 10 import android.content.BroadcastReceiver; 11 import android.content.Context; 12 import android.content.Intent; 13 import android.content.IntentFilter; 14 import android.os.AsyncTask; 15 import android.os.Bundle; 16 import android.os.Handler; 17 import android.os.Looper; 18 import android.util.Log; 19 import android.util.Size; 20 import android.view.Surface; 21 import android.view.SurfaceHolder; 22 import android.view.SurfaceView; 23 import android.widget.LinearLayout; 24 25 import java.util.concurrent.CountDownLatch; 26 27 /** Activity responsible for running the native Codec2.0 E2E tests. */ 28 public class E2eTestActivity extends Activity implements SurfaceHolder.Callback { 29 30 public final String TAG = "E2eTestActivity"; 31 32 private SurfaceView mSurfaceView; 33 private Size mSize; 34 35 private boolean mSurfaceCreated = false; 36 private boolean mCanStartTest = false; 37 private Size mExpectedSize; 38 private CountDownLatch mLatch; 39 40 private long mCodecPtr = 0; 41 42 private BroadcastReceiver mCodecConfigReceiver; 43 44 @Override onCreate(Bundle savedInstanceState)45 protected void onCreate(Bundle savedInstanceState) { 46 super.onCreate(savedInstanceState); 47 48 System.loadLibrary("codectest"); 49 50 setContentView(R.layout.main_activity); 51 mSurfaceView = (SurfaceView) findViewById(R.id.surface); 52 53 mSurfaceView.getHolder().addCallback(this); 54 55 mCanStartTest = !getIntent().getBooleanExtra("delay-start", false); 56 57 mCodecConfigReceiver = new CodecReadyReceiver(); 58 registerReceiver( 59 mCodecConfigReceiver, 60 new IntentFilter("org.chromium.c2.test.CHECK_CODEC_CONFIGURED")); 61 } 62 63 @Override onDestroy()64 protected void onDestroy() { 65 super.onDestroy(); 66 unregisterReceiver(mCodecConfigReceiver); 67 // gtest can't reuse a process 68 System.exit(0); 69 } 70 71 @Override surfaceCreated(SurfaceHolder holder)72 public void surfaceCreated(SurfaceHolder holder) { 73 mSurfaceCreated = true; 74 maybeStartTest(); 75 } 76 maybeStartTest()77 private void maybeStartTest() { 78 if (!mSurfaceCreated || !mCanStartTest) { 79 return; 80 } 81 boolean encode = getIntent().getBooleanExtra("do-encode", false); 82 String[] testArgs = 83 getIntent().getStringArrayExtra("test-args") != null 84 ? getIntent().getStringArrayExtra("test-args") 85 : new String[0]; 86 String logFile = getIntent().getStringExtra("log-file"); 87 88 AsyncTask.execute( 89 new Runnable() { 90 @Override 91 public void run() { 92 int res = 93 c2VideoTest( 94 encode, 95 testArgs, 96 testArgs.length, 97 mSurfaceView.getHolder().getSurface(), 98 logFile); 99 Log.i(TAG, "Test returned result code " + res); 100 101 new Handler(Looper.getMainLooper()) 102 .post( 103 new Runnable() { 104 @Override 105 public void run() { 106 finish(); 107 } 108 }); 109 } 110 }); 111 } 112 onCodecReady(long codecPtr)113 void onCodecReady(long codecPtr) { 114 synchronized (this) { 115 mCodecPtr = codecPtr; 116 } 117 } 118 119 @Override onNewIntent(Intent intent)120 public void onNewIntent(Intent intent) { 121 if (intent.getAction().equals("org.chromium.c2.test.START_TEST")) { 122 mCanStartTest = true; 123 maybeStartTest(); 124 return; 125 } 126 127 synchronized (this) { 128 if (mCodecPtr != 0) { 129 stopDecoderLoop(mCodecPtr); 130 } 131 } 132 } 133 134 @Override surfaceChanged(SurfaceHolder holder, int format, int width, int height)135 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 136 synchronized (this) { 137 mSize = new Size(width, height); 138 if (mLatch != null && mExpectedSize.equals(mSize)) { 139 mLatch.countDown(); 140 } 141 } 142 } 143 144 // Configures the SurfaceView with the dimensions of the video the test is currently playing. onSizeChanged(int width, int height)145 void onSizeChanged(int width, int height) { 146 synchronized (this) { 147 mExpectedSize = new Size(width, height); 148 if (mSize != null && mSize.equals(mExpectedSize)) { 149 return; 150 } 151 mLatch = new CountDownLatch(1); 152 } 153 154 new Handler(Looper.getMainLooper()) 155 .post( 156 new Runnable() { 157 @Override 158 public void run() { 159 mSurfaceView.setLayoutParams( 160 new LinearLayout.LayoutParams(width, height)); 161 } 162 }); 163 164 try { 165 mLatch.await(); 166 } catch (Exception e) { 167 } 168 synchronized (this) { 169 mLatch = null; 170 } 171 } 172 173 @Override surfaceDestroyed(SurfaceHolder holder)174 public void surfaceDestroyed(SurfaceHolder holder) { 175 if (!isFinishing()) { 176 throw new RuntimeException("Surface destroyed during test"); 177 } 178 } 179 180 class CodecReadyReceiver extends BroadcastReceiver { 181 @Override onReceive(Context ctx, Intent intent)182 public void onReceive(Context ctx, Intent intent) { 183 boolean ready; 184 synchronized (E2eTestActivity.this) { 185 ready = mCodecPtr != 0; 186 } 187 setResultCode(ready ? 1 : 0); 188 } 189 } 190 c2VideoTest( boolean encode, String[] testArgs, int testArgsCount, Surface surface, String tmpFile)191 public native int c2VideoTest( 192 boolean encode, String[] testArgs, int testArgsCount, Surface surface, String tmpFile); 193 stopDecoderLoop(long decoderPtr)194 public native void stopDecoderLoop(long decoderPtr); 195 } 196