security: catch exceptions in StagefrightTest

Not all exceptions from MediaCodec indicate security vulnerabilities.
Also fix cleanup of MediaPlayer and MediaCodec tests.

Bug: 27902454
Change-Id: Ica5acb2ee44787258f36f0cb600a667312e77ba8
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 8073672..6f34498 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -242,10 +242,28 @@
 
         final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener();
 
-        Thread t = new Thread(new Runnable() {
+        class LooperThread extends Thread {
+            private Looper mLooper;
+
+            LooperThread(Runnable runner) {
+                super(runner);
+            }
+
             @Override
             public void run() {
                 Looper.prepare();
+                mLooper = Looper.myLooper();
+                super.run();
+            }
+
+            public void stopLooper() {
+                mLooper.quitSafely();
+            }
+        }
+
+        LooperThread t = new LooperThread(new Runnable() {
+            @Override
+            public void run() {
 
                 MediaPlayer mp = new MediaPlayer();
                 mp.setOnErrorListener(mpcl);
@@ -274,7 +292,7 @@
         String cve = name.replace("_", "-").toUpperCase();
         assertFalse("Device *IS* vulnerable to " + cve,
                     mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED);
-        t.interrupt();
+        t.stopLooper();
     }
 
     private void doStagefrightTestMediaCodec(final int rid) throws Exception {
@@ -321,34 +339,46 @@
                 codec.configure(format, surface, null, 0);
                 codec.start();
                 MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
-                while (true) {
-                    int flags = ex.getSampleFlags();
-                    long time = ex.getSampleTime();
-                    int bufidx = codec.dequeueInputBuffer(5000);
-                    if (bufidx >= 0) {
-                        int n = ex.readSampleData(codec.getInputBuffer(bufidx), 0);
-                        if (n < 0) {
-                            flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
-                            time = 0;
-                            n = 0;
+                try {
+                    while (true) {
+                        int flags = ex.getSampleFlags();
+                        long time = ex.getSampleTime();
+                        int bufidx = codec.dequeueInputBuffer(5000);
+                        if (bufidx >= 0) {
+                            int n = ex.readSampleData(codec.getInputBuffer(bufidx), 0);
+                            if (n < 0) {
+                                flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+                                time = 0;
+                                n = 0;
+                            }
+                            codec.queueInputBuffer(bufidx, 0, n, time, flags);
+                            ex.advance();
                         }
-                        codec.queueInputBuffer(bufidx, 0, n, time, flags);
-                        ex.advance();
+                        int status = codec.dequeueOutputBuffer(info, 5000);
+                        if (status >= 0) {
+                            if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                                break;
+                            }
+                            if (info.presentationTimeUs > TIMEOUT_NS / 1000) {
+                                Log.d(TAG, "stopping after 10 seconds worth of data");
+                                break;
+                            }
+                            codec.releaseOutputBuffer(status, true);
+                        }
                     }
-                    int status = codec.dequeueOutputBuffer(info, 5000);
-                    if (status >= 0) {
-                        if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
-                            break;
-                        }
-                        if (info.presentationTimeUs > TIMEOUT_NS / 1000) {
-                            Log.d(TAG, "stopping after 10 seconds worth of data");
-                            break;
-                        }
-                        codec.releaseOutputBuffer(status, true);
+                } catch (MediaCodec.CodecException ce) {
+                    if (ce.getErrorCode() == MediaCodec.CodecException.ERROR_RECLAIMED) {
+                        // This indicates that the remote service is dead, suggesting a crash.
+                        throw new RuntimeException(ce);
                     }
+                    // Other errors ignored.
+                } catch (IllegalStateException ise) {
+                    // Other errors ignored.
+                } finally {
+                    codec.release();
                 }
-                codec.release();
             }
         }
+        ex.release();
     }
 }