DO NOT MERGE StagefrightTest: add MediaPlayer ANR test.

Test: this test passes with fixing patch
Bug: 62673844
Change-Id: I583fb66d0f52530dc308ab8286534943f0197982
(cherry picked from commit d1e11e2da486e270cf916fc136e1fdd99fa13c79)
diff --git a/tests/tests/security/res/raw/bug_62673844.mp4 b/tests/tests/security/res/raw/bug_62673844.mp4
new file mode 100644
index 0000000..8b03b94
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_62673844.mp4
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index c70022125..ed4f950 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -69,6 +69,10 @@
      before any existing test methods
      ***********************************************************/
 
+    public void testStagefrightANR_bug_62673844() throws Exception {
+        doStagefrightTestANR(R.raw.bug_62673844);
+    }
+
     public void testStagefright_bug_37079296() throws Exception {
         doStagefrightTest(R.raw.bug_37079296);
     }
@@ -235,6 +239,10 @@
         server.shutdown();
     }
 
+    private void doStagefrightTestANR(final int rid) throws Exception {
+        doStagefrightTestMediaPlayerANR(rid, null);
+    }
+
     private Surface getDummySurface() {
         int[] textures = new int[1];
         GLES20.glGenTextures(1, textures, 0);
@@ -288,6 +296,7 @@
         public void onCompletion(MediaPlayer mp) {
             // preserve error condition, if any
             lock.lock();
+            completed = true;
             condition.signal();
             lock.unlock();
         }
@@ -307,9 +316,19 @@
             return what;
         }
 
+        public boolean waitForErrorOrCompletion() throws InterruptedException {
+            lock.lock();
+            if (condition.awaitNanos(TIMEOUT_NS) <= 0) {
+                Log.d(TAG, "timed out on waiting for error or completion");
+            }
+            lock.unlock();
+            return (what != 0 && what != MediaPlayer.MEDIA_ERROR_SERVER_DIED) || completed;
+        }
+
         ReentrantLock lock = new ReentrantLock();
         Condition condition = lock.newCondition();
         int what;
+        boolean completed = false;
     }
 
     class LooperThread extends Thread {
@@ -638,4 +657,50 @@
         thr.stopLooper();
         thr.join();
     }
+
+    private void doStagefrightTestMediaPlayerANR(final int rid, final String uri) throws Exception {
+        String name = uri != null ? uri :
+            getInstrumentation().getContext().getResources().getResourceEntryName(rid);
+        Log.i(TAG, "start mediaplayerANR test for: " + name);
+
+        final MediaPlayerCrashListener mpl = new MediaPlayerCrashListener();
+
+        LooperThread t = new LooperThread(new Runnable() {
+            @Override
+            public void run() {
+                MediaPlayer mp = new MediaPlayer();
+                mp.setOnErrorListener(mpl);
+                mp.setOnPreparedListener(mpl);
+                mp.setOnCompletionListener(mpl);
+                Surface surface = getDummySurface();
+                mp.setSurface(surface);
+                AssetFileDescriptor fd = null;
+                try {
+                    if (uri == null) {
+                        fd = getInstrumentation().getContext().getResources()
+                                .openRawResourceFd(rid);
+
+                        mp.setDataSource(fd.getFileDescriptor(),
+                                fd.getStartOffset(),
+                                fd.getLength());
+                    } else {
+                        mp.setDataSource(uri);
+                    }
+                    mp.prepareAsync();
+                } catch (Exception e) {
+                } finally {
+                    closeQuietly(fd);
+                }
+
+                Looper.loop();
+                mp.release();
+            }
+        });
+
+        t.start();
+        String cve = name.replace("_", "-").toUpperCase();
+        assertTrue("Device *IS* vulnerable to " + cve, mpl.waitForErrorOrCompletion());
+        t.stopLooper();
+        t.join(); // wait for thread to exit so we're sure the player was released
+    }
 }