Merge "Add TV app tests to CtsVerifier DO NOT MERGE" into lmp-sprout-dev
diff --git a/libs/deviceutil/src/android/cts/util/MediaUtils.java b/libs/deviceutil/src/android/cts/util/MediaUtils.java
new file mode 100644
index 0000000..eab4808
--- /dev/null
+++ b/libs/deviceutil/src/android/cts/util/MediaUtils.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.cts.util;
+
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.net.Uri;
+import java.lang.reflect.Method;
+import static java.lang.reflect.Modifier.isPublic;
+import static java.lang.reflect.Modifier.isStatic;
+import java.util.Map;
+import android.util.Log;
+
+import java.io.IOException;
+
+public class MediaUtils {
+    private static final String TAG = "MediaUtils";
+
+    private static final int ALL_AV_TRACKS = -1;
+
+    private static final MediaCodecList sMCL = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+
+
+    /**
+     * Finds test name (heuristically) and prints out standard skip message.
+     *
+     * Since it uses heuristics, this method has only been verified for media
+     * tests. This centralizes the way to signal a skipped test.
+     */
+    public static void skipTest(String tag, String reason) {
+        int bestScore = -1;
+        String testName = "test???";
+        Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
+        for (Map.Entry<Thread, StackTraceElement[]> entry : traces.entrySet()) {
+            StackTraceElement[] stack = entry.getValue();
+            for (int index = 0; index < stack.length; ++index) {
+                // method name must start with "test"
+                String methodName = stack[index].getMethodName();
+                if (!methodName.startsWith("test")) {
+                    continue;
+                }
+
+                int score = 0;
+                // see if there is a public non-static void method that takes no argument
+                Class<?> clazz;
+                try {
+                    clazz = Class.forName(stack[index].getClassName());
+                    ++score;
+                    for (final Method method : clazz.getDeclaredMethods()) {
+                        if (method.getName().equals(methodName)
+                                && isPublic(method.getModifiers())
+                                && !isStatic(method.getModifiers())
+                                && method.getParameterTypes().length == 0
+                                && method.getReturnType().equals(Void.TYPE)) {
+                            ++score;
+                            break;
+                        }
+                    }
+                    if (score == 1) {
+                        // if we could read the class, but method is not public void, it is
+                        // not a candidate
+                        continue;
+                    }
+                } catch (ClassNotFoundException e) {
+                }
+
+                // even if we cannot verify the method signature, there are signals in the stack
+
+                // usually test method is invoked by reflection
+                int depth = 1;
+                while (index + depth < stack.length
+                        && stack[index + depth].getMethodName().equals("invoke")
+                        && stack[index + depth].getClassName().equals(
+                                "java.lang.reflect.Method")) {
+                    ++depth;
+                }
+                if (depth > 1) {
+                    ++score;
+                    // and usually test method is run by runMethod method in android.test package
+                    if (index + depth < stack.length) {
+                        if (stack[index + depth].getClassName().startsWith("android.test.")) {
+                            ++score;
+                        }
+                        if (stack[index + depth].getMethodName().equals("runMethod")) {
+                            ++score;
+                        }
+                    }
+                }
+
+                if (score > bestScore) {
+                    bestScore = score;
+                    testName = methodName;
+                }
+            }
+        }
+
+        Log.i(tag, "SKIPPING " + testName + "(): " + reason);
+    }
+
+    /**
+     * Finds test name (heuristically) and prints out standard skip message.
+     *
+     * Since it uses heuristics, this method has only been verified for media
+     * tests.  This centralizes the way to signal a skipped test.
+     */
+    public static void skipTest(String reason) {
+        skipTest(TAG, reason);
+    }
+
+    public static boolean check(boolean result, String message) {
+        if (!result) {
+            skipTest(message);
+        }
+        return result;
+    }
+
+    public static boolean canDecode(MediaFormat format) {
+        if (sMCL.findDecoderForFormat(format) == null) {
+            Log.i(TAG, "no decoder for " + format);
+            return false;
+        }
+        return true;
+    }
+
+    public static boolean hasCodecForTrack(MediaExtractor ex, int track) {
+        int count = ex.getTrackCount();
+        if (track < 0 || track >= count) {
+            throw new IndexOutOfBoundsException(track + " not in [0.." + (count - 1) + "]");
+        }
+        return canDecode(ex.getTrackFormat(track));
+    }
+
+    /**
+     * return true iff all audio and video tracks are supported
+     */
+    public static boolean hasCodecsForMedia(MediaExtractor ex) {
+        for (int i = 0; i < ex.getTrackCount(); ++i) {
+            MediaFormat format = ex.getTrackFormat(i);
+            // only check for audio and video codecs
+            String mime = format.getString(MediaFormat.KEY_MIME).toLowerCase();
+            if (!mime.startsWith("audio/") && !mime.startsWith("video/")) {
+                continue;
+            }
+            if (!canDecode(format)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * return true iff any track starting with mimePrefix is supported
+     */
+    public static boolean hasCodecForMediaAndDomain(MediaExtractor ex, String mimePrefix) {
+        mimePrefix = mimePrefix.toLowerCase();
+        for (int i = 0; i < ex.getTrackCount(); ++i) {
+            MediaFormat format = ex.getTrackFormat(i);
+            String mime = format.getString(MediaFormat.KEY_MIME);
+            if (mime.toLowerCase().startsWith(mimePrefix)) {
+                if (canDecode(format)) {
+                    return true;
+                }
+                Log.i(TAG, "no decoder for " + format);
+            }
+        }
+        return false;
+    }
+
+    private static boolean hasCodecsForResourceCombo(
+            Context context, int resourceId, int track, String mimePrefix) {
+        try {
+            AssetFileDescriptor afd = null;
+            MediaExtractor ex = null;
+            try {
+                afd = context.getResources().openRawResourceFd(resourceId);
+                ex = new MediaExtractor();
+                ex.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+                if (mimePrefix != null) {
+                    return hasCodecForMediaAndDomain(ex, mimePrefix);
+                } else if (track == ALL_AV_TRACKS) {
+                    return hasCodecsForMedia(ex);
+                } else {
+                    return hasCodecForTrack(ex, track);
+                }
+            } finally {
+                if (ex != null) {
+                    ex.release();
+                }
+                if (afd != null) {
+                    afd.close();
+                }
+            }
+        } catch (IOException e) {
+            Log.i(TAG, "could not open resource");
+        }
+        return false;
+    }
+
+    /**
+     * return true iff all audio and video tracks are supported
+     */
+    public static boolean hasCodecsForResource(Context context, int resourceId) {
+        return hasCodecsForResourceCombo(context, resourceId, ALL_AV_TRACKS, null /* mimePrefix */);
+    }
+
+    public static boolean checkCodecsForResource(Context context, int resourceId) {
+        return check(hasCodecsForResource(context, resourceId), "no decoder found");
+    }
+
+    /**
+     * return true iff track is supported.
+     */
+    public static boolean hasCodecForResource(Context context, int resourceId, int track) {
+        return hasCodecsForResourceCombo(context, resourceId, track, null /* mimePrefix */);
+    }
+
+    public static boolean checkCodecForResource(Context context, int resourceId, int track) {
+        return check(hasCodecForResource(context, resourceId, track), "no decoder found");
+    }
+
+    /**
+     * return true iff any track starting with mimePrefix is supported
+     */
+    public static boolean hasCodecForResourceAndDomain(
+            Context context, int resourceId, String mimePrefix) {
+        return hasCodecsForResourceCombo(context, resourceId, ALL_AV_TRACKS, mimePrefix);
+    }
+
+    /**
+     * return true iff all audio and video tracks are supported
+     */
+    public static boolean hasCodecsForPath(Context context, String path) {
+        MediaExtractor ex = null;
+        try {
+            ex = new MediaExtractor();
+            Uri uri = Uri.parse(path);
+            String scheme = uri.getScheme();
+            if (scheme == null) { // file
+                ex.setDataSource(path);
+            } else if (scheme.equalsIgnoreCase("file")) {
+                ex.setDataSource(uri.getPath());
+            } else {
+                ex.setDataSource(context, uri, null);
+            }
+            return hasCodecsForMedia(ex);
+        } catch (IOException e) {
+            Log.i(TAG, "could not open path " + path);
+        } finally {
+            if (ex != null) {
+                ex.release();
+            }
+        }
+        return false;
+    }
+
+    public static boolean checkCodecsForPath(Context context, String path) {
+        return check(hasCodecsForPath(context, path), "no decoder found");
+    }
+
+    private static boolean hasCodecForMime(boolean encoder, String mime) {
+        for (MediaCodecInfo info : sMCL.getCodecInfos()) {
+            if (encoder != info.isEncoder()) {
+                continue;
+            }
+
+            for (String type : info.getSupportedTypes()) {
+                if (type.equalsIgnoreCase(mime)) {
+                    Log.i(TAG, "found codec " + info.getName() + " for mime " + mime);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static boolean hasCodecForMimes(boolean encoder, String[] mimes) {
+        for (String mime : mimes) {
+            if (!hasCodecForMime(encoder, mime)) {
+                Log.i(TAG, "no " + (encoder ? "encoder" : "decoder") + " for mime " + mime);
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    public static boolean hasEncoder(String... mimes) {
+        return hasCodecForMimes(true /* encoder */, mimes);
+    }
+
+    public static boolean hasDecoder(String... mimes) {
+        return hasCodecForMimes(false /* encoder */, mimes);
+    }
+
+    public static boolean checkDecoder(String... mimes) {
+        return check(hasCodecForMimes(false /* encoder */, mimes), "no decoder found");
+    }
+
+    public static boolean checkEncoder(String... mimes) {
+        return check(hasCodecForMimes(true /* encoder */, mimes), "no encoder found");
+    }
+
+    public static boolean canDecodeVideo(String mime, int width, int height, float rate) {
+        MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
+        format.setFloat(MediaFormat.KEY_FRAME_RATE, rate);
+        return canDecode(format);
+    }
+
+    public static boolean checkDecoderForFormat(MediaFormat format) {
+        return check(canDecode(format), "no decoder for " + format);
+    }
+}
diff --git a/suite/cts/deviceTests/videoperf/Android.mk b/suite/cts/deviceTests/videoperf/Android.mk
index cb398a9..cd82dde 100644
--- a/suite/cts/deviceTests/videoperf/Android.mk
+++ b/suite/cts/deviceTests/videoperf/Android.mk
@@ -24,7 +24,7 @@
 
 LOCAL_PACKAGE_NAME := CtsDeviceVideoPerf
 
-LOCAL_SDK_VERSION := 16
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
 
diff --git a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java
index b9edfa4..b7d1d27 100644
--- a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java
+++ b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java
@@ -19,7 +19,9 @@
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecInfo.CodecCapabilities;
 import android.media.MediaCodecInfo.CodecProfileLevel;
+import android.media.MediaCodecInfo.VideoCapabilities;
 import android.media.MediaCodecList;
+import android.media.MediaFormat;
 import android.util.Log;
 
 
@@ -38,21 +40,33 @@
     public boolean mSupportPlanar = false;
 
     private static final String TAG = "CodecInfo";
-    private static final String VIDEO_AVC = "video/avc";
+    private static final String VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
     /**
      * Check if given codec with given (w,h) is supported.
-     * @param mimeType codec type in mime format like "video/avc"
+     * @param mimeType codec type in mime format like MediaFormat.MIMETYPE_VIDEO_AVC
      * @param w video width
      * @param h video height
      * @param isEncoder whether the codec is encoder or decoder
      * @return null if the configuration is not supported.
      */
-    public static CodecInfo getSupportedFormatInfo(String mimeType, int w, int h,
-            boolean isEncoder) {
-        CodecCapabilities cap = getCodecCapability(mimeType, isEncoder);
-        if (cap == null) { // not supported
+    public static CodecInfo getSupportedFormatInfo(
+            String mimeType, int w, int h, boolean isEncoder) {
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        MediaFormat format = MediaFormat.createVideoFormat(mimeType, w, h);
+        String codec = isEncoder
+                ? mcl.findEncoderForFormat(format)
+                : mcl.findDecoderForFormat(format);
+        if (codec == null) { // not supported
             return null;
         }
+        CodecCapabilities cap = null;
+        for (MediaCodecInfo info : mcl.getCodecInfos()) {
+            if (info.getName().equals(codec)) {
+                cap = info.getCapabilitiesForType(mimeType);
+                break;
+            }
+        }
+        VideoCapabilities vidCap = cap.getVideoCapabilities();
         CodecInfo info = new CodecInfo();
         for (int color : cap.colorFormats) {
             if (color == CodecCapabilities.COLOR_FormatYUV420SemiPlanar) {
@@ -70,129 +84,13 @@
         }
 
         if (mimeType.equals(VIDEO_AVC)) {
-            int highestLevel = 0;
-            for (CodecProfileLevel lvl : cap.profileLevels) {
-                if (lvl.level > highestLevel) {
-                    highestLevel = lvl.level;
-                }
-            }
-            Log.i(TAG, "Avc highest level " + Integer.toHexString(highestLevel));
-            int maxW = 0;
-            int maxH = 0;
-            int bitRate = 0;
-            int mbW = (w + 15) / 16; // size in macroblocks
-            int mbH = (h + 15) / 16;
-            int maxMacroblocksPerSecond = 0; // max decoding speed
-            switch(highestLevel) {
-            // Do not support Level 1 to 2.
-            case CodecProfileLevel.AVCLevel1:
-            case CodecProfileLevel.AVCLevel11:
-            case CodecProfileLevel.AVCLevel12:
-            case CodecProfileLevel.AVCLevel13:
-            case CodecProfileLevel.AVCLevel1b:
-            case CodecProfileLevel.AVCLevel2:
-                return null;
-            case CodecProfileLevel.AVCLevel21:
-                maxW = 352;
-                maxH = 576;
-                bitRate = 4000000;
-                maxMacroblocksPerSecond = 19800;
-                break;
-            case CodecProfileLevel.AVCLevel22:
-                maxW = 720;
-                maxH = 480;
-                bitRate = 4000000;
-                maxMacroblocksPerSecond = 20250;
-                break;
-            case CodecProfileLevel.AVCLevel3:
-                maxW = 720;
-                maxH = 480;
-                bitRate = 10000000;
-                maxMacroblocksPerSecond = 40500;
-                break;
-            case CodecProfileLevel.AVCLevel31:
-                maxW = 1280;
-                maxH = 720;
-                bitRate = 14000000;
-                maxMacroblocksPerSecond = 108000;
-                break;
-            case CodecProfileLevel.AVCLevel32:
-                maxW = 1280;
-                maxH = 720;
-                bitRate = 20000000;
-                maxMacroblocksPerSecond = 216000;
-                break;
-            case CodecProfileLevel.AVCLevel4:
-                maxW = 1920;
-                maxH = 1080;
-                bitRate = 20000000;
-                maxMacroblocksPerSecond = 245760;
-                break;
-            case CodecProfileLevel.AVCLevel41:
-                maxW = 1920;
-                maxH = 1080;
-                bitRate = 50000000;
-                maxMacroblocksPerSecond = 245760;
-                break;
-            case CodecProfileLevel.AVCLevel42:
-                maxW = 2048;
-                maxH = 1080;
-                bitRate = 50000000;
-                maxMacroblocksPerSecond = 522240;
-                break;
-            case CodecProfileLevel.AVCLevel5:
-                maxW = 3672;
-                maxH = 1536;
-                bitRate = 135000000;
-                maxMacroblocksPerSecond = 589824;
-                break;
-            case CodecProfileLevel.AVCLevel51:
-            default:
-                maxW = 4096;
-                maxH = 2304;
-                bitRate = 240000000;
-                maxMacroblocksPerSecond = 983040;
-                break;
-            }
-            if ((w > maxW) || (h > maxH)) {
-                Log.i(TAG, "Requested resolution (" + w + "," + h + ") exceeds (" +
-                        maxW + "," + maxH + ")");
-                return null;
-            }
-            info.mFps = maxMacroblocksPerSecond / mbH / mbW;
-            info.mBitRate = bitRate;
-            Log.i(TAG, "AVC Level " + Integer.toHexString(highestLevel) + " bit rate " + bitRate +
-                    " fps " + info.mFps);
+            info.mFps = vidCap.getSupportedFrameRatesFor(w, h).getUpper().intValue();
+            info.mBitRate = vidCap.getBitrateRange().getUpper();
+            Log.i(TAG, "AVC bit rate " + info.mBitRate + " fps " + info.mFps);
         }
         return info;
     }
 
-    /**
-     * Search for given codecName and returns CodecCapabilities if found
-     * @param codecName
-     * @param isEncoder true for encoder, false for decoder
-     * @return null if the codec is not supported
-     */
-    private static CodecCapabilities getCodecCapability(
-            String codecName, boolean isEncoder) {
-        int codecCount = MediaCodecList.getCodecCount();
-        for (int i = 0; i < codecCount; ++i) {
-            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
-            String[] types = info.getSupportedTypes();
-            if (isEncoder != info.isEncoder()) {
-                continue;
-            }
-            for (int j = 0; j < types.length; ++j) {
-                if (types[j].compareTo(codecName) == 0) {
-                    CodecCapabilities cap = info.getCapabilitiesForType(types[j]);
-                    Log.i(TAG, "Use codec " + info.getName());
-                    return cap;
-                }
-            }
-        }
-        return null;
-    }
-
     // for debugging
     private static void printIntArray(String msg, int[] data) {
         StringBuilder builder = new StringBuilder();
diff --git a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
index a009ce2..aacb7a5 100644
--- a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
+++ b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
@@ -18,6 +18,7 @@
 
 import android.graphics.Point;
 import android.media.MediaCodec;
+import android.media.MediaCodecList;
 import android.media.MediaCodecInfo.CodecCapabilities;
 import android.media.MediaFormat;
 import android.util.Log;
@@ -27,6 +28,7 @@
 import com.android.cts.util.ResultUnit;
 import com.android.cts.util.Stat;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.lang.System;
 import java.util.Random;
@@ -49,7 +51,7 @@
     // is not very high.
     private static final long VIDEO_CODEC_WAIT_TIME_US = 5000;
     private static final boolean VERBOSE = false;
-    private static final String VIDEO_AVC = "video/avc";
+    private static final String VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
     private static final int TOTAL_FRAMES = 300;
     private static final int NUMBER_OF_REPEAT = 10;
     // i frame interval for encoder
@@ -130,12 +132,12 @@
      * @param numberRepeat how many times to repeat the encoding / decoding process
      */
     private void doTest(String mimeType, int w, int h, int numberRepeat) throws Exception {
-        CodecInfo infoEnc = CodecInfo.getSupportedFormatInfo(mimeType, w, h, true);
+        CodecInfo infoEnc = CodecInfo.getSupportedFormatInfo(mimeType, w, h, true /* encoder */);
         if (infoEnc == null) {
-            Log.i(TAG, "Codec " + mimeType + "with " + w + "," + h + " not supported");
+            Log.i(TAG, "Encoder " + mimeType + " with " + w + "," + h + " not supported");
             return;
         }
-        CodecInfo infoDec = CodecInfo.getSupportedFormatInfo(mimeType, w, h, false);
+        CodecInfo infoDec = CodecInfo.getSupportedFormatInfo(mimeType, w, h, false /* encoder */);
         assertNotNull(infoDec);
         mVideoWidth = w;
         mVideoHeight = h;
@@ -207,8 +209,11 @@
      * @return time taken in ms to encode the frames. This does not include initialization time.
      */
     private double runEncoder(String mimeType, MediaFormat format, int totalFrames) {
-        MediaCodec codec = MediaCodec.createEncoderByType(mimeType);
+        MediaCodec codec = null;
         try {
+            MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+            String encoderName = mcl.findEncoderForFormat(format);
+            codec = MediaCodec.createByCodecName(encoderName);
             codec.configure(
                     format,
                     null /* surface */,
@@ -216,7 +221,11 @@
                     MediaCodec.CONFIGURE_FLAG_ENCODE);
         } catch (IllegalStateException e) {
             Log.e(TAG, "codec '" + mimeType + "' failed configuration.");
+            codec.release();
             assertTrue("codec '" + mimeType + "' failed configuration.", false);
+        } catch (IOException | NullPointerException e) {
+            Log.i(TAG, "could not find codec for " + format);
+            return Double.NaN;
         }
         codec.start();
         ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
@@ -347,7 +356,15 @@
      * @return returns length-2 array with 0: time for decoding, 1 : rms error of pixels
      */
     private double[] runDecoder(String mimeType, MediaFormat format) {
-        MediaCodec codec = MediaCodec.createDecoderByType(mimeType);
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        String decoderName = mcl.findDecoderForFormat(format);
+        MediaCodec codec = null;
+        try {
+            codec = MediaCodec.createByCodecName(decoderName);
+        } catch (IOException | NullPointerException e) {
+            Log.i(TAG, "could not find codec for " + format);
+            return null;
+        }
         codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
         codec.start();
         ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index 669de2d..52f6075 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -30,6 +30,7 @@
 import android.media.Image;
 import android.media.ImageReader;
 import android.media.MediaCodecList;
+import android.media.MediaFormat;
 import android.media.MediaPlayer;
 import android.media.MediaRecorder;
 import android.os.Environment;
@@ -1050,133 +1051,10 @@
      * by AVC specification for certain level.
      */
     private static boolean isSupportedByAVCEncoder(Size sz, int frameRate) {
-        String mimeType = "video/avc";
-        MediaCodecInfo codecInfo = getEncoderInfo(mimeType);
-        if (codecInfo == null) {
-            return false;
-        }
-        CodecCapabilities cap = codecInfo.getCapabilitiesForType(mimeType);
-        if (cap == null) {
-            return false;
-        }
-
-        int highestLevel = 0;
-        for (CodecProfileLevel lvl : cap.profileLevels) {
-            if (lvl.level > highestLevel) {
-                highestLevel = lvl.level;
-            }
-        }
-        // Don't support anything meaningful for level 1 or 2.
-        if (highestLevel <= CodecProfileLevel.AVCLevel2) {
-            return false;
-        }
-
-        if(VERBOSE) {
-            Log.v(TAG, "The highest level supported by encoder is: " + highestLevel);
-        }
-
-        // Put bitRate here for future use.
-        int maxW, maxH, bitRate;
-        // Max encoding speed.
-        int maxMacroblocksPerSecond = 0;
-        switch(highestLevel) {
-            case CodecProfileLevel.AVCLevel21:
-                maxW = 352;
-                maxH = 576;
-                bitRate = 4000000;
-                maxMacroblocksPerSecond = 19800;
-                break;
-            case CodecProfileLevel.AVCLevel22:
-                maxW = 720;
-                maxH = 480;
-                bitRate = 4000000;
-                maxMacroblocksPerSecond = 20250;
-                break;
-            case CodecProfileLevel.AVCLevel3:
-                maxW = 720;
-                maxH = 480;
-                bitRate = 10000000;
-                maxMacroblocksPerSecond = 40500;
-                break;
-            case CodecProfileLevel.AVCLevel31:
-                maxW = 1280;
-                maxH = 720;
-                bitRate = 14000000;
-                maxMacroblocksPerSecond = 108000;
-                break;
-            case CodecProfileLevel.AVCLevel32:
-                maxW = 1280;
-                maxH = 720;
-                bitRate = 20000000;
-                maxMacroblocksPerSecond = 216000;
-                break;
-            case CodecProfileLevel.AVCLevel4:
-                maxW = 1920;
-                maxH = 1088; // It should be 1088 in terms of AVC capability.
-                bitRate = 20000000;
-                maxMacroblocksPerSecond = 245760;
-                break;
-            case CodecProfileLevel.AVCLevel41:
-                maxW = 1920;
-                maxH = 1088; // It should be 1088 in terms of AVC capability.
-                bitRate = 50000000;
-                maxMacroblocksPerSecond = 245760;
-                break;
-            case CodecProfileLevel.AVCLevel42:
-                maxW = 2048;
-                maxH = 1088; // It should be 1088 in terms of AVC capability.
-                bitRate = 50000000;
-                maxMacroblocksPerSecond = 522240;
-                break;
-            case CodecProfileLevel.AVCLevel5:
-                maxW = 3672;
-                maxH = 1536;
-                bitRate = 135000000;
-                maxMacroblocksPerSecond = 589824;
-                break;
-            case CodecProfileLevel.AVCLevel51:
-            default:
-                maxW = 4096;
-                maxH = 2304;
-                bitRate = 240000000;
-                maxMacroblocksPerSecond = 983040;
-                break;
-        }
-
-        // Check size limit.
-        if (sz.getWidth() > maxW || sz.getHeight() > maxH) {
-            Log.i(TAG, "Requested resolution " + sz.toString() + " exceeds (" +
-                    maxW + "," + maxH + ")");
-            return false;
-        }
-
-        // Check frame rate limit.
-        Size sizeInMb = new Size((sz.getWidth() + 15) / 16, (sz.getHeight() + 15) / 16);
-        int maxFps = maxMacroblocksPerSecond / (sizeInMb.getWidth() * sizeInMb.getHeight());
-        if (frameRate > maxFps) {
-            Log.i(TAG, "Requested frame rate " + frameRate + " exceeds " + maxFps);
-            return false;
-        }
-
-        return true;
-    }
-
-    private static MediaCodecInfo getEncoderInfo(String mimeType) {
-        int numCodecs = MediaCodecList.getCodecCount();
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; j++) {
-                if (types[j].equalsIgnoreCase(mimeType)) {
-                    return codecInfo;
-                }
-            }
-        }
-        return null;
+        MediaFormat format = MediaFormat.createVideoFormat(
+                MediaFormat.MIMETYPE_VIDEO_AVC, sz.getWidth(), sz.getHeight());
+        format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        return mcl.findEncoderForFormat(format) != null;
     }
 }
diff --git a/tests/tests/media/assets/noiseandchirps.ogg b/tests/tests/media/assets/noiseandchirps.ogg
index 1acb643..5c67a88 100644
--- a/tests/tests/media/assets/noiseandchirps.ogg
+++ b/tests/tests/media/assets/noiseandchirps.ogg
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..2c9c3d3
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_60fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_60fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..71150af
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_mp4_h264_8192kbps_60fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..18d53e6
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz.webm
deleted file mode 100644
index c8b9512..0000000
--- a/tests/tests/media/res/raw/video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz.webm
+++ /dev/null
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..b0cd94d
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..bf93ab4
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_60fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_60fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..ae0e0e3
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_webm_vp8_8192kbps_60fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_44100hz.webm
deleted file mode 100644
index 65b436a..0000000
--- a/tests/tests/media/res/raw/video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_44100hz.webm
+++ /dev/null
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..b79e3f6
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..2e769e6
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..35ab7a0
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_60fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_60fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..b837dc2
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_mp4_h264_20480kbps_60fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..631ea04
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..c147461
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_60fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_60fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..10a1a5d
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_webm_vp8_20480kbps_60fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..949b327
--- /dev/null
+++ b/tests/tests/media/res/raw/video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_2840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_2840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..7b663a4
--- /dev/null
+++ b/tests/tests/media/res/raw/video_2840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..12e07ce
--- /dev/null
+++ b/tests/tests/media/res/raw/video_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..b060ca6
--- /dev/null
+++ b/tests/tests/media/res/raw/video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..086f144
--- /dev/null
+++ b/tests/tests/media/res/raw/video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..4404877
--- /dev/null
+++ b/tests/tests/media/res/raw/video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..d6ed441
--- /dev/null
+++ b/tests/tests/media/res/raw/video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz.webm
deleted file mode 100644
index f64aec3..0000000
--- a/tests/tests/media/res/raw/video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz.webm
+++ /dev/null
Binary files differ
diff --git a/tests/tests/media/res/raw/video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..c101291
--- /dev/null
+++ b/tests/tests/media/res/raw/video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz.webm b/tests/tests/media/res/raw/video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_48000hz.webm
similarity index 86%
rename from tests/tests/media/res/raw/video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz.webm
rename to tests/tests/media/res/raw/video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_48000hz.webm
index 59b0c44..b17c5af 100644
--- a/tests/tests/media/res/raw/video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz.webm
+++ b/tests/tests/media/res/raw/video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..60860f1
--- /dev/null
+++ b/tests/tests/media/res/raw/video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_640x360_webm_vp9_1638kbps_30fps_vorbis_stereo_128kbps_48000hz.webm b/tests/tests/media/res/raw/video_640x360_webm_vp9_1638kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
new file mode 100644
index 0000000..418cc91
--- /dev/null
+++ b/tests/tests/media/res/raw/video_640x360_webm_vp9_1638kbps_30fps_vorbis_stereo_128kbps_48000hz.webm
Binary files differ
diff --git a/tests/tests/media/res/raw/video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..055e217
--- /dev/null
+++ b/tests/tests/media/res/raw/video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..87c6897
--- /dev/null
+++ b/tests/tests/media/res/raw/video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
index dbe2c92..3b46360 100644
--- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
+++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
@@ -50,7 +50,7 @@
     public Iterable<Codec> H264(CodecFactory factory) {
         return factory.createCodecList(
                 mContext,
-                "video/avc",
+                MediaFormat.MIMETYPE_VIDEO_AVC,
                 "OMX.google.h264.decoder",
                 R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz,
                 R.raw.video_1280x720_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz);
@@ -59,7 +59,7 @@
     public Iterable<Codec> HEVC(CodecFactory factory) {
         return factory.createCodecList(
                 mContext,
-                "video/hevc",
+                MediaFormat.MIMETYPE_VIDEO_HEVC,
                 "OMX.google.hevc.decoder",
                 R.raw.video_640x360_mp4_hevc_450kbps_30fps_aac_stereo_128kbps_48000hz,
                 R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz);
@@ -68,7 +68,7 @@
     public Iterable<Codec> H263(CodecFactory factory) {
         return factory.createCodecList(
                 mContext,
-                "video/3gpp",
+                MediaFormat.MIMETYPE_VIDEO_H263,
                 "OMX.google.h263.decoder",
                 R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
                 R.raw.video_352x288_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz);
@@ -77,7 +77,7 @@
     public Iterable<Codec> Mpeg4(CodecFactory factory) {
         return factory.createCodecList(
                 mContext,
-                "video/mp4v-es",
+                MediaFormat.MIMETYPE_VIDEO_MPEG4,
                 "OMX.google.mpeg4.decoder",
 
                 R.raw.video_1280x720_mp4_mpeg4_1000kbps_25fps_aac_stereo_128kbps_44100hz,
@@ -87,19 +87,19 @@
     public Iterable<Codec> VP8(CodecFactory factory) {
         return factory.createCodecList(
                 mContext,
-                "video/x-vnd.on2.vp8",
+                MediaFormat.MIMETYPE_VIDEO_VP8,
                 "OMX.google.vp8.decoder",
-                R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
-                R.raw.video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz);
+                R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz,
+                R.raw.video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz);
     }
 
     public Iterable<Codec> VP9(CodecFactory factory) {
         return factory.createCodecList(
                 mContext,
-                "video/x-vnd.on2.vp9",
+                MediaFormat.MIMETYPE_VIDEO_VP9,
                 "OMX.google.vp9.decoder",
-                R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
-                R.raw.video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_44100hz);
+                R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_48000hz,
+                R.raw.video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_48000hz);
     }
 
     CodecFactory ALL = new CodecFactory();
@@ -1288,9 +1288,8 @@
             }
 
             /* enumerate codecs */
-            int codecCount = MediaCodecList.getCodecCount();
-            for (int codecIx = 0; codecIx < codecCount; codecIx++) {
-                MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(codecIx);
+            MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+            for (MediaCodecInfo codecInfo : mcl.getCodecInfos()) {
                 if (codecInfo.isEncoder()) {
                     continue;
                 }
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index e65fb0b..f7fcd0a 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -42,6 +42,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.media.AudioManager;
+import android.content.pm.PackageManager;
 import android.media.MediaPlayer;
 import android.os.Vibrator;
 import android.provider.Settings;
@@ -56,6 +57,7 @@
     private AudioManager mAudioManager;
     private boolean mHasVibrator;
     private boolean mUseFixedVolume;
+    private boolean mIsTelevision;
 
     @Override
     protected void setUp() throws Exception {
@@ -65,6 +67,10 @@
         mHasVibrator = (vibrator != null) && vibrator.hasVibrator();
         mUseFixedVolume = mContext.getResources().getBoolean(
                 Resources.getSystem().getIdentifier("config_useFixedVolume", "bool", "android"));
+        PackageManager packageManager = mContext.getPackageManager();
+        mIsTelevision = packageManager != null
+                && (packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+                        || packageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION));
     }
 
     public void testMicrophoneMute() throws Exception {
@@ -171,7 +177,7 @@
     }
 
     public void testVibrateNotification() throws Exception {
-        if (mUseFixedVolume) {
+        if (mUseFixedVolume || !mHasVibrator) {
             return;
         }
         // VIBRATE_SETTING_ON
@@ -232,7 +238,7 @@
     }
 
     public void testVibrateRinger() throws Exception {
-        if (mUseFixedVolume) {
+        if (mUseFixedVolume || !mHasVibrator) {
             return;
         }
         // VIBRATE_TYPE_RINGER
@@ -298,14 +304,16 @@
         assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
 
         mAudioManager.setRingerMode(RINGER_MODE_SILENT);
-        if (mUseFixedVolume) {
+        // AudioService#setRingerMode() has:
+        // if (isTelevision) return;
+        if (mUseFixedVolume || mIsTelevision) {
             assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
         } else {
             assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode());
         }
 
         mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
-        if (mUseFixedVolume) {
+        if (mUseFixedVolume || mIsTelevision) {
             assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode());
         } else {
             assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT,
diff --git a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
index ff05246..c837d0a 100644
--- a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
+++ b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
@@ -24,6 +24,7 @@
 import android.media.MediaCodecList;
 import android.media.MediaDrm;
 import android.media.MediaDrmException;
+import android.media.MediaFormat;
 import android.media.CamcorderProfile;
 import android.net.Uri;
 import android.os.Environment;
@@ -63,7 +64,7 @@
     private static final int VIDEO_WIDTH = 1280;
     private static final int VIDEO_HEIGHT = 720;
     private static final long PLAY_TIME_MS = TimeUnit.MILLISECONDS.convert(1, TimeUnit.MINUTES);
-    private static final String MIME_VIDEO_AVC = "video/avc";
+    private static final String MIME_VIDEO_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
 
     private static final Uri AUDIO_URL = Uri.parse(
             "http://yt-dash-mse-test.commondatastorage.googleapis.com/media/car_cenc-20120827-8c.mp4");
@@ -303,104 +304,16 @@
             }
         }
 
-        CodecCapabilities cap;
-        int highestProfileLevel = 0;
-        MediaCodecInfo codecInfo;
-
-        for (int i = 0; i < MediaCodecList.getCodecCount(); i++) {
-            codecInfo = MediaCodecList.getCodecInfoAt(i);
-            if (codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; ++j) {
-                if (!types[j].equalsIgnoreCase(MIME_VIDEO_AVC)) {
-                    continue;
-                }
-
-                Log.d(TAG, "codec: " + codecInfo.getName() + "types: " + types[j]);
-                cap = codecInfo.getCapabilitiesForType(types[j]);
-                for (CodecProfileLevel profileLevel : cap.profileLevels) {
-                    Log.i(TAG, "codec " + codecInfo.getName() + ", level " + profileLevel.level);
-                    if (profileLevel.level > highestProfileLevel) {
-                        highestProfileLevel = profileLevel.level;
-                    }
-                }
-                Log.i(TAG, "codec " + codecInfo.getName() + ", highest level " + highestProfileLevel);
-            }
+        MediaFormat format = MediaFormat.createVideoFormat(
+                MIME_VIDEO_AVC, videoWidth, videoHeight);
+        // using secure codec even though it is clear key DRM
+        format.setFeatureEnabled(CodecCapabilities.FEATURE_SecurePlayback, true);
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.ALL_CODECS);
+        if (mcl.findDecoderForFormat(format) == null) {
+            Log.i(TAG, "could not find codec for " + format);
+            return false;
         }
-
-        // AVCLevel and its resolution is taken from http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC
-        switch(highestProfileLevel) {
-        case CodecProfileLevel.AVCLevel1:
-        case CodecProfileLevel.AVCLevel1b:
-            return (videoWidth <= 176 && videoHeight <= 144);
-        case CodecProfileLevel.AVCLevel11:
-        case CodecProfileLevel.AVCLevel12:
-        case CodecProfileLevel.AVCLevel13:
-        case CodecProfileLevel.AVCLevel2:
-            return (videoWidth <= 352 && videoHeight <= 288);
-        case CodecProfileLevel.AVCLevel21:
-            return (videoWidth <= 352 && videoHeight <= 576);
-        case CodecProfileLevel.AVCLevel22:
-        case CodecProfileLevel.AVCLevel3:
-            return (videoWidth <= 720 && videoHeight <= 576);
-        case CodecProfileLevel.AVCLevel31:
-            return (videoWidth <= 1280 && videoHeight <= 720);
-        case CodecProfileLevel.AVCLevel32:
-            return (videoWidth <= 1280 && videoHeight <= 1024);
-        case CodecProfileLevel.AVCLevel4:
-        case CodecProfileLevel.AVCLevel41:
-            // 1280 x 720
-            // 1920 x 1080
-            // 2048 x 1024
-            if (videoWidth <= 1920) {
-                return (videoHeight <= 1080);
-            } else if (videoWidth <= 2048) {
-                return (videoHeight <= 1024);
-            } else {
-                return false;
-            }
-        case CodecProfileLevel.AVCLevel42:
-            return (videoWidth <= 2048 && videoHeight <= 1080);
-        case CodecProfileLevel.AVCLevel5:
-            // 1920 x 1080
-            // 2048 x 1024
-            // 2048 x 1080
-            // 2560 x 1920
-            // 3672 x 1536
-            if (videoWidth <= 1920) {
-                return (videoHeight <= 1080);
-            } else if (videoWidth <= 2048) {
-                return (videoHeight <= 1080);
-            } else if (videoWidth <= 2560) {
-                return (videoHeight <= 1920);
-            } else if (videoWidth <= 3672) {
-                return (videoHeight <= 1536);
-            } else {
-                return false;
-            }
-        case CodecProfileLevel.AVCLevel51:
-        default:  // any future extension will cap at level 5.1
-            // 1920 x 1080
-            // 2560 x 1920
-            // 3840 x 2160
-            // 4096 x 2048
-            // 4096 x 2160
-            // 4096 x 2304
-            if (videoWidth <= 1920) {
-                return (videoHeight <= 1080);
-            } else if (videoWidth <= 2560) {
-                return (videoHeight <= 1920);
-            } else if (videoWidth <= 3840) {
-                return (videoHeight <= 2160);
-            } else if (videoWidth <= 4096) {
-                return (videoHeight <= 2304);
-            } else {
-                return false;
-            }
-        }
+        return true;
     }
 
     /**
@@ -410,7 +323,7 @@
         if (!hasAudioOutput()) {
             return;
         }
-        
+
         MediaDrm drm = startDrm();
         if (null == drm) {
             throw new Error("Failed to create drm.");
diff --git a/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java b/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
index 9ee3118..1ceb025 100644
--- a/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
+++ b/tests/tests/media/src/android/media/cts/DecodeEditEncodeTest.java
@@ -53,7 +53,8 @@
     private static final boolean DEBUG_SAVE_FILE = false;   // save copy of encoded movie
 
     // parameters for the encoder
-    private static final String MIME_TYPE = "video/avc";    // H.264 Advanced Video Coding
+                                                            // H.264 Advanced Video Coding
+    private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
     private static final int FRAME_RATE = 15;               // 15fps
     private static final int IFRAME_INTERVAL = 10;          // 10 seconds between I-frames
 
@@ -806,7 +807,7 @@
 
 
     /**
-     * The elementary stream coming out of the "video/avc" encoder needs to be fed back into
+     * The elementary stream coming out of the encoder needs to be fed back into
      * the decoder one chunk at a time.  If we just wrote the data to a file, we would lose
      * the information about chunk boundaries.  This class stores the encoded data in memory,
      * retaining the chunk organization.
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index d71d38a..c8f2064 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -18,13 +18,15 @@
 
 import com.android.cts.media.R;
 
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
+import android.cts.util.MediaUtils;
 import android.graphics.ImageFormat;
 import android.media.Image;
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.util.Log;
@@ -81,14 +83,15 @@
 
     // TODO: add similar tests for other audio and video formats
     public void testBug11696552() throws Exception {
-        MediaCodec mMediaCodec = MediaCodec.createDecoderByType("audio/mp4a-latm");
-        MediaFormat mFormat = MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 2);
+        MediaCodec mMediaCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_AUDIO_AAC);
+        MediaFormat mFormat = MediaFormat.createAudioFormat(
+                MediaFormat.MIMETYPE_AUDIO_AAC, 48000 /* frequency */, 2 /* channels */);
         mFormat.setByteBuffer("csd-0", ByteBuffer.wrap( new byte [] {0x13, 0x10} ));
         mFormat.setInteger(MediaFormat.KEY_IS_ADTS, 1);
         mMediaCodec.configure(mFormat, null, null, 0);
         mMediaCodec.start();
         int index = mMediaCodec.dequeueInputBuffer(250000);
-        mMediaCodec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM );
+        mMediaCodec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
         MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
         mMediaCodec.dequeueOutputBuffer(info, 250000);
     }
@@ -165,20 +168,25 @@
     }
 
     public void testBFrames() throws Exception {
-        testBFrames(R.raw.video_h264_main_b_frames);
-        testBFrames(R.raw.video_h264_main_b_frames_frag);
+        int testsRun =
+            testBFrames(R.raw.video_h264_main_b_frames) +
+            testBFrames(R.raw.video_h264_main_b_frames_frag);
+        if (testsRun == 0) {
+            MediaUtils.skipTest("no codec found");
+        }
     }
 
-    public void testBFrames(int res) throws Exception {
+    public int testBFrames(int res) throws Exception {
         AssetFileDescriptor fd = mResources.openRawResourceFd(res);
         MediaExtractor ex = new MediaExtractor();
         ex.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
         MediaFormat format = ex.getTrackFormat(0);
         String mime = format.getString(MediaFormat.KEY_MIME);
         assertTrue("not a video track. Wrong test file?", mime.startsWith("video/"));
-        if (!hasCodecForMimeType(mime, false)) {
-            Log.i(TAG, "SKIPPING testBFrames(): Could not find a codec for mimeType: " + mime);
-            return;
+        if (!MediaUtils.canDecode(format)) {
+            ex.release();
+            fd.close();
+            return 0; // skip
         }
         MediaCodec dec = MediaCodec.createDecoderByType(mime);
         Surface s = getActivity().getSurfaceHolder().getSurface();
@@ -222,6 +230,8 @@
         assertTrue("extractor timestamps were ordered, wrong test file?", inputoutoforder);
         dec.release();
         ex.release();
+        fd.close();
+        return 1;
       }
 
     private void testTrackSelection(int resid) throws Exception {
@@ -844,292 +854,312 @@
         return numsamples;
     }
 
-    public void testCodecBasicH264() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "SKIPPING testCodecBasicH264(): No codec found.");
-            return;
+    private void testDecode(int testVideo, int frameNum) throws Exception {
+        if (!MediaUtils.checkCodecForResource(mContext, testVideo, 0 /* track */)) {
+            return; // skip
         }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
-                R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, -1 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 240, frames1);
 
-        int frames2 = countFrames(
-                R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, -1 /* eosframe */, null);
+        // Decode to Surface.
+        Surface s = getActivity().getSurfaceHolder().getSurface();
+        int frames1 = countFrames(testVideo, RESET_MODE_NONE, -1 /* eosframe */, s);
+        assertEquals("wrong number of frames decoded", frameNum, frames1);
+
+        // Decode to buffer.
+        int frames2 = countFrames(testVideo, RESET_MODE_NONE, -1 /* eosframe */, null);
         assertEquals("different number of frames when using Surface", frames1, frames2);
     }
 
+    public void testCodecBasicH264() throws Exception {
+        testDecode(R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz, 240);
+    }
+
     public void testCodecBasicHEVC() throws Exception {
-        if (!hasHEVC(false)) {
-            Log.i(TAG, "SKIPPING testCodecBasicHEVC(): No codec found.");
-            return;
-        }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
-                R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz,
-                RESET_MODE_NONE, -1 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 300, frames1);
-
-        int frames2 = countFrames(
-                R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz,
-                RESET_MODE_NONE, -1 /* eosframe */, null);
-        assertEquals("different number of frames when using Surface", frames1, frames2);
+        testDecode(R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz, 300);
     }
 
     public void testCodecBasicH263() throws Exception {
-        if (!hasH263(false)) {
-            Log.i(TAG, "SKIPPING testCodecBasicH263(): No codec found.");
-            return;
-        }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
-                R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
-                RESET_MODE_NONE, -1 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 122, frames1);
-
-        int frames2 = countFrames(
-                R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
-                RESET_MODE_NONE, -1 /* eosframe */, null);
-        assertEquals("different number of frames when using Surface", frames1, frames2);
+        testDecode(R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz, 122);
     }
 
     public void testCodecBasicMpeg4() throws Exception {
-        if (!hasMpeg4(false)) {
-            Log.i(TAG, "SKIPPING testCodecBasicMpeg4(): No codec found.");
-            return;
-        }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
-                R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, -1 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 249, frames1);
-
-        int frames2 = countFrames(
-                R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, -1 /* eosframe */, null);
-        assertEquals("different number of frames when using Surface", frames1, frames2);
+        testDecode(R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz, 249);
     }
 
     public void testCodecBasicVP8() throws Exception {
-        if (!hasVP8(false)) {
-            Log.i(TAG, "SKIPPING testCodecBasicVP8(): No codec found.");
-            return;
-        }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
-                R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, -1 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 240, frames1);
-
-        int frames2 = countFrames(
-                R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, -1 /* eosframe */, null);
-        assertEquals("different number of frames when using Surface", frames1, frames2);
+        testDecode(R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz, 240);
     }
 
     public void testCodecBasicVP9() throws Exception {
-        if (!hasVP9(false)) {
-            Log.i(TAG, "SKIPPING testCodecBasicVP9(): No codec found.");
-            return;
+        testDecode(R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_48000hz, 240);
+    }
+
+    public void testH264Decode320x240() throws Exception {
+        testDecode(R.raw.video_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+    }
+
+    public void testH264Decode720x480() throws Exception {
+        testDecode(R.raw.video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+    }
+
+    public void testH264Decode30fps1280x720Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 30));
+        }
+    }
+
+    public void testH264Decode30fps1280x720() throws Exception {
+        testDecode(R.raw.video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+    }
+
+    public void testH264Decode60fps1280x720Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 60));
+        }
+    }
+
+    public void testH264Decode60fps1280x720() throws Exception {
+        testDecode(R.raw.video_1280x720_mp4_h264_8192kbps_60fps_aac_stereo_128kbps_44100hz, 596);
+    }
+
+    public void testH264Decode30fps1920x1080Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 30));
+        }
+    }
+
+    public void testH264Decode30fps1920x1080() throws Exception {
+        testDecode(R.raw.video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+    }
+
+    public void testH264Decode60fps1920x1080Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 60));
+        }
+    }
+
+    public void testH264Decode60fps1920x1080() throws Exception {
+        testDecode(R.raw.video_1920x1080_mp4_h264_20480kbps_60fps_aac_stereo_128kbps_44100hz, 596);
+    }
+
+    public void testVP8Decode320x240() throws Exception {
+        testDecode(R.raw.video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_48000hz, 249);
+    }
+
+    public void testVP8Decode640x360() throws Exception {
+        testDecode(R.raw.video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_48000hz, 249);
+    }
+
+    public void testVP8Decode30fps1280x720Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 30));
+        }
+    }
+
+    public void testVP8Decode30fps1280x720() throws Exception {
+        testDecode(R.raw.video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_48000hz, 249);
+    }
+
+    public void testVP8Decode60fps1280x720Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 60));
+        }
+    }
+
+    public void testVP8Decode60fps1280x720() throws Exception {
+        testDecode(R.raw.video_1280x720_webm_vp8_8192kbps_60fps_vorbis_stereo_128kbps_48000hz, 249);
+    }
+
+    public void testVP8Decode30fps1920x1080Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 30));
+        }
+    }
+
+    public void testVP8Decode30fps1920x1080() throws Exception {
+        testDecode(R.raw.video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_48000hz,
+                249);
+    }
+
+    public void testVP8Decode60fps1920x1080Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 60));
+        }
+    }
+
+    public void testVP8Decode60fps1920x1080() throws Exception {
+        testDecode(R.raw.video_1920x1080_webm_vp8_20480kbps_60fps_vorbis_stereo_128kbps_48000hz,
+                249);
+    }
+
+    public void testVP9Decode320x240() throws Exception {
+        testDecode(R.raw.video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_48000hz, 249);
+    }
+
+    public void testVP9Decode640x360() throws Exception {
+        testDecode(R.raw.video_640x360_webm_vp9_1638kbps_30fps_vorbis_stereo_128kbps_48000hz, 249);
+    }
+
+    public void testVP9Decode30fps1280x720Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_VP9, 1280, 720, 30));
+        }
+    }
+
+    public void testVP9Decode30fps1280x720() throws Exception {
+        testDecode(R.raw.video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_48000hz, 249);
+    }
+
+    public void testVP9Decode30fps1920x1080() throws Exception {
+        testDecode(R.raw.video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_48000hz,
+                249);
+    }
+
+    public void testVP9Decode30fps3840x2160() throws Exception {
+        testDecode(R.raw.video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_48000hz,
+                249);
+    }
+
+    public void testHEVCDecode352x288() throws Exception {
+        testDecode(R.raw.video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+    }
+
+    public void testHEVCDecode720x480() throws Exception {
+        testDecode(R.raw.video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+    }
+
+    public void testHEVCDecode30fps1280x720Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_HEVC, 1280, 720, 30));
+        }
+    }
+
+    public void testHEVCDecode30fps1280x720() throws Exception {
+        testDecode(R.raw.video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+    }
+
+    public void testHEVCDecode30fps1920x1080Tv() throws Exception {
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_HEVC, 1920, 1080, 30));
+        }
+    }
+
+    public void testHEVCDecode30fps1920x1080() throws Exception {
+        testDecode(R.raw.video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+    }
+
+    public void testHEVCDecode30fps2840x2160() throws Exception {
+        testDecode(R.raw.video_2840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz, 299);
+    }
+
+    private void testCodecEarlyEOS(int resid, int eosFrame) throws Exception {
+        if (!MediaUtils.checkCodecForResource(mContext, resid, 0 /* track */)) {
+            return; // skip
         }
         Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
-                R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, -1 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 240, frames1);
-
-        int frames2 = countFrames(
-                R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, -1 /* eosframe */, null);
-        assertEquals("different number of frames when using Surface", frames1, frames2);
+        int frames1 = countFrames(resid, RESET_MODE_NONE, eosFrame, s);
+        assertEquals("wrong number of frames decoded", eosFrame, frames1);
     }
 
     public void testCodecEarlyEOSH263() throws Exception {
-        if (!hasH263(false)) {
-            Log.i(TAG, "SKIPPING testCodecEarlyEOSH263(): No codec found.");
-            return;
-        }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
+        testCodecEarlyEOS(
                 R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
-                RESET_MODE_NONE, 64 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 64, frames1);
+                64 /* eosframe */);
     }
 
     public void testCodecEarlyEOSH264() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "SKIPPING testCodecEarlyEOSH264(): No codec found.");
-            return;
-        }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
+        testCodecEarlyEOS(
                 R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, 120 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 120, frames1);
+                120 /* eosframe */);
     }
 
     public void testCodecEarlyEOSHEVC() throws Exception {
-        if (!hasHEVC(false)) {
-            Log.i(TAG, "SKIPPING testCodecEarlyEOSHEVC(): No codec found.");
-            return;
-        }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
+        testCodecEarlyEOS(
                 R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz,
-                RESET_MODE_NONE, 120 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 120, frames1);
+                120 /* eosframe */);
     }
 
     public void testCodecEarlyEOSMpeg4() throws Exception {
-        if (!hasMpeg4(false)) {
-            Log.i(TAG, "SKIPPING testCodecEarlyEOSMpeg4(): No codec found.");
-            return;
-        }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
+        testCodecEarlyEOS(
                 R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, 120 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 120, frames1);
+                120 /* eosframe */);
     }
 
     public void testCodecEarlyEOSVP8() throws Exception {
-        if (!hasVP8(false)) {
-            Log.i(TAG, "SKIPPING testCodecEarlyEOSVP8(): No codec found.");
-            return;
-        }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
-                R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, 120 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 120, frames1);
+        testCodecEarlyEOS(
+                R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz,
+                120 /* eosframe */);
     }
 
     public void testCodecEarlyEOSVP9() throws Exception {
-        if (!hasVP9(false)) {
-            Log.i(TAG, "SKIPPING testCodecEarlyEOSVP9(): No codec found.");
-            return;
-        }
-        Surface s = getActivity().getSurfaceHolder().getSurface();
-        int frames1 = countFrames(
-                R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
-                RESET_MODE_NONE, 120 /* eosframe */, s);
-        assertEquals("wrong number of frames decoded", 120, frames1);
+        testCodecEarlyEOS(
+                R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_48000hz,
+                120 /* eosframe */);
     }
 
     public void testCodecResetsH264WithoutSurface() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsH264WithoutSurface(): No codec found.");
-            return;
-        }
         testCodecResets(
                 R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz, null);
     }
 
     public void testCodecResetsH264WithSurface() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsH264WithSurface(): No codec found.");
-            return;
-        }
         Surface s = getActivity().getSurfaceHolder().getSurface();
         testCodecResets(
                 R.raw.video_480x360_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz, s);
     }
 
     public void testCodecResetsHEVCWithoutSurface() throws Exception {
-        if (!hasHEVC(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsHEVCWithoutSurface(): No codec found.");
-            return;
-        }
         testCodecResets(
                 R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz, null);
     }
 
     public void testCodecResetsHEVCWithSurface() throws Exception {
-        if (!hasHEVC(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsHEVCWithSurface(): No codec found.");
-            return;
-        }
         Surface s = getActivity().getSurfaceHolder().getSurface();
         testCodecResets(
                 R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz, s);
     }
 
     public void testCodecResetsH263WithoutSurface() throws Exception {
-        if (!hasH263(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsH263WithoutSurface(): No codec found.");
-            return;
-        }
         testCodecResets(
                 R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz, null);
     }
 
     public void testCodecResetsH263WithSurface() throws Exception {
-        if (!hasH263(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsH263WithSurface(): No codec found.");
-            return;
-        }
         Surface s = getActivity().getSurfaceHolder().getSurface();
         testCodecResets(
                 R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz, s);
     }
 
     public void testCodecResetsMpeg4WithoutSurface() throws Exception {
-        if (!hasMpeg4(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsMpeg4WithoutSurface(): No codec found.");
-            return;
-        }
         testCodecResets(
                 R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz, null);
     }
 
     public void testCodecResetsMpeg4WithSurface() throws Exception {
-        if (!hasMpeg4(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsMpeg4WithSurface(): No codec found.");
-            return;
-        }
         Surface s = getActivity().getSurfaceHolder().getSurface();
         testCodecResets(
                 R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz, s);
     }
 
     public void testCodecResetsVP8WithoutSurface() throws Exception {
-        if (!hasVP8(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsVP8WithoutSurface(): No codec found.");
-            return;
-        }
         testCodecResets(
-                R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz, null);
+                R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz, null);
     }
 
     public void testCodecResetsVP8WithSurface() throws Exception {
-        if (!hasVP8(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsVP8WithSurface(): No codec found.");
-            return;
-        }
         Surface s = getActivity().getSurfaceHolder().getSurface();
         testCodecResets(
-                R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz, s);
+                R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz, s);
     }
 
     public void testCodecResetsVP9WithoutSurface() throws Exception {
-        if (!hasVP9(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsVP9WithoutSurface(): No codec found.");
-            return;
-        }
         testCodecResets(
-                R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz, null);
+                R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_48000hz, null);
     }
 
     public void testCodecResetsVP9WithSurface() throws Exception {
-        if (!hasVP9(false)) {
-            Log.i(TAG, "SKIPPING testCodecResetsVP9WithSurface(): No codec found.");
-            return;
-        }
         Surface s = getActivity().getSurfaceHolder().getSurface();
         testCodecResets(
-                R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz, s);
+                R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_48000hz, s);
     }
 
 //    public void testCodecResetsOgg() throws Exception {
@@ -1155,6 +1185,10 @@
     }
 
     private void testCodecResets(int video, Surface s) throws Exception {
+        if (!MediaUtils.checkCodecForResource(mContext, video, 0 /* track */)) {
+            return; // skip
+        }
+
         int frames1 = countFrames(video, RESET_MODE_NONE, -1 /* eosframe */, s);
         int frames2 = countFrames(video, RESET_MODE_RECONFIGURE, -1 /* eosframe */, s);
         int frames3 = countFrames(video, RESET_MODE_FLUSH, -1 /* eosframe */, s);
@@ -1234,11 +1268,8 @@
                 testFd.getLength());
         extractor.selectTrack(0); // consider variable looping on track
         MediaFormat format = extractor.getTrackFormat(0);
-        String mimeType = format.getString(MediaFormat.KEY_MIME);
-        if (!hasCodecForMimeType(mimeType, false)) {
-            Log.i(TAG, "SKIPPING testEOSBehavior() for resid=" + movie + " No codec found for "
-                    + "mimeType = " + mimeType);
-            return;
+        if (!MediaUtils.checkDecoderForFormat(format)) {
+            return; // skip
         }
         List<Long> outputChecksums = new ArrayList<Long>();
         List<Long> outputTimestamps = new ArrayList<Long>();
@@ -1544,13 +1575,13 @@
 
     public void testEOSBehaviorVP8() throws Exception {
         // this video has an I frame at 46
-        testEOSBehavior(R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
+        testEOSBehavior(R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz,
                 new int[] {46, 47, 57, 45});
     }
 
     public void testEOSBehaviorVP9() throws Exception {
         // this video has an I frame at 44
-        testEOSBehavior(R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_44100hz,
+        testEOSBehavior(R.raw.video_480x360_webm_vp9_333kbps_25fps_vorbis_stereo_128kbps_48000hz,
                 new int[] {44, 45, 55, 43});
     }
 
diff --git a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
index a480d97..0796515 100644
--- a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
@@ -51,8 +51,9 @@
     private static final String DEBUG_FILE_NAME_BASE = "/sdcard/test.";
 
     // parameters for the encoder
-    private static final String MIME_TYPE_AVC = "video/avc";    // H.264 Advanced Video Coding
-    private static final String MIME_TYPE_VP8 = "video/x-vnd.on2.vp8";
+                                                            // H.264 Advanced Video Coding
+    private static final String MIME_TYPE_AVC = MediaFormat.MIMETYPE_VIDEO_AVC;
+    private static final String MIME_TYPE_VP8 = MediaFormat.MIMETYPE_VIDEO_VP8;
     private static final int FRAME_RATE = 15;               // 15fps
     private static final int IFRAME_INTERVAL = 10;          // 10 seconds between I-frames
 
@@ -297,20 +298,24 @@
         mLargestColorDelta = -1;
 
         try {
-            MediaCodecInfo codecInfo = selectCodec(mMimeType);
-            if (codecInfo == null) {
-                // Don't fail CTS if they don't have an AVC codec (not here, anyway).
-                Log.e(TAG, "Unable to find an appropriate codec for " + mMimeType);
-                return;
-            }
-            if (VERBOSE) Log.d(TAG, "found codec: " + codecInfo.getName());
-
-            int colorFormat = selectColorFormat(codecInfo, mMimeType);
-            if (VERBOSE) Log.d(TAG, "found colorFormat: " + colorFormat);
-
             // We avoid the device-specific limitations on width and height by using values that
             // are multiples of 16, which all tested devices seem to be able to handle.
             MediaFormat format = MediaFormat.createVideoFormat(mMimeType, mWidth, mHeight);
+            MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+            String codec = mcl.findEncoderForFormat(format);
+            if (codec == null) {
+                // Don't fail CTS if they don't have an AVC codec (not here, anyway).
+                Log.e(TAG, "Unable to find an appropriate codec for " + format);
+                return;
+            }
+            if (VERBOSE) Log.d(TAG, "found codec: " + codec);
+
+            // Create a MediaCodec for the desired codec, then configure it as an encoder with
+            // our desired properties.
+            encoder = MediaCodec.createByCodecName(codec);
+
+            int colorFormat = selectColorFormat(encoder.getCodecInfo(), mMimeType);
+            if (VERBOSE) Log.d(TAG, "found colorFormat: " + colorFormat);
 
             // Set some properties.  Failing to specify some of these can cause the MediaCodec
             // configure() call to throw an unhelpful exception.
@@ -320,9 +325,6 @@
             format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
             if (VERBOSE) Log.d(TAG, "format: " + format);
 
-            // Create a MediaCodec for the desired codec, then configure it as an encoder with
-            // our desired properties.
-            encoder = MediaCodec.createByCodecName(codecInfo.getName());
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             encoder.start();
 
@@ -362,19 +364,19 @@
         mLargestColorDelta = -1;
 
         try {
-            MediaCodecInfo codecInfo = selectCodec(mMimeType);
-            if (codecInfo == null) {
-                // Don't fail CTS if they don't have an AVC codec (not here, anyway).
-                Log.e(TAG, "Unable to find an appropriate codec for " + mMimeType);
-                return;
-            }
-            if (VERBOSE) Log.d(TAG, "found codec: " + codecInfo.getName());
-
-            int colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
-
             // We avoid the device-specific limitations on width and height by using values that
             // are multiples of 16, which all tested devices seem to be able to handle.
             MediaFormat format = MediaFormat.createVideoFormat(mMimeType, mWidth, mHeight);
+            MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+            String codec = mcl.findEncoderForFormat(format);
+            if (codec == null) {
+                // Don't fail CTS if they don't have an AVC codec (not here, anyway).
+                Log.e(TAG, "Unable to find an appropriate codec for " + format);
+                return;
+            }
+            if (VERBOSE) Log.d(TAG, "found codec: " + codec);
+
+            int colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
 
             // Set some properties.  Failing to specify some of these can cause the MediaCodec
             // configure() call to throw an unhelpful exception.
@@ -396,7 +398,7 @@
 
             // Create a MediaCodec for the desired codec, then configure it as an encoder with
             // our desired properties.  Request a Surface to use for input.
-            encoder = MediaCodec.createByCodecName(codecInfo.getName());
+            encoder = MediaCodec.createByCodecName(codec);
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             inputSurface = new InputSurface(encoder.createInputSurface());
             encoder.start();
@@ -424,29 +426,6 @@
     }
 
     /**
-     * Returns the first codec capable of encoding the specified MIME type, or null if no
-     * match was found.
-     */
-    private static MediaCodecInfo selectCodec(String mimeType) {
-        int numCodecs = MediaCodecList.getCodecCount();
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; j++) {
-                if (types[j].equalsIgnoreCase(mimeType)) {
-                    return codecInfo;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
      * Returns a color format that is supported by the codec and by this test code.  If no
      * match is found, this throws a test failure -- the set of formats known to the test
      * should be expanded for new platforms.
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
index 89b06dc..ba67a42 100755
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
@@ -67,24 +67,24 @@
 
     // Encoder parameters table, sort by encoder level from high to low.
     private static final int[][] ENCODER_PARAM_TABLE = {
-        // encoder level,                             width,   height,  bitrate,    framerate
-        {MediaCodecInfo.CodecProfileLevel.AVCLevel31, 1280,     720,    14000000,   30},
-        {MediaCodecInfo.CodecProfileLevel.AVCLevel3,   720,     480,    10000000,   30},
-        {MediaCodecInfo.CodecProfileLevel.AVCLevel22,  720,     480,    4000000,    15},
-        {MediaCodecInfo.CodecProfileLevel.AVCLevel21,  352,     576,    4000000,    25},
+        // width,  height,  bitrate,    framerate  /* level */
+        { 1280,     720,    14000000,   30 },  /* AVCLevel31 */
+        {  720,     480,    10000000,   30 },  /* AVCLevel3  */
+        {  720,     480,    4000000,    15 },  /* AVCLevel22 */
+        {  352,     576,    4000000,    25 },  /* AVCLevel21 */
     };
 
     // Virtual display characteristics.  Scaled down from full display size because not all
     // devices can encode at the resolution of their own display.
     private static final String NAME = TAG;
-    private static int sWidth = ENCODER_PARAM_TABLE[ENCODER_PARAM_TABLE.length-1][1];
-    private static int sHeight = ENCODER_PARAM_TABLE[ENCODER_PARAM_TABLE.length-1][2];
+    private static int sWidth = ENCODER_PARAM_TABLE[ENCODER_PARAM_TABLE.length-1][0];
+    private static int sHeight = ENCODER_PARAM_TABLE[ENCODER_PARAM_TABLE.length-1][1];
     private static final int DENSITY = DisplayMetrics.DENSITY_HIGH;
     private static final int UI_TIMEOUT_MS = 2000;
     private static final int UI_RENDER_PAUSE_MS = 400;
 
     // Encoder parameters.  We use the same width/height as the virtual display.
-    private static final String MIME_TYPE = "video/avc";
+    private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
     private static int sFrameRate = 15;               // 15fps
     private static final int IFRAME_INTERVAL = 10;    // 10 seconds between I-frames
     private static int sBitRate = 6000000;            // 6Mbps
@@ -161,56 +161,16 @@
         }
     }
 
-    private static boolean hasCodec(String mimeType) {
-        int numCodecs = MediaCodecList.getCodecCount();
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; j++) {
-                if (types[j].equalsIgnoreCase(mimeType)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     /**
      * Returns true if the encoder level, specified in the ENCODER_PARAM_TABLE, can be supported.
      */
-    private static boolean verifySupportForEncoderLevel(int index) {
-        int numCodecs = MediaCodecList.getCodecCount();
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; j++) {
-
-                if (false == types[j].equalsIgnoreCase(MIME_TYPE)) {
-                    continue;
-                }
-
-                MediaCodecInfo.CodecCapabilities caps = codecInfo.getCapabilitiesForType(types[j]);
-                for (int k = 0; k < caps.profileLevels.length; k++) {
-                    int profile = caps.profileLevels[k].profile;
-                    int level = caps.profileLevels[k].level;
-                    //Log.d(TAG, "[" + k + "] supported profile = " + profile + ", level = " + level);
-                    if (caps.profileLevels[k].level >= ENCODER_PARAM_TABLE[index][0]) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
+    private static boolean verifySupportForEncoderLevel(int i) {
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        MediaFormat format = MediaFormat.createVideoFormat(
+                MIME_TYPE, ENCODER_PARAM_TABLE[i][0], ENCODER_PARAM_TABLE[i][1]);
+        format.setInteger(MediaFormat.KEY_BIT_RATE, ENCODER_PARAM_TABLE[i][2]);
+        format.setInteger(MediaFormat.KEY_FRAME_RATE, ENCODER_PARAM_TABLE[i][3]);
+        return mcl.findEncoderForFormat(format) != null;
     }
 
     /**
@@ -224,10 +184,10 @@
             // Check if we can support it?
             if (verifySupportForEncoderLevel(i)) {
 
-                sWidth = ENCODER_PARAM_TABLE[i][1];
-                sHeight = ENCODER_PARAM_TABLE[i][2];
-                sBitRate = ENCODER_PARAM_TABLE[i][3];
-                sFrameRate = ENCODER_PARAM_TABLE[i][4];
+                sWidth = ENCODER_PARAM_TABLE[i][0];
+                sHeight = ENCODER_PARAM_TABLE[i][1];
+                sBitRate = ENCODER_PARAM_TABLE[i][2];
+                sFrameRate = ENCODER_PARAM_TABLE[i][3];
 
                 Log.d(TAG, "encoder parameters changed: width = " + sWidth + ", height = " + sHeight
                     + ", bitrate = " + sBitRate + ", framerate = " + sFrameRate);
@@ -245,11 +205,6 @@
         OutputSurface outputSurface = null;
         VirtualDisplay virtualDisplay = null;
 
-        // Don't run the test of the codec isn't present.
-        if (!hasCodec(MIME_TYPE)) {
-            return;
-        }
-
         try {
             // Encoded video resolution matches virtual display.
             MediaFormat encoderFormat = MediaFormat.createVideoFormat(MIME_TYPE, sWidth, sHeight);
@@ -259,7 +214,15 @@
             encoderFormat.setInteger(MediaFormat.KEY_FRAME_RATE, sFrameRate);
             encoderFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
 
-            encoder = MediaCodec.createEncoderByType(MIME_TYPE);
+            MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+            String codec = mcl.findEncoderForFormat(encoderFormat);
+            if (codec == null) {
+                // Don't run the test if the codec isn't present.
+                Log.i(TAG, "SKIPPING test: no support for " + encoderFormat);
+                return;
+            }
+
+            encoder = MediaCodec.createByCodecName(codec);
             encoder.configure(encoderFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             Surface inputSurface = encoder.createInputSurface();
             encoder.start();
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
index 9c99c2d..89d6efa 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
@@ -46,7 +46,7 @@
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.Pair;
+import android.util.Size;
 import android.view.Display;
 import android.view.Surface;
 import android.view.TextureView;
@@ -79,7 +79,7 @@
 public class EncodeVirtualDisplayWithCompositionTest extends AndroidTestCase {
     private static final String TAG = "EncodeVirtualDisplayWithCompositionTest";
     private static final boolean DBG = true;
-    private static final String MIME_TYPE = "video/avc";
+    private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
 
     private static final long DEFAULT_WAIT_TIMEOUT_MS = 3000;
     private static final long DEFAULT_WAIT_TIMEOUT_US = 3000000;
@@ -92,6 +92,8 @@
     private static final int BITRATE_1080p = 20000000;
     private static final int BITRATE_720p = 14000000;
     private static final int BITRATE_800x480 = 14000000;
+    private static final int BITRATE_DEFAULT = 10000000;
+
     private static final int IFRAME_INTERVAL = 10;
 
     private static final int MAX_NUM_WINDOWS = 3;
@@ -138,79 +140,59 @@
 
     public void testRendering800x480Locally() throws Throwable {
         Log.i(TAG, "testRendering800x480Locally");
-        Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
-        if (maxRes == null) {
-            Log.i(TAG, "SKIPPING testRendering800x480Locally(): codec not supported");
-            return;
-        }
-        if (maxRes.first >= 800 && maxRes.second >= 480) {
+        if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
             runTestRenderingInSeparateThread(800, 480, false, false);
         } else {
-            Log.w(TAG, "This H/W does not support 800x480");
+            Log.i(TAG, "SKIPPING testRendering800x480Locally(): codec not supported");
         }
     }
 
     public void testRenderingMaxResolutionLocally() throws Throwable {
         Log.i(TAG, "testRenderingMaxResolutionLocally");
-        Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
+        Size maxRes = checkMaxConcurrentEncodingDecodingResolution();
         if (maxRes == null) {
             Log.i(TAG, "SKIPPING testRenderingMaxResolutionLocally(): codec not supported");
-            return;
+        } else {
+            Log.w(TAG, "Trying resolution " + maxRes);
+            runTestRenderingInSeparateThread(maxRes.getWidth(), maxRes.getHeight(), false, false);
         }
-        Log.w(TAG, "Trying resolution w:" + maxRes.first + " h:" + maxRes.second);
-        runTestRenderingInSeparateThread(maxRes.first, maxRes.second, false, false);
     }
 
     public void testRendering800x480Remotely() throws Throwable {
         Log.i(TAG, "testRendering800x480Remotely");
-        Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
-        if (maxRes == null) {
-            Log.i(TAG, "SKIPPING testRendering800x480Remotely(): codec not supported");
-            return;
-        }
-        if (maxRes.first >= 800 && maxRes.second >= 480) {
+        if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
             runTestRenderingInSeparateThread(800, 480, true, false);
         } else {
-            Log.w(TAG, "This H/W does not support 800x480");
+            Log.i(TAG, "SKIPPING testRendering800x480Remotely(): codec not supported");
         }
     }
 
     public void testRenderingMaxResolutionRemotely() throws Throwable {
         Log.i(TAG, "testRenderingMaxResolutionRemotely");
-        Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
+        Size maxRes = checkMaxConcurrentEncodingDecodingResolution();
         if (maxRes == null) {
             Log.i(TAG, "SKIPPING testRenderingMaxResolutionRemotely(): codec not supported");
-            return;
+        } else {
+            Log.w(TAG, "Trying resolution " + maxRes);
+            runTestRenderingInSeparateThread(maxRes.getWidth(), maxRes.getHeight(), true, false);
         }
-        Log.w(TAG, "Trying resolution w:" + maxRes.first + " h:" + maxRes.second);
-        runTestRenderingInSeparateThread(maxRes.first, maxRes.second, true, false);
     }
 
     public void testRendering800x480RemotelyWith3Windows() throws Throwable {
         Log.i(TAG, "testRendering800x480RemotelyWith3Windows");
-        Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
-        if (maxRes == null) {
-            Log.i(TAG, "SKIPPING testRendering800x480RemotelyWith3Windows(): codec not supported");
-            return;
-        }
-        if (maxRes.first >= 800 && maxRes.second >= 480) {
+        if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
             runTestRenderingInSeparateThread(800, 480, true, true);
         } else {
-            Log.w(TAG, "This H/W does not support 800x480");
+            Log.i(TAG, "SKIPPING testRendering800x480RemotelyWith3Windows(): codec not supported");
         }
     }
 
     public void testRendering800x480LocallyWith3Windows() throws Throwable {
         Log.i(TAG, "testRendering800x480LocallyWith3Windows");
-        Pair<Integer, Integer> maxRes = checkMaxConcurrentEncodingDecodingResolution();
-        if (maxRes == null) {
-            Log.i(TAG, "SKIPPING testRendering800x480LocallyWith3Windows(): codec not supported");
-            return;
-        }
-        if (maxRes.first >= 800 && maxRes.second >= 480) {
+        if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
             runTestRenderingInSeparateThread(800, 480, false, true);
         } else {
-            Log.w(TAG, "This H/W does not support 800x480");
+            Log.i(TAG, "SKIPPING testRendering800x480LocallyWith3Windows(): codec not supported");
         }
     }
 
@@ -424,8 +406,8 @@
     private static final int NUM_DISPLAY_CREATION = 10;
     private static final int NUM_RENDERING = 10;
     private void doTestVirtualDisplayRecycles(int numDisplays) throws Exception {
-        CodecInfo codecInfo = getAvcSupportedFormatInfo();
-        if (codecInfo == null) {
+        Size maxSize = getMaxSupportedEncoderSize();
+        if (maxSize == null) {
             Log.i(TAG, "no codec found, skipping");
             return;
         }
@@ -437,13 +419,13 @@
                 Log.i(TAG, "start encoding");
             }
             EncodingHelper encodingHelper = new EncodingHelper();
-            mEncodingSurface = encodingHelper.startEncoding(codecInfo.mMaxW, codecInfo.mMaxH,
+            mEncodingSurface = encodingHelper.startEncoding(maxSize.getWidth(), maxSize.getHeight(),
                     mEncoderEventListener);
             GlCompositor compositor = new GlCompositor();
             if (DBG) {
                 Log.i(TAG, "start composition");
             }
-            compositor.startComposition(mEncodingSurface, codecInfo.mMaxW, codecInfo.mMaxH,
+            compositor.startComposition(mEncodingSurface, maxSize.getWidth(), maxSize.getHeight(),
                     numDisplays);
             for (int j = 0; j < NUM_DISPLAY_CREATION; j++) {
                 if (DBG) {
@@ -453,7 +435,7 @@
                     virtualDisplays[k] =
                         new VirtualDisplayPresentation(getContext(),
                                 compositor.getWindowSurface(k),
-                                codecInfo.mMaxW/numDisplays, codecInfo.mMaxH);
+                                maxSize.getWidth()/numDisplays, maxSize.getHeight());
                     virtualDisplays[k].createVirtualDisplay();
                     virtualDisplays[k].createPresentation();
                 }
@@ -549,7 +531,7 @@
             MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mW, mH);
             format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
                     MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
-            int bitRate = 10000000;
+            int bitRate = BITRATE_DEFAULT;
             if (mW == 1920 && mH == 1080) {
                 bitRate = BITRATE_1080p;
             } else if (mW == 1280 && mH == 720) {
@@ -1335,152 +1317,56 @@
         }
     }
 
-    private static class CodecInfo {
-        public int mMaxW;
-        public int mMaxH;
-        public int mFps;
-        public int mBitRate;
-        public String mCodecName;
-    };
+    private static Size getMaxSupportedEncoderSize() {
+        final Size[] standardSizes = new Size[] {
+            new Size(1920, 1080),
+            new Size(1280, 720),
+            new Size(720, 480),
+            new Size(352, 576)
+        };
 
-    /**
-     * Returns the first codec capable of encoding the specified MIME type, or null if no
-     * match was found.
-     */
-    private static MediaCodecInfo selectCodec(String mimeType) {
-        int numCodecs = MediaCodecList.getCodecCount();
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; j++) {
-                if (types[j].equalsIgnoreCase(mimeType)) {
-                    return codecInfo;
-                }
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        for (Size sz : standardSizes) {
+            MediaFormat format = MediaFormat.createVideoFormat(
+                MIME_TYPE, sz.getWidth(), sz.getHeight());
+            format.setInteger(MediaFormat.KEY_FRAME_RATE, 15); // require at least 15fps
+            if (mcl.findEncoderForFormat(format) != null) {
+                return sz;
             }
         }
         return null;
     }
 
-    private static CodecInfo getAvcSupportedFormatInfo() {
-        MediaCodecInfo mediaCodecInfo = selectCodec(MIME_TYPE);
-        if (mediaCodecInfo == null) {
-            return null;
-        }
-        CodecCapabilities cap = mediaCodecInfo.getCapabilitiesForType(MIME_TYPE);
-        if (cap == null) { // not supported
-            return null;
-        }
-        CodecInfo info = new CodecInfo();
-        int highestLevel = 0;
-        for (CodecProfileLevel lvl : cap.profileLevels) {
-            if (lvl.level > highestLevel) {
-                highestLevel = lvl.level;
-            }
-        }
-        int maxW = 0;
-        int maxH = 0;
-        int bitRate = 0;
-        int fps = 0; // frame rate for the max resolution
-        switch(highestLevel) {
-            // Do not support Level 1 to 2.
-            case CodecProfileLevel.AVCLevel1:
-            case CodecProfileLevel.AVCLevel11:
-            case CodecProfileLevel.AVCLevel12:
-            case CodecProfileLevel.AVCLevel13:
-            case CodecProfileLevel.AVCLevel1b:
-            case CodecProfileLevel.AVCLevel2:
-                return null;
-            case CodecProfileLevel.AVCLevel21:
-                maxW = 352;
-                maxH = 576;
-                bitRate = 4000000;
-                fps = 25;
-                break;
-            case CodecProfileLevel.AVCLevel22:
-                maxW = 720;
-                maxH = 480;
-                bitRate = 4000000;
-                fps = 15;
-                break;
-            case CodecProfileLevel.AVCLevel3:
-                maxW = 720;
-                maxH = 480;
-                bitRate = 10000000;
-                fps = 30;
-                break;
-            case CodecProfileLevel.AVCLevel31:
-                maxW = 1280;
-                maxH = 720;
-                bitRate = 14000000;
-                fps = 30;
-                break;
-            case CodecProfileLevel.AVCLevel32:
-                maxW = 1280;
-                maxH = 720;
-                bitRate = 20000000;
-                fps = 60;
-                break;
-            case CodecProfileLevel.AVCLevel4: // only try up to 1080p
-            default:
-                maxW = 1920;
-                maxH = 1080;
-                bitRate = 20000000;
-                fps = 30;
-                break;
-        }
-        info.mMaxW = maxW;
-        info.mMaxH = maxH;
-        info.mFps = fps;
-        info.mBitRate = bitRate;
-        info.mCodecName = mediaCodecInfo.getName();
-        Log.i(TAG, "AVC Level 0x" + Integer.toHexString(highestLevel) + " bit rate " + bitRate +
-                " fps " + info.mFps + " w " + maxW + " h " + maxH);
-
-        return info;
-    }
-
     /**
      * Check maximum concurrent encoding / decoding resolution allowed.
      * Some H/Ws cannot support maximum resolution reported in encoder if decoder is running
      * at the same time.
-     * Check is done for 4 different levels: 1080p, 720p, 800x480 and max of encoder if is is
-     * smaller than 800x480.
+     * Check is done for 4 different levels: 1080p, 720p, 800x480, 480p
+     * (The last one is required by CDD.)
      */
-    private Pair<Integer, Integer> checkMaxConcurrentEncodingDecodingResolution() {
-        CodecInfo codecInfo = getAvcSupportedFormatInfo();
-        if (codecInfo == null) {
-            return null;
+    private Size checkMaxConcurrentEncodingDecodingResolution() {
+        if (isConcurrentEncodingDecodingSupported(1920, 1080, BITRATE_1080p)) {
+            return new Size(1920, 1080);
+        } else if (isConcurrentEncodingDecodingSupported(1280, 720, BITRATE_720p)) {
+            return new Size(1280, 720);
+        } else if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
+            return new Size(800, 480);
+        } else if (isConcurrentEncodingDecodingSupported(720, 480, BITRATE_DEFAULT)) {
+            return new Size(720, 480);
         }
-        int maxW = codecInfo.mMaxW;
-        int maxH = codecInfo.mMaxH;
-        if (maxW >= 1920 && maxH >= 1080) {
-            if (isConcurrentEncodingDecodingSupported(1920, 1080, BITRATE_1080p)) {
-                return new Pair<Integer, Integer>(1920, 1080);
-            }
-        }
-        if (maxW >= 1280 && maxH >= 720) {
-            if (isConcurrentEncodingDecodingSupported(1280, 720, BITRATE_720p)) {
-                return new Pair<Integer, Integer>(1280, 720);
-            }
-        }
-        if (maxW >= 800 && maxH >= 480) {
-            if (isConcurrentEncodingDecodingSupported(800, 480, BITRATE_800x480)) {
-                return new Pair<Integer, Integer>(800, 480);
-            }
-        }
-        if (!isConcurrentEncodingDecodingSupported(codecInfo.mMaxW, codecInfo.mMaxH,
-                codecInfo.mBitRate)) {
-            fail("should work with advertised resolution");
-        }
-        return new Pair<Integer, Integer>(maxW, maxH);
+        Log.i(TAG, "SKIPPING test: concurrent encoding and decoding is not supported");
+        return null;
     }
 
     private boolean isConcurrentEncodingDecodingSupported(int w, int h, int bitRate) {
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        MediaFormat testFormat = MediaFormat.createVideoFormat(MIME_TYPE, w, h);
+        testFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
+        if (mcl.findDecoderForFormat(testFormat) == null
+                || mcl.findEncoderForFormat(testFormat) == null) {
+            return false;
+        }
+
         MediaCodec decoder = null;
         OutputSurface decodingSurface = null;
         MediaCodec encoder = null;
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index c2e59d4..4b2a168 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -50,14 +50,14 @@
 
         for (int j = 0; j < kBitRates.length; ++j) {
             MediaFormat format  = new MediaFormat();
-            format.setString(MediaFormat.KEY_MIME, "audio/3gpp");
+            format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AMR_NB);
             format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 8000);
             format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
             format.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates[j]);
             formats.push(format);
         }
 
-        testEncoderWithFormats("audio/3gpp", formats);
+        testEncoderWithFormats(MediaFormat.MIMETYPE_AUDIO_AMR_NB, formats);
     }
 
     public void testAMRWBEncoders() {
@@ -68,14 +68,14 @@
 
         for (int j = 0; j < kBitRates.length; ++j) {
             MediaFormat format  = new MediaFormat();
-            format.setString(MediaFormat.KEY_MIME, "audio/amr-wb");
+            format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AMR_WB);
             format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 16000);
             format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
             format.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates[j]);
             formats.push(format);
         }
 
-        testEncoderWithFormats("audio/amr-wb", formats);
+        testEncoderWithFormats(MediaFormat.MIMETYPE_AUDIO_AMR_WB, formats);
     }
 
     public void testAACEncoders() {
@@ -99,7 +99,7 @@
                 for (int j = 0; j < kBitRates.length; ++j) {
                     for (int ch = 1; ch <= 2; ++ch) {
                         MediaFormat format  = new MediaFormat();
-                        format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
+                        format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AAC);
 
                         format.setInteger(
                                 MediaFormat.KEY_AAC_PROFILE, kAACProfiles[k]);
@@ -115,7 +115,7 @@
             }
         }
 
-        testEncoderWithFormats("audio/mp4a-latm", formats);
+        testEncoderWithFormats(MediaFormat.MIMETYPE_AUDIO_AAC, formats);
     }
 
     private void testEncoderWithFormats(
@@ -135,27 +135,13 @@
     private List<String> getEncoderNamesForType(String mime) {
         LinkedList<String> names = new LinkedList<String>();
 
-        int n = MediaCodecList.getCodecCount();
-        for (int i = 0; i < n; ++i) {
-            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
-
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        for (MediaCodecInfo info : mcl.getCodecInfos()) {
             if (!info.isEncoder()) {
                 continue;
             }
-
-            if (!info.getName().startsWith("OMX.")) {
-                // Unfortunately for legacy reasons, "AACEncoder", a
-                // non OMX component had to be in this list for the video
-                // editor code to work... but it cannot actually be instantiated
-                // using MediaCodec.
-                Log.d(TAG, "skipping '" + info.getName() + "'.");
-                continue;
-            }
-
-            String[] supportedTypes = info.getSupportedTypes();
-
-            for (int j = 0; j < supportedTypes.length; ++j) {
-                if (supportedTypes[j].equalsIgnoreCase(mime)) {
+            for (String type : info.getSupportedTypes()) {
+                if (type.equalsIgnoreCase(mime)) {
                     names.push(info.getName());
                     break;
                 }
diff --git a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
index 43b769a..029a632 100644
--- a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
+++ b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
@@ -62,16 +62,18 @@
     private static final File OUTPUT_FILENAME_DIR = Environment.getExternalStorageDirectory();
 
     // parameters for the video encoder
-    private static final String OUTPUT_VIDEO_MIME_TYPE = "video/avc"; // H.264 Advanced Video Coding
-    private static final int OUTPUT_VIDEO_BIT_RATE = 2000000; // 2Mbps
-    private static final int OUTPUT_VIDEO_FRAME_RATE = 15; // 15fps
+                                                                // H.264 Advanced Video Coding
+    private static final String OUTPUT_VIDEO_MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
+    private static final int OUTPUT_VIDEO_BIT_RATE = 2000000;   // 2Mbps
+    private static final int OUTPUT_VIDEO_FRAME_RATE = 15;      // 15fps
     private static final int OUTPUT_VIDEO_IFRAME_INTERVAL = 10; // 10 seconds between I-frames
     private static final int OUTPUT_VIDEO_COLOR_FORMAT =
             MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
 
     // parameters for the audio encoder
-    private static final String OUTPUT_AUDIO_MIME_TYPE = "audio/mp4a-latm"; // Advanced Audio Coding
-    private static final int OUTPUT_AUDIO_CHANNEL_COUNT = 2; // Must match the input stream.
+                                                                // Advanced Audio Coding
+    private static final String OUTPUT_AUDIO_MIME_TYPE = MediaFormat.MIMETYPE_AUDIO_AAC;
+    private static final int OUTPUT_AUDIO_CHANNEL_COUNT = 2;    // Must match the input stream.
     private static final int OUTPUT_AUDIO_BIT_RATE = 128 * 1024;
     private static final int OUTPUT_AUDIO_AAC_PROFILE =
             MediaCodecInfo.CodecProfileLevel.AACObjectHE;
@@ -259,21 +261,45 @@
         // Exception that may be thrown during release.
         Exception exception = null;
 
-        MediaCodecInfo videoCodecInfo = selectCodec(OUTPUT_VIDEO_MIME_TYPE);
-        if (videoCodecInfo == null) {
-            // Don't fail CTS if they don't have an AVC codec (not here, anyway).
-            Log.e(TAG, "Unable to find an appropriate codec for " + OUTPUT_VIDEO_MIME_TYPE);
-            return;
-        }
-        if (VERBOSE) Log.d(TAG, "video found codec: " + videoCodecInfo.getName());
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
 
-        MediaCodecInfo audioCodecInfo = selectCodec(OUTPUT_AUDIO_MIME_TYPE);
-        if (audioCodecInfo == null) {
-            // Don't fail CTS if they don't have an AAC codec (not here, anyway).
-            Log.e(TAG, "Unable to find an appropriate codec for " + OUTPUT_AUDIO_MIME_TYPE);
+        // We avoid the device-specific limitations on width and height by using values
+        // that are multiples of 16, which all tested devices seem to be able to handle.
+        MediaFormat outputVideoFormat =
+                MediaFormat.createVideoFormat(OUTPUT_VIDEO_MIME_TYPE, mWidth, mHeight);
+
+        // Set some properties. Failing to specify some of these can cause the MediaCodec
+        // configure() call to throw an unhelpful exception.
+        outputVideoFormat.setInteger(
+                MediaFormat.KEY_COLOR_FORMAT, OUTPUT_VIDEO_COLOR_FORMAT);
+        outputVideoFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_VIDEO_BIT_RATE);
+        outputVideoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, OUTPUT_VIDEO_FRAME_RATE);
+        outputVideoFormat.setInteger(
+                MediaFormat.KEY_I_FRAME_INTERVAL, OUTPUT_VIDEO_IFRAME_INTERVAL);
+        if (VERBOSE) Log.d(TAG, "video format: " + outputVideoFormat);
+
+        String videoEncoderName = mcl.findEncoderForFormat(outputVideoFormat);
+        if (videoEncoderName == null) {
+            // Don't fail CTS if they don't have an AVC codec (not here, anyway).
+            Log.e(TAG, "Unable to find an appropriate codec for " + outputVideoFormat);
             return;
         }
-        if (VERBOSE) Log.d(TAG, "audio found codec: " + audioCodecInfo.getName());
+        if (VERBOSE) Log.d(TAG, "video found codec: " + videoEncoderName);
+
+        MediaFormat outputAudioFormat =
+                MediaFormat.createAudioFormat(
+                        OUTPUT_AUDIO_MIME_TYPE, OUTPUT_AUDIO_SAMPLE_RATE_HZ,
+                        OUTPUT_AUDIO_CHANNEL_COUNT);
+        outputAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_AUDIO_BIT_RATE);
+        outputAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, OUTPUT_AUDIO_AAC_PROFILE);
+
+        String audioEncoderName = mcl.findEncoderForFormat(outputAudioFormat);
+        if (audioEncoderName == null) {
+            // Don't fail CTS if they don't have an AAC codec (not here, anyway).
+            Log.e(TAG, "Unable to find an appropriate codec for " + outputAudioFormat);
+            return;
+        }
+        if (VERBOSE) Log.d(TAG, "audio found codec: " + audioEncoderName);
 
         MediaExtractor videoExtractor = null;
         MediaExtractor audioExtractor = null;
@@ -293,32 +319,17 @@
                 assertTrue("missing video track in test video", videoInputTrack != -1);
                 MediaFormat inputFormat = videoExtractor.getTrackFormat(videoInputTrack);
 
-                // We avoid the device-specific limitations on width and height by using values
-                // that are multiples of 16, which all tested devices seem to be able to handle.
-                MediaFormat outputVideoFormat =
-                        MediaFormat.createVideoFormat(OUTPUT_VIDEO_MIME_TYPE, mWidth, mHeight);
-
-                // Set some properties. Failing to specify some of these can cause the MediaCodec
-                // configure() call to throw an unhelpful exception.
-                outputVideoFormat.setInteger(
-                        MediaFormat.KEY_COLOR_FORMAT, OUTPUT_VIDEO_COLOR_FORMAT);
-                outputVideoFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_VIDEO_BIT_RATE);
-                outputVideoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, OUTPUT_VIDEO_FRAME_RATE);
-                outputVideoFormat.setInteger(
-                        MediaFormat.KEY_I_FRAME_INTERVAL, OUTPUT_VIDEO_IFRAME_INTERVAL);
-                if (VERBOSE) Log.d(TAG, "video format: " + outputVideoFormat);
-
                 // Create a MediaCodec for the desired codec, then configure it as an encoder with
                 // our desired properties. Request a Surface to use for input.
                 AtomicReference<Surface> inputSurfaceReference = new AtomicReference<Surface>();
                 videoEncoder = createVideoEncoder(
-                        videoCodecInfo, outputVideoFormat, inputSurfaceReference);
+                        videoEncoderName, outputVideoFormat, inputSurfaceReference);
                 inputSurface = new InputSurface(inputSurfaceReference.get());
                 inputSurface.makeCurrent();
                 // Create a MediaCodec for the decoder, based on the extractor's format.
                 outputSurface = new OutputSurface();
                 outputSurface.changeFragmentShader(FRAGMENT_SHADER);
-                videoDecoder = createVideoDecoder(inputFormat, outputSurface.getSurface());
+                videoDecoder = createVideoDecoder(mcl, inputFormat, outputSurface.getSurface());
             }
 
             if (mCopyAudio) {
@@ -327,18 +338,11 @@
                 assertTrue("missing audio track in test video", audioInputTrack != -1);
                 MediaFormat inputFormat = audioExtractor.getTrackFormat(audioInputTrack);
 
-                MediaFormat outputAudioFormat =
-                        MediaFormat.createAudioFormat(
-                                OUTPUT_AUDIO_MIME_TYPE, OUTPUT_AUDIO_SAMPLE_RATE_HZ,
-                                OUTPUT_AUDIO_CHANNEL_COUNT);
-                outputAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_AUDIO_BIT_RATE);
-                outputAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, OUTPUT_AUDIO_AAC_PROFILE);
-
                 // Create a MediaCodec for the desired codec, then configure it as an encoder with
                 // our desired properties. Request a Surface to use for input.
-                audioEncoder = createAudioEncoder(audioCodecInfo, outputAudioFormat);
+                audioEncoder = createAudioEncoder(audioEncoderName, outputAudioFormat);
                 // Create a MediaCodec for the decoder, based on the extractor's format.
-                audioDecoder = createAudioDecoder(inputFormat);
+                audioDecoder = createAudioDecoder(mcl, inputFormat);
             }
 
             // Creates a muxer but do not start or add tracks just yet.
@@ -517,9 +521,9 @@
      * @param inputFormat the format of the stream to decode
      * @param surface into which to decode the frames
      */
-    private MediaCodec createVideoDecoder(MediaFormat inputFormat, Surface surface)
-            throws IOException {
-        MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFor(inputFormat));
+    private MediaCodec createVideoDecoder(
+            MediaCodecList mcl, MediaFormat inputFormat, Surface surface) throws IOException {
+        MediaCodec decoder = MediaCodec.createByCodecName(mcl.findDecoderForFormat(inputFormat));
         decoder.configure(inputFormat, surface, null, 0);
         decoder.start();
         return decoder;
@@ -536,11 +540,11 @@
      * @param surfaceReference to store the surface to use as input
      */
     private MediaCodec createVideoEncoder(
-            MediaCodecInfo codecInfo,
+            String codecName,
             MediaFormat format,
             AtomicReference<Surface> surfaceReference)
             throws IOException {
-        MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
+        MediaCodec encoder = MediaCodec.createByCodecName(codecName);
         encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
         // Must be called before start() is.
         surfaceReference.set(encoder.createInputSurface());
@@ -553,9 +557,9 @@
      *
      * @param inputFormat the format of the stream to decode
      */
-    private MediaCodec createAudioDecoder(MediaFormat inputFormat)
-            throws IOException {
-        MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFor(inputFormat));
+    private MediaCodec createAudioDecoder(
+            MediaCodecList mcl, MediaFormat inputFormat) throws IOException {
+        MediaCodec decoder = MediaCodec.createByCodecName(mcl.findDecoderForFormat(inputFormat));
         decoder.configure(inputFormat, null, null, 0);
         decoder.start();
         return decoder;
@@ -567,9 +571,9 @@
      * @param codecInfo of the codec to use
      * @param format of the stream to be produced
      */
-    private MediaCodec createAudioEncoder(MediaCodecInfo codecInfo, MediaFormat format) 
+    private MediaCodec createAudioEncoder(String codecName, MediaFormat format)
             throws IOException {
-        MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
+        MediaCodec encoder = MediaCodec.createByCodecName(codecName);
         encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
         encoder.start();
         return encoder;
@@ -1126,28 +1130,4 @@
     private static String getMimeTypeFor(MediaFormat format) {
         return format.getString(MediaFormat.KEY_MIME);
     }
-
-    /**
-     * Returns the first codec capable of encoding the specified MIME type, or null if no match was
-     * found.
-     */
-    private static MediaCodecInfo selectCodec(String mimeType) {
-        int numCodecs = MediaCodecList.getCodecCount();
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; j++) {
-                if (types[j].equalsIgnoreCase(mimeType)) {
-                    return codecInfo;
-                }
-            }
-        }
-        return null;
-    }
-
 }
diff --git a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
index 9528db9..5f326ee 100644
--- a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
+import android.cts.util.MediaUtils;
 import android.graphics.ImageFormat;
 import android.media.Image;
 import android.media.Image.Plane;
@@ -28,7 +29,6 @@
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.MediaCodecList;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.os.Handler;
@@ -100,10 +100,6 @@
      * to be supported by hw decoder.
      */
     public void testHwAVCDecode360pForFlexibleYuv() throws Exception {
-        if (!MediaPlayerTestBase.hasH264(false)) {
-            Log.i(TAG, "SKIPPING testSwAVCDecode360pForFlexibleYuv(): no codec found.");
-            return;
-        }
         try {
             int format = ImageFormat.YUV_420_888;
             videoDecodeToSurface(
@@ -119,10 +115,6 @@
      * to be supported by sw decoder.
      */
     public void testSwAVCDecode360pForFlexibleYuv() throws Exception {
-        if (!MediaPlayerTestBase.hasH264(false)) {
-            Log.i(TAG, "SKIPPING testSwAVCDecode360pForFlexibleYuv(): no codec found.");
-            return;
-        }
         try {
             int format = ImageFormat.YUV_420_888;
             videoDecodeToSurface(
@@ -168,6 +160,10 @@
         ByteBuffer[] decoderInputBuffers;
         ByteBuffer[] decoderOutputBuffers;
 
+        if (!MediaUtils.checkCodecForResource(mContext, video, 0 /* track */)) {
+            return; // skip
+        }
+
         AssetFileDescriptor vidFD = mResources.openRawResourceFd(video);
 
         extractor = new MediaExtractor();
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
index 723652f..afed27b 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
@@ -16,10 +16,15 @@
 package android.media.cts;
 
 import android.content.pm.PackageManager;
+import android.cts.util.MediaUtils;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecInfo.CodecCapabilities;
 import android.media.MediaCodecInfo.CodecProfileLevel;
+import static android.media.MediaCodecInfo.CodecProfileLevel.*;
+import static android.media.MediaFormat.MIMETYPE_VIDEO_AVC;
+import static android.media.MediaFormat.MIMETYPE_VIDEO_HEVC;
 import android.media.MediaCodecList;
+import android.media.MediaFormat;
 import android.media.MediaPlayer;
 
 import android.os.Build;
@@ -32,27 +37,84 @@
 public class MediaCodecCapabilitiesTest extends MediaPlayerTestBase {
 
     private static final String TAG = "MediaCodecCapabilitiesTest";
-    private static final String AVC_MIME = "video/avc";
-    private static final String HEVC_MIME = "video/hevc";
     private static final int PLAY_TIME_MS = 30000;
 
-    public void testAvcBaseline1() throws Exception {
-        if (hasCodec(AVC_MIME) && !supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline,
-                CodecProfileLevel.AVCLevel1)) {
-            throw new RuntimeException("AVCLevel1 support is required by CDD");
+    // Android device implementations with H.264 encoders, MUST support Baseline Profile Level 3.
+    // SHOULD support Main Profile/ Level 4, if supported the device must also support Main
+    // Profile/Level 4 decoding.
+    public void testH264EncoderProfileAndLevel() throws Exception {
+        if (!MediaUtils.checkEncoder(MIMETYPE_VIDEO_AVC)) {
+            return; // skip
         }
-        // We don't have a test stream, but at least we're testing
-        // that supports() returns true for something.
+
+        assertTrue(
+                "H.264 must support Baseline Profile Level 3",
+                hasEncoder(MIMETYPE_VIDEO_AVC, AVCProfileBaseline, AVCLevel3));
+
+        if (hasEncoder(MIMETYPE_VIDEO_AVC, AVCProfileMain, AVCLevel4)) {
+            assertTrue(
+                    "H.264 decoder must support Main Profile Level 4 if it can encode it",
+                    hasDecoder(MIMETYPE_VIDEO_AVC, AVCProfileMain, AVCLevel4));
+        }
+    }
+
+    // Android device implementations with H.264 decoders, MUST support Baseline Profile Level 3.
+    // Android Television Devices MUST support High Profile Level 4.2.
+    public void testH264DecoderProfileAndLevel() throws Exception {
+        if (!MediaUtils.checkDecoder(MIMETYPE_VIDEO_AVC)) {
+            return; // skip
+        }
+
+        assertTrue(
+                "H.264 must support Baseline Profile Level 3",
+                hasDecoder(MIMETYPE_VIDEO_AVC, AVCProfileBaseline, AVCLevel3));
+
+        if (isTv()) {
+            assertTrue(
+                    "H.264 must support High Profile Level 4.2 on TV",
+                    checkDecoder(MIMETYPE_VIDEO_AVC, AVCProfileHigh, AVCLevel42));
+        }
+    }
+
+    // Android device implementations, when supporting H.265 codec MUST support the Main Profile
+    // Level 3 Main tier.
+    // Android Television Devices MUST support the Main Profile Level 4.1 Main tier.
+    // When the UHD video decoding profile is supported, it MUST support Main10 Level 5 Main
+    // Tier profile.
+    public void testH265DecoderProfileAndLevel() throws Exception {
+        if (!MediaUtils.checkDecoder(MIMETYPE_VIDEO_HEVC)) {
+            return; // skip
+        }
+
+        assertTrue(
+                "H.265 must support Main Profile Main Tier Level 3",
+                hasDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel3));
+
+        if (isTv()) {
+            assertTrue(
+                    "H.265 must support Main Profile Main Tier Level 4.1 on TV",
+                    hasDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel41));
+        }
+
+        if (MediaUtils.canDecodeVideo(MIMETYPE_VIDEO_HEVC, 3840, 2160, 30)) {
+            assertTrue(
+                    "H.265 must support Main10 Profile Main Tier Level 5 if UHD is supported",
+                    hasDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain10, HEVCMainTierLevel5));
+        }
+    }
+
+    public void testAvcBaseline1() throws Exception {
+        if (!checkDecoder(MIMETYPE_VIDEO_AVC, AVCProfileBaseline, AVCLevel1)) {
+            return; // skip
+        }
+
+        // TODO: add a test stream
+        MediaUtils.skipTest(TAG, "no test stream");
     }
 
     public void testAvcBaseline12() throws Exception {
-        if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline)) {
-            return;
-        }
-        if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline,
-                CodecProfileLevel.AVCLevel12)) {
-            Log.i(TAG, "AvcBaseline12 not supported");
-            return;  // TODO: Can we make this mandatory?
+        if (!checkDecoder(MIMETYPE_VIDEO_AVC, AVCProfileBaseline, AVCLevel12)) {
+            return; // skip
         }
         playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
                 + "&itag=160&source=youtube&user=android-device-test"
@@ -64,13 +126,8 @@
     }
 
     public void testAvcBaseline30() throws Exception {
-        if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline)) {
-            return;
-        }
-        if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline,
-                CodecProfileLevel.AVCLevel3)) {
-            Log.i(TAG, "AvcBaseline30 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_AVC, AVCProfileBaseline, AVCLevel3)) {
+            return; // skip
         }
         playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
                 + "&itag=18&source=youtube&user=android-device-test"
@@ -82,13 +139,8 @@
     }
 
     public void testAvcHigh31() throws Exception {
-        if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileHigh)) {
-            return;
-        }
-        if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileHigh,
-                CodecProfileLevel.AVCLevel31)) {
-            Log.i(TAG, "AvcHigh31 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_AVC, AVCProfileHigh, AVCLevel31)) {
+            return; // skip
         }
         playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
                 + "&itag=22&source=youtube&user=android-device-test"
@@ -101,16 +153,11 @@
     }
 
     public void testAvcHigh40() throws Exception {
-        if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileHigh)) {
-            return;
-        }
-        if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileHigh,
-                CodecProfileLevel.AVCLevel4)) {
-            Log.i(TAG, "AvcHigh40 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_AVC, AVCProfileHigh, AVCLevel4)) {
+            return; // skip
         }
         if (Build.VERSION.SDK_INT < 18) {
-            Log.i(TAG, "fragmented mp4 not supported");
+            MediaUtils.skipTest(TAG, "fragmented mp4 not supported");
             return;
         }
         playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
@@ -123,126 +170,118 @@
     }
 
     public void testHevcMain1() throws Exception {
-        if (hasCodec(HEVC_MIME) && !supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel1)) {
-            throw new RuntimeException("HECLevel1 support is required by CDD");
+        if (!checkDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel1)) {
+            return; // skip
         }
-        // We don't have a test stream, but at least we're testing
-        // that supports() returns true for something.
+
+        // TODO: add a test stream
+        MediaUtils.skipTest(TAG, "no test stream");
     }
+
     public void testHevcMain2() throws Exception {
-        if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel2)) {
-            Log.i(TAG, "HevcMain2 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel2)) {
+            return; // skip
         }
+
+        // TODO: add a test stream
+        MediaUtils.skipTest(TAG, "no test stream");
     }
 
     public void testHevcMain21() throws Exception {
-        if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel21)) {
-            Log.i(TAG, "HevcMain21 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel21)) {
+            return; // skip
         }
+
+        // TODO: add a test stream
+        MediaUtils.skipTest(TAG, "no test stream");
     }
 
     public void testHevcMain3() throws Exception {
-        if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel3)) {
-            Log.i(TAG, "HevcMain3 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel3)) {
+            return; // skip
         }
+
+        // TODO: add a test stream
+        MediaUtils.skipTest(TAG, "no test stream");
     }
 
     public void testHevcMain31() throws Exception {
-        if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel31)) {
-            Log.i(TAG, "HevcMain31 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel31)) {
+            return; // skip
         }
+
+        // TODO: add a test stream
+        MediaUtils.skipTest(TAG, "no test stream");
     }
 
     public void testHevcMain4() throws Exception {
-        if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel4)) {
-            Log.i(TAG, "HevcMain4 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel4)) {
+            return; // skip
         }
+
+        // TODO: add a test stream
+        MediaUtils.skipTest(TAG, "no test stream");
     }
 
     public void testHevcMain41() throws Exception {
-        if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel41)) {
-            Log.i(TAG, "HevcMain41 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel41)) {
+            return; // skip
         }
+
+        // TODO: add a test stream
+        MediaUtils.skipTest(TAG, "no test stream");
     }
 
     public void testHevcMain5() throws Exception {
-        if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel5)) {
-            Log.i(TAG, "HevcMain5 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel5)) {
+            return; // skip
         }
+
+        // TODO: add a test stream
+        MediaUtils.skipTest(TAG, "no test stream");
     }
 
     public void testHevcMain51() throws Exception {
-        if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel51)) {
-            Log.i(TAG, "HevcMain51 not supported");
-            return;
+        if (!checkDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel51)) {
+            return; // skip
         }
+
+        // TODO: add a test stream
+        MediaUtils.skipTest(TAG, "no test stream");
     }
 
-    private boolean supports(String mimeType, int profile) {
-        return supports(mimeType, profile, 0, false);
+    private boolean checkDecoder(String mime, int profile, int level) {
+        if (!hasDecoder(mime, profile, level)) {
+            MediaUtils.skipTest(TAG, "no " + mime + " decoder for profile "
+                    + profile + " and level " + level);
+            return false;
+        }
+        return true;
     }
 
-    private boolean supports(String mimeType, int profile, int level) {
-        return supports(mimeType, profile, level, true);
+    private boolean hasDecoder(String mime, int profile, int level) {
+        return supports(mime, false /* isEncoder */, profile, level);
     }
 
-    private boolean supports(String mimeType, int profile, int level, boolean testLevel) {
-        int numCodecs = MediaCodecList.getCodecCount();
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-            if (codecInfo.isEncoder()) {
+    private boolean hasEncoder(String mime, int profile, int level) {
+        return supports(mime, true /* isEncoder */, profile, level);
+    }
+
+    private boolean supports(
+            String mime, boolean isEncoder, int profile, int level) {
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        for (MediaCodecInfo info : mcl.getCodecInfos()) {
+            if (isEncoder != info.isEncoder()) {
                 continue;
             }
-
-            if (!supportsMimeType(codecInfo, mimeType)) {
-                continue;
-            }
-
-            CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);
-            for (CodecProfileLevel profileLevel : capabilities.profileLevels) {
-                if (profileLevel.profile == profile
-                        && (!testLevel || profileLevel.level >= level)) {
-                    return true;
+            try {
+                CodecCapabilities caps = info.getCapabilitiesForType(mime);
+                for (CodecProfileLevel pl : caps.profileLevels) {
+                    if (pl.profile == profile && pl.level >= level) {
+                        return true;
+                    }
                 }
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean supportsMimeType(MediaCodecInfo codecInfo, String mimeType) {
-        String[] supportedMimeTypes = codecInfo.getSupportedTypes();
-        for (String supportedMimeType : supportedMimeTypes) {
-            if (mimeType.equalsIgnoreCase(supportedMimeType)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static boolean hasCodec(String mimeType) {
-        MediaCodecList list = new MediaCodecList(MediaCodecList.ALL_CODECS);
-        for (MediaCodecInfo info : list.getCodecInfos()) {
-            for (String type : info.getSupportedTypes()) {
-                if (type.equalsIgnoreCase(mimeType)) {
-                    return true;
-                }
+            } catch (IllegalArgumentException e) {
             }
         }
         return false;
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
index 865780e..4030636 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
@@ -249,6 +249,25 @@
                 pm.hasSystemFeature(pm.FEATURE_CAMERA);
     }
 
+    private boolean hasMicrophone() {
+        PackageManager pm = getContext().getPackageManager();
+        return pm.hasSystemFeature(pm.FEATURE_MICROPHONE);
+    }
+
+    private boolean isWatch() {
+        PackageManager pm = getContext().getPackageManager();
+        return pm.hasSystemFeature(pm.FEATURE_WATCH);
+    }
+
+    private boolean isHandheld() {
+        // handheld nature is not exposed to package manager, for now
+        // we check for touchscreen and NOT watch and NOT tv
+        PackageManager pm = getContext().getPackageManager();
+        return pm.hasSystemFeature(pm.FEATURE_TOUCHSCREEN)
+                && !pm.hasSystemFeature(pm.FEATURE_WATCH)
+                && !pm.hasSystemFeature(pm.FEATURE_TELEVISION);
+    }
+
     // H263 baseline profile must be supported
     public void testIsH263BaselineProfileSupported() {
         if (!hasCamera()) {
@@ -257,21 +276,21 @@
         }
 
         int profile = CodecProfileLevel.H263ProfileBaseline;
-        assertTrue(checkProfileSupported("video/3gpp", false, profile));
-        assertTrue(checkProfileSupported("video/3gpp", true, profile));
+        assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_H263, false, profile));
+        assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_H263, true, profile));
     }
 
     // AVC baseline profile must be supported
     public void testIsAVCBaselineProfileSupported() {
         int profile = CodecProfileLevel.AVCProfileBaseline;
-        assertTrue(checkProfileSupported("video/avc", false, profile));
-        assertTrue(checkProfileSupported("video/avc", true, profile));
+        assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_AVC, false, profile));
+        assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_AVC, true, profile));
     }
 
     // HEVC main profile must be supported
     public void testIsHEVCMainProfileSupported() {
         int profile = CodecProfileLevel.HEVCProfileMain;
-        assertTrue(checkProfileSupported("video/hevc", false, profile));
+        assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, false, profile));
     }
 
     // MPEG4 simple profile must be supported
@@ -282,10 +301,10 @@
         }
 
         int profile = CodecProfileLevel.MPEG4ProfileSimple;
-        assertTrue(checkProfileSupported("video/mp4v-es", false, profile));
+        assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_MPEG4, false, profile));
 
         // FIXME: no support for M4v simple profile video encoder
-        // assertTrue(checkProfileSupported("video/mp4v-es", true, profile));
+        // assertTrue(checkProfileSupported(MediaFormat.MIMETYPE_VIDEO_MPEG4, true, profile));
     }
 
     /*
@@ -375,29 +394,40 @@
         List<CodecType> list = new ArrayList<CodecType>(16);
 
         // Mandatory audio codecs
-        list.add(new CodecType("audio/amr-wb", false));         // amrwb decoder
-        list.add(new CodecType("audio/amr-wb", true));          // amrwb encoder
 
         // flac decoder is not omx-based yet
-        // list.add(new CodecType("audio/flac", false));        // flac decoder
-        list.add(new CodecType("audio/flac", true));            // flac encoder
-        list.add(new CodecType("audio/mpeg", false));           // mp3 decoder
-        list.add(new CodecType("audio/mp4a-latm", false));      // aac decoder
-        list.add(new CodecType("audio/mp4a-latm", true));       // aac encoder
-        list.add(new CodecType("audio/vorbis", false));         // vorbis decoder
-        list.add(new CodecType("audio/3gpp", false));           // amrnb decoder
-        list.add(new CodecType("audio/3gpp", true));            // amrnb encoder
+        // list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_FLAC, false));  // flac decoder
+        list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_MPEG, false));     // mp3 decoder
+        list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_VORBIS, false));   // vorbis decoder
+        list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AAC, false));      // aac decoder
+        list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_RAW, false));      // raw/pcm decoder
+        if (hasMicrophone() && !isWatch()) {
+            list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AAC, true));       // aac encoder
+            // flac encoder is not required
+            // list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_FLAC, true));   // flac encoder
+        }
+        if (isHandheld()) {
+            list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AMR_NB, false));   // amrnb decoder
+            list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AMR_NB, true));    // amrnb encoder
+            list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AMR_WB, false));   // amrwb decoder
+            list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AMR_WB, true));    // amrwb encoder
+        }
 
         // Mandatory video codecs
-        list.add(new CodecType("video/avc", false));            // avc decoder
-        list.add(new CodecType("video/avc", true));             // avc encoder
-        list.add(new CodecType("video/hevc", false));           // hevc decoder
-        list.add(new CodecType("video/3gpp", false));           // h263 decoder
-        list.add(new CodecType("video/3gpp", true));            // h263 encoder
-        list.add(new CodecType("video/mp4v-es", false));        // m4v decoder
-        list.add(new CodecType("video/x-vnd.on2.vp8", false));  // vp8 decoder
-        list.add(new CodecType("video/x-vnd.on2.vp8", true));   // vp8 encoder
-        list.add(new CodecType("video/x-vnd.on2.vp9", false));  // vp9 decoder
+
+        if (!isWatch()) {
+            list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_AVC, false));    // avc decoder
+            list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_AVC, true));     // avc encoder
+            list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_VP8, false));    // vp8 decoder
+            list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_VP8, true));     // vp8 encoder
+            list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_VP9, false));    // vp9 decoder
+            list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_HEVC, false));   // hevc decoder
+            list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_MPEG4, false));  // m4v decoder
+            list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_H263, false));   // h263 decoder
+            if (hasCamera()) {
+                list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_H263, true));    // h263 encoder
+            }
+        }
 
         return list;
     }
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index 5f8885d..1ff5048 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -50,14 +50,15 @@
     private static final boolean VERBOSE = false;           // lots of logging
 
     // parameters for the video encoder
-    private static final String MIME_TYPE = "video/avc";    // H.264 Advanced Video Coding
+                                                            // H.264 Advanced Video Coding
+    private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
     private static final int BIT_RATE = 2000000;            // 2Mbps
     private static final int FRAME_RATE = 15;               // 15fps
     private static final int IFRAME_INTERVAL = 10;          // 10 seconds between I-frames
     private static final int WIDTH = 1280;
     private static final int HEIGHT = 720;
     // parameters for the audio encoder
-    private static final String MIME_TYPE_AUDIO = "audio/mp4a-latm";
+    private static final String MIME_TYPE_AUDIO = MediaFormat.MIMETYPE_AUDIO_AAC;
     private static final int AUDIO_SAMPLE_RATE = 44100;
     private static final int AUDIO_AAC_PROFILE = 2; /* OMX_AUDIO_AACObjectLC */
     private static final int AUDIO_CHANNEL_COUNT = 2; // mono
@@ -79,7 +80,7 @@
      * methods when called in incorrect operational states.
      */
     public void testException() throws Exception {
-        String mimeType = "audio/amr-wb";
+        String mimeType = MediaFormat.MIMETYPE_AUDIO_AMR_WB;
         if (!supportsCodec(mimeType, false)) {
             Log.i(TAG, "No decoder found for mimeType= " + mimeType);
             return;
@@ -1004,18 +1005,17 @@
      * match was found.
      */
     private static MediaCodecInfo selectCodec(String mimeType) {
-        int numCodecs = MediaCodecList.getCodecCount();
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
+        // FIXME: select codecs based on the complete use-case, not just the mime
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        for (MediaCodecInfo info : mcl.getCodecInfos()) {
+            if (!info.isEncoder()) {
                 continue;
             }
 
-            String[] types = codecInfo.getSupportedTypes();
+            String[] types = info.getSupportedTypes();
             for (int j = 0; j < types.length; j++) {
                 if (types[j].equalsIgnoreCase(mimeType)) {
-                    return codecInfo;
+                    return info;
                 }
             }
         }
diff --git a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
index 6591555..67eeca0 100644
--- a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
@@ -97,7 +97,7 @@
 
         // Throws exception b/c start() is not called.
         muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
-        muxer.addTrack(MediaFormat.createVideoFormat("video/avc", 480, 320));
+        muxer.addTrack(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 320));
 
         try {
             muxer.stop();
@@ -108,10 +108,10 @@
 
         // Throws exception b/c 2 video tracks were added.
         muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
-        muxer.addTrack(MediaFormat.createVideoFormat("video/avc", 480, 320));
+        muxer.addTrack(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 320));
 
         try {
-            muxer.addTrack(MediaFormat.createVideoFormat("video/avc", 480, 320));
+            muxer.addTrack(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 320));
             fail("should throw IllegalStateException.");
         } catch (IllegalStateException e) {
             // expected
@@ -119,9 +119,9 @@
 
         // Throws exception b/c 2 audio tracks were added.
         muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
-        muxer.addTrack(MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 1));
+        muxer.addTrack(MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, 48000, 1));
         try {
-            muxer.addTrack(MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 1));
+            muxer.addTrack(MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, 48000, 1));
             fail("should throw IllegalStateException.");
         } catch (IllegalStateException e) {
             // expected
@@ -129,11 +129,11 @@
 
         // Throws exception b/c 3 tracks were added.
         muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
-        muxer.addTrack(MediaFormat.createVideoFormat("video/avc", 480, 320));
-        muxer.addTrack(MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 1));
+        muxer.addTrack(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 320));
+        muxer.addTrack(MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, 48000, 1));
         try {
 
-            muxer.addTrack(MediaFormat.createVideoFormat("video/avc", 480, 320));
+            muxer.addTrack(MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 480, 320));
             fail("should throw IllegalStateException.");
         } catch (IllegalStateException e) {
             // expected
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
index c5cd04e..a498eac 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
@@ -15,6 +15,7 @@
  */
 package android.media.cts;
 
+import android.cts.util.MediaUtils;
 import android.media.MediaPlayer;
 import android.os.Handler;
 import android.os.Looper;
@@ -34,6 +35,7 @@
 
 import java.net.Socket;
 import java.util.Random;
+import java.util.Vector;
 import java.util.concurrent.Callable;
 import java.util.concurrent.FutureTask;
 
@@ -42,6 +44,7 @@
  * from an HTTP server over a simulated "flaky" network.
  */
 public class MediaPlayerFlakyNetworkTest extends MediaPlayerTestBase {
+    private static final String PKG = "com.android.cts.media";
 
     private static final String[] TEST_VIDEOS = {
         "raw/video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz",
@@ -92,24 +95,36 @@
         doPlayStreams(6, 0.00002f);
     }
 
-    private void doPlayStreams(int seed, float probability) throws Throwable {
-        if (!hasH264(false)) {
-            return;
+    private String[] getSupportedVideos() {
+        Vector<String> supported = new Vector<String>();
+        for (String video : TEST_VIDEOS) {
+            if (MediaUtils.hasCodecsForPath(mContext, "android.resource://" + PKG + "/" + video)) {
+                supported.add(video);
+            }
         }
+        return supported.toArray(new String[supported.size()]);
+    }
+
+    private void doPlayStreams(int seed, float probability) throws Throwable {
+        String[] supported = getSupportedVideos();
+        if (supported.length == 0) {
+            MediaUtils.skipTest("no codec found");
+        }
+
         Random random = new Random(seed);
         createHttpServer(seed, probability);
         for (int i = 0; i < 10; i++) {
-            String video = getRandomTestVideo(random);
+            String video = getRandomTestVideo(random, supported);
             doPlayMp4Stream(video, 20000, 5000);
             doAsyncPrepareAndRelease(video);
             doRandomOperations(video);
         }
-        doPlayMp4Stream(getRandomTestVideo(random), 30000, 20000);
+        doPlayMp4Stream(getRandomTestVideo(random, supported), 30000, 20000);
         releaseHttpServer();
     }
 
-    private String getRandomTestVideo(Random random) {
-        return TEST_VIDEOS[random.nextInt(TEST_VIDEOS.length)];
+    private String getRandomTestVideo(Random random, String[] videos) {
+        return videos[random.nextInt(videos.length)];
     }
 
     private void doPlayMp4Stream(String video, int millisToPrepare, int millisToPlay)
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 108aa8b..65a34f4 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -20,10 +20,9 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.AssetFileDescriptor;
+import android.cts.util.MediaUtils;
 import android.media.AudioManager;
 import android.media.MediaCodec;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.media.MediaPlayer;
@@ -674,11 +673,8 @@
             }
         });
 
-        try {
-            loadResource(R.raw.testvideo);
-        } catch (UnsupportedCodecException e) {
-            Log.i(LOG_TAG, "SKIPPING testVideoSurfaceResetting(). Could not find codec.");
-            return;
+        if (!checkLoadResource(R.raw.testvideo)) {
+            return; // skip;
         }
         playLoadedVideo(352, 288, -1);
 
@@ -1030,11 +1026,8 @@
     }
 
     public void testDeselectTrack() throws Throwable {
-        try {
-            loadResource(R.raw.testvideo_with_2_subtitles);
-        } catch (UnsupportedCodecException e) {
-            Log.i(LOG_TAG, "SKIPPING testDeselectTrack(). Could not find codec.");
-            return;
+        if (!checkLoadResource(R.raw.testvideo_with_2_subtitles)) {
+            return; // skip;
         }
         runTestOnUiThread(new Runnable() {
             public void run() {
@@ -1106,11 +1099,8 @@
     }
 
     public void testChangeSubtitleTrack() throws Throwable {
-        try {
-            loadResource(R.raw.testvideo_with_2_subtitles);
-        } catch (UnsupportedCodecException e) {
-            Log.i(LOG_TAG, "SKIPPING testChangeSubtitleTrack(). Could not find codec.");
-            return;
+        if (!checkLoadResource(R.raw.testvideo_with_2_subtitles)) {
+            return; // skip;
         }
 
         mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
@@ -1199,11 +1189,8 @@
     }
 
     public void testGetTrackInfo() throws Throwable {
-        try {
-            loadResource(R.raw.testvideo_with_2_subtitles);
-        } catch (UnsupportedCodecException e) {
-            Log.i(LOG_TAG, "SKIPPING testGetTrackInfo(). Could not find codec.");
-            return;
+        if (!checkLoadResource(R.raw.testvideo_with_2_subtitles)) {
+            return; // skip;
         }
         runTestOnUiThread(new Runnable() {
             public void run() {
@@ -1246,17 +1233,23 @@
      *  The ones being used here are 10 seconds long.
      */
     public void testResumeAtEnd() throws Throwable {
-        testResumeAtEnd(R.raw.loudsoftmp3);
-        testResumeAtEnd(R.raw.loudsoftwav);
-        testResumeAtEnd(R.raw.loudsoftogg);
-        testResumeAtEnd(R.raw.loudsoftitunes);
-        testResumeAtEnd(R.raw.loudsoftfaac);
-        testResumeAtEnd(R.raw.loudsoftaac);
+        int testsRun =
+            testResumeAtEnd(R.raw.loudsoftmp3) +
+            testResumeAtEnd(R.raw.loudsoftwav) +
+            testResumeAtEnd(R.raw.loudsoftogg) +
+            testResumeAtEnd(R.raw.loudsoftitunes) +
+            testResumeAtEnd(R.raw.loudsoftfaac) +
+            testResumeAtEnd(R.raw.loudsoftaac);
+        if (testsRun == 0) {
+            MediaUtils.skipTest("no decoder found");
+        }
     }
 
-    private void testResumeAtEnd(int res) throws Throwable {
-
-        loadResource(res);
+    // returns 1 if test was run, 0 otherwise
+    private int testResumeAtEnd(int res) throws Throwable {
+        if (!loadResource(res)) {
+            return 0; // skip
+        }
         mMediaPlayer.prepare();
         mOnCompletionCalled.reset();
         mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@@ -1274,16 +1267,14 @@
         assertTrue("MediaPlayer should still be playing", mMediaPlayer.isPlaying());
         mMediaPlayer.reset();
         assertEquals("wrong number of repetitions", 1, mOnCompletionCalled.getNumSignal());
+        return 1;
     }
 
     public void testCallback() throws Throwable {
         final int mp4Duration = 8484;
 
-        try {
-            loadResource(R.raw.testvideo);
-        } catch (UnsupportedCodecException e) {
-            Log.i(LOG_TAG, "SKIPPING testCallback(). Could not find codec.");
-            return;
+        if (!checkLoadResource(R.raw.testvideo)) {
+            return; // skip;
         }
 
         mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
@@ -1357,12 +1348,12 @@
 
     public void testRecordAndPlay() throws Exception {
         if (!hasMicrophone()) {
-            Log.i(LOG_TAG, "SKIPPING testRecordAndPlay(). No microphone.");
+            MediaUtils.skipTest(LOG_TAG, "no microphone");
             return;
         }
-        if (!hasH263(false)) {
-            Log.i(LOG_TAG, "SKIPPING testRecordAndPlay(). Cound not find codec.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_AUDIO_AMR_NB)
+                || !MediaUtils.checkEncoder(MediaFormat.MIMETYPE_AUDIO_AMR_NB)) {
+            return; // skip
         }
         File outputFile = new File(Environment.getExternalStorageDirectory(),
                 "record_and_play.3gp");
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
index 9225203..d089658 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
@@ -16,15 +16,10 @@
 package android.media.cts;
 
 import android.content.Context;
-
 import android.content.pm.PackageManager;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
-import android.media.MediaCodec;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
-import android.media.MediaExtractor;
-import android.media.MediaFormat;
+import android.cts.util.MediaUtils;
 import android.media.MediaPlayer;
 import android.test.ActivityInstrumentationTestCase2;
 
@@ -149,9 +144,10 @@
         super.tearDown();
     }
 
-    protected void loadResource(int resid) throws Exception {
-        if (!supportsPlayback(resid)) {
-            throw new UnsupportedCodecException();
+    // returns true on success
+    protected boolean loadResource(int resid) throws Exception {
+        if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
+            return false;
         }
 
         AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
@@ -170,6 +166,11 @@
             afd.close();
         }
         sUseScaleToFitMode = !sUseScaleToFitMode;  // Alternate the scaling mode
+        return true;
+    }
+
+    protected boolean checkLoadResource(int resid) throws Exception {
+        return MediaUtils.check(loadResource(resid), "no decoder found");
     }
 
     protected void loadSubtitleSource(int resid) throws Exception {
@@ -208,13 +209,10 @@
     }
 
     protected void playVideoTest(int resid, int width, int height) throws Exception {
-        if (!supportsPlayback(resid)) {
-            LOG.info("SKIPPING playVideoTest() for resid=" + resid 
-                    + " Could not find a codec for playback.");
-            return;
+        if (!checkLoadResource(resid)) {
+            return; // skip
         }
 
-        loadResource(resid);
         playLoadedVideo(width, height, 0);
     }
 
@@ -295,69 +293,19 @@
     }
 
     private static class PrepareFailedException extends Exception {}
-    public static class UnsupportedCodecException extends Exception {}
-
-    public boolean supportsPlayback(int resid) throws IOException {
-        // First determine if the device supports playback of the requested resource.
-        AssetFileDescriptor fd = mResources.openRawResourceFd(resid);
-        MediaExtractor ex = new MediaExtractor();
-        ex.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
-        MediaFormat format = ex.getTrackFormat(0);
-        String mimeType = format.getString(MediaFormat.KEY_MIME);
-        return hasCodecForMimeType(mimeType, false);
-    }
-
-    public boolean supportsPlayback(String path) throws IOException {
-        MediaExtractor ex = new MediaExtractor();
-        ex.setDataSource(path);
-        MediaFormat format = ex.getTrackFormat(0);
-        String mimeType = format.getString(MediaFormat.KEY_MIME);
-        return hasCodecForMimeType(mimeType, false);
-    }
-
-    public static boolean hasCodecForMimeType(String mimeType, boolean encoder) {
-        MediaCodecList list = new MediaCodecList(MediaCodecList.ALL_CODECS);
-        for (MediaCodecInfo info : list.getCodecInfos()) {
-            if (encoder != info.isEncoder()) {
-                continue;
-            }
-
-            for (String type : info.getSupportedTypes()) {
-                if (type.equalsIgnoreCase(mimeType)) {
-                    LOG.info("Found codec for mimeType=" + mimeType + " codec=" + info.getName());
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public static boolean hasH264(boolean encoder) {
-        return hasCodecForMimeType("video/avc", encoder);
-    }
-
-    public static boolean hasHEVC(boolean encoder) {
-        return hasCodecForMimeType("video/hevc", encoder);
-    }
-
-    public static boolean hasH263(boolean encoder) {
-        return hasCodecForMimeType("video/3gpp", encoder);
-    }
-
-    public static boolean hasMpeg4(boolean encoder) {
-        return hasCodecForMimeType("video/mp4v-es", encoder);
-    }
-
-    public static boolean hasVP8(boolean encoder) {
-        return hasCodecForMimeType("video/x-vnd.on2.vp8", encoder);
-    }
-
-    public static boolean hasVP9(boolean encoder) {
-        return hasCodecForMimeType("video/x-vnd.on2.vp9", encoder);
-    }
 
     public boolean hasAudioOutput() {
         return getInstrumentation().getTargetContext().getPackageManager()
             .hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT);
     }
+
+    public boolean isTv() {
+        PackageManager pm = getInstrumentation().getTargetContext().getPackageManager();
+        return pm.hasSystemFeature(pm.FEATURE_TELEVISION)
+                && pm.hasSystemFeature(pm.FEATURE_LEANBACK);
+    }
+
+    public boolean checkTv() {
+        return MediaUtils.check(isTv(), "not a TV");
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index 85966ce..78b5cfd 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -17,9 +17,8 @@
 
 
 import android.content.pm.PackageManager;
+import android.cts.util.MediaUtils;
 import android.hardware.Camera;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
 import android.media.MediaFormat;
 import android.media.MediaMetadataRetriever;
 import android.media.MediaRecorder;
@@ -309,36 +308,40 @@
     }
 
     public void testRecordingAudioInRawFormats() throws Exception {
-        if (hasAmrnb()) {
-            testRecordAudioInRawFormat(
+        int testsRun = 0;
+        if (hasAmrNb()) {
+            testsRun += testRecordAudioInRawFormat(
                     MediaRecorder.OutputFormat.AMR_NB,
                     MediaRecorder.AudioEncoder.AMR_NB);
         }
 
-        if (hasAmrwb()) {
-            testRecordAudioInRawFormat(
+        if (hasAmrWb()) {
+            testsRun += testRecordAudioInRawFormat(
                     MediaRecorder.OutputFormat.AMR_WB,
                     MediaRecorder.AudioEncoder.AMR_WB);
         }
 
-        if (hasAcc()) {
-            testRecordAudioInRawFormat(
+        if (hasAac()) {
+            testsRun += testRecordAudioInRawFormat(
                     MediaRecorder.OutputFormat.AAC_ADTS,
                     MediaRecorder.AudioEncoder.AAC);
         }
+        if (testsRun == 0) {
+            MediaUtils.skipTest("no audio codecs or microphone");
+        }
     }
 
-    private void testRecordAudioInRawFormat(
+    private int testRecordAudioInRawFormat(
             int fileFormat, int codec) throws Exception {
-
         if (!hasMicrophone()) {
-            return;
+            return 0; // skip
         }
         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
         mMediaRecorder.setOutputFormat(fileFormat);
         mMediaRecorder.setOutputFile(OUTPUT_PATH);
         mMediaRecorder.setAudioEncoder(codec);
         recordMedia(MAX_FILE_SIZE, mOutFile);
+        return 1;
     }
 
     public void testGetAudioSourceMax() throws Exception {
@@ -354,10 +357,8 @@
     }
 
     public void testRecorderAudio() throws Exception {
-        if (!hasMicrophone()) {
-            return;
-        }
-        if (!hasAmrnb()) {
+        if (!hasMicrophone() || !hasAmrNb()) {
+            MediaUtils.skipTest("no audio codecs or microphone");
             return;
         }
         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
@@ -372,10 +373,8 @@
     }
 
     public void testOnInfoListener() throws Exception {
-        if (!hasMicrophone()) {
-            return;
-        }
-        if (!hasAmrnb()) {
+        if (!hasMicrophone() || !hasAmrNb()) {
+            MediaUtils.skipTest("no audio codecs or microphone");
             return;
         }
         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
@@ -389,10 +388,8 @@
     }
 
     public void testSetMaxDuration() throws Exception {
-        if (!hasMicrophone()) {
-            return;
-        }
-        if (!hasAmrnb()) {
+        if (!hasMicrophone() || !hasAmrNb()) {
+            MediaUtils.skipTest("no audio codecs or microphone");
             return;
         }
         testSetMaxDuration(RECORD_TIME_LONG_MS, RECORDED_DUR_TOLERANCE_MS);
@@ -430,14 +427,15 @@
     }
 
     public void testSetMaxFileSize() throws Exception {
-        if (!hasMicrophone() || !hasCamera()) {
-            return;
-        }
         testSetMaxFileSize(512 * 1024, 50 * 1024);
     }
 
     private void testSetMaxFileSize(
             long fileSize, long tolerance) throws Exception {
+        if (!hasMicrophone() || !hasCamera() || !hasAmrNb() || !hasH264()) {
+            MediaUtils.skipTest("no microphone, camera, or codecs");
+            return;
+        }
         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
         mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
         mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
@@ -466,10 +464,8 @@
     }
 
     public void testOnErrorListener() throws Exception {
-        if (!hasMicrophone()) {
-            return;
-        }
-        if (!hasAmrnb()) {
+        if (!hasMicrophone() || !hasAmrNb()) {
+            MediaUtils.skipTest("no audio codecs or microphone");
             return;
         }
         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
@@ -505,31 +501,19 @@
                 PackageManager.FEATURE_MICROPHONE);
     }
 
-    private static boolean hasCodecForMimeType(String mimeType, boolean encoder) {
-        MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        for (MediaCodecInfo info : list.getCodecInfos()) {
-            if (encoder != info.isEncoder()) {
-                continue;
-            }
-
-            for (String type : info.getSupportedTypes()) {
-                if (type.equalsIgnoreCase(mimeType)) {
-                    return true;
-                }
-            }
-        }
-        return false;
+    private static boolean hasAmrNb() {
+        return MediaUtils.hasEncoder(MediaFormat.MIMETYPE_AUDIO_AMR_NB);
     }
 
-    private static boolean hasAmrnb() {
-        return hasCodecForMimeType(MediaFormat.MIMETYPE_AUDIO_AMR_NB, true);
+    private static boolean hasAmrWb() {
+        return MediaUtils.hasEncoder(MediaFormat.MIMETYPE_AUDIO_AMR_WB);
     }
 
-    private static boolean hasAmrwb() {
-        return hasCodecForMimeType(MediaFormat.MIMETYPE_AUDIO_AMR_WB, true);
+    private static boolean hasAac() {
+        return MediaUtils.hasEncoder(MediaFormat.MIMETYPE_AUDIO_AAC);
     }
 
-    private static boolean hasAcc() {
-        return hasCodecForMimeType(MediaFormat.MIMETYPE_AUDIO_AAC, true);
+    private static boolean hasH264() {
+        return MediaUtils.hasEncoder(MediaFormat.MIMETYPE_VIDEO_AVC);
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
index 81c5113..d7bcd78 100644
--- a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
@@ -20,6 +20,7 @@
 
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
+import android.cts.util.MediaUtils;
 import android.media.MediaCodec;
 import android.media.MediaCodec.BufferInfo;
 import android.media.MediaCodecInfo;
@@ -90,8 +91,8 @@
         testExtractor(R.raw.sinesweepwav);
 
         testExtractor(R.raw.video_1280x720_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz);
-        testExtractor(R.raw.video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz);
-        testExtractor(R.raw.video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_44100hz);
+        testExtractor(R.raw.video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz);
+        testExtractor(R.raw.video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_48000hz);
         testExtractor(R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz);
         testExtractor(R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz);
 
@@ -183,24 +184,27 @@
 
 
     public void testDecoder() throws Exception {
-        testDecoder(R.raw.sinesweepogg);
-        testDecoder(R.raw.sinesweepmp3lame);
-        testDecoder(R.raw.sinesweepmp3smpb);
-        testDecoder(R.raw.sinesweepm4a);
-        testDecoder(R.raw.sinesweepflac);
-        testDecoder(R.raw.sinesweepwav);
+        int testsRun =
+            testDecoder(R.raw.sinesweepogg) +
+            testDecoder(R.raw.sinesweepmp3lame) +
+            testDecoder(R.raw.sinesweepmp3smpb) +
+            testDecoder(R.raw.sinesweepm4a) +
+            testDecoder(R.raw.sinesweepflac) +
+            testDecoder(R.raw.sinesweepwav) +
 
-        testDecoder(R.raw.video_1280x720_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz);
-        testDecoder(R.raw.video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz);
-        testDecoder(R.raw.video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_44100hz);
-        testDecoder(R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz);
-        testDecoder(R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz);
+            testDecoder(R.raw.video_1280x720_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz) +
+            testDecoder(R.raw.video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz) +
+            testDecoder(R.raw.video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_48000hz) +
+            testDecoder(R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz) +
+            testDecoder(R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz);
+        if (testsRun == 0) {
+            MediaUtils.skipTest("no decoders found");
+        }
     }
 
-    private void testDecoder(int res) throws Exception {
-        if (!supportsPlayback(res)) {
-            Log.i(TAG, "SKIPPING testDecoder() resid=" + res + " Unsupported decorder.");
-            return;
+    private int testDecoder(int res) throws Exception {
+        if (!MediaUtils.hasCodecsForResource(mContext, res)) {
+            return 0; // skip
         }
 
         AssetFileDescriptor fd = mResources.openRawResourceFd(res);
@@ -215,6 +219,7 @@
         Log.i("@@@", Arrays.toString(ndata));
         assertEquals("number of samples differs", jdata.length, ndata.length);
         assertTrue("different decoded data", Arrays.equals(jdata, ndata));
+        return 1;
     }
 
     private static int[] getDecodedData(FileDescriptor fd, long offset, long size)
@@ -378,17 +383,25 @@
             throws IOException;
 
     public void testVideoPlayback() throws Exception {
-        testVideoPlayback(R.raw.video_1280x720_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz);
-        testVideoPlayback(R.raw.video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz);
-        testVideoPlayback(R.raw.video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_44100hz);
-        testVideoPlayback(R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz);
-        testVideoPlayback(R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz);
+        int testsRun =
+            testVideoPlayback(
+                    R.raw.video_1280x720_mp4_h264_1000kbps_25fps_aac_stereo_128kbps_44100hz) +
+            testVideoPlayback(
+                    R.raw.video_1280x720_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_48000hz) +
+            testVideoPlayback(
+                    R.raw.video_1280x720_webm_vp9_309kbps_25fps_vorbis_stereo_128kbps_48000hz) +
+            testVideoPlayback(
+                    R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz) +
+            testVideoPlayback(
+                    R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz);
+        if (testsRun == 0) {
+            MediaUtils.skipTest("no decoders found");
+        }
     }
 
-    private void testVideoPlayback(int res) throws Exception {
-        if (!supportsPlayback(res)) {
-            Log.i(TAG, "SKIPPING testVideoPlayback() resid=" + res + " Unsupported decorder.");
-            return;
+    private int testVideoPlayback(int res) throws Exception {
+        if (!MediaUtils.checkCodecsForResource(mContext, res)) {
+            return 0; // skip
         }
 
         AssetFileDescriptor fd = mResources.openRawResourceFd(res);
@@ -396,6 +409,7 @@
         boolean ret = testPlaybackNative(mActivity.getSurfaceHolder().getSurface(),
                 fd.getParcelFileDescriptor().getFd(), fd.getStartOffset(), fd.getLength());
         assertTrue("native playback error", ret);
+        return 1;
     }
 
     private static native boolean testPlaybackNative(Surface surface,
@@ -406,10 +420,10 @@
     }
 
     private void testMuxer(int res, boolean webm) throws Exception {
-        if (!supportsPlayback(res)) {
-            Log.i(TAG, "SKIPPING testMuxer() resid=" + res + " Unsupported decorder.");
-            return;
+        if (!MediaUtils.checkCodecsForResource(mContext, res)) {
+            return; // skip
         }
+
         AssetFileDescriptor infd = mResources.openRawResourceFd(res);
 
         File base = mContext.getExternalFilesDir(null);
diff --git a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
index 6198d5f..748cda7 100644
--- a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
@@ -15,6 +15,8 @@
  */
 package android.media.cts;
 
+import android.cts.util.MediaUtils;
+import android.media.MediaFormat;
 import android.media.MediaPlayer;
 import android.os.Looper;
 import android.os.SystemClock;
@@ -23,7 +25,6 @@
 
 import java.io.IOException;
 
-
 /**
  * Tests of MediaPlayer streaming capabilities.
  */
@@ -64,9 +65,8 @@
 */
     // Streaming HTTP video from YouTube
     public void testHTTP_H263_AMR_Video1() throws Exception {
-        if (!hasH263(false)) {
-            Log.i(TAG, "Skipping testHTTP_H263_AMR_Video1(): No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_H263, MediaFormat.MIMETYPE_AUDIO_AMR_NB)) {
+            return; // skip
         }
 
         playVideoTest("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
@@ -77,9 +77,8 @@
                 + "&key=test_key1&user=android-device-test", 176, 144);
     }
     public void testHTTP_H263_AMR_Video2() throws Exception {
-        if (!hasH263(false)) {
-            Log.i(TAG, "Skipping testHTTP_H263_AMR_Video2(): No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_H263, MediaFormat.MIMETYPE_AUDIO_AMR_NB)) {
+            return; // skip
         }
 
         playVideoTest("http://redirector.c.youtube.com/videoplayback?id=c80658495af60617"
@@ -91,9 +90,8 @@
     }
 
     public void testHTTP_MPEG4SP_AAC_Video1() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "Skipping testHTTP_MPEG4SP_AAC_Video1(): No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
+            return; // skip
         }
 
         playVideoTest("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
@@ -104,9 +102,8 @@
                 + "&key=test_key1&user=android-device-test", 176, 144);
     }
     public void testHTTP_MPEG4SP_AAC_Video2() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "Skipping testHTTP_MPEG4SP_AAC_Video2(): No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
+            return; // skip
         }
 
         playVideoTest("http://redirector.c.youtube.com/videoplayback?id=c80658495af60617"
@@ -118,9 +115,8 @@
     }
 
     public void testHTTP_H264Base_AAC_Video1() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "Skipping testHTTP_H264Base_AAC_Video1(): No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+            return; // skip
         }
 
         playVideoTest("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
@@ -131,9 +127,8 @@
                 + "&key=test_key1&user=android-device-test", 640, 360);
     }
     public void testHTTP_H264Base_AAC_Video2() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "Skipping testHTTP_H264Base_AAC_Video2(): No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+            return; // skip
         }
 
         playVideoTest("http://redirector.c.youtube.com/videoplayback?id=c80658495af60617"
@@ -146,9 +141,8 @@
 
     // Streaming HLS video from YouTube
     public void testHLS() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "Skipping testHLS(): No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+            return; // skip
         }
 
         // Play stream for 60 seconds
@@ -202,9 +196,8 @@
                 stream_url = stream_url + "?" + CtsTestServer.NOLENGTH_POSTFIX;
             }
 
-            if (!supportsPlayback(stream_url)) {
-                Log.i(TAG, "Failed to find codec for: '" + stream_url + "'. Skipping test.");
-                return;
+            if (!MediaUtils.checkCodecsForPath(mContext, stream_url)) {
+                return; // skip
             }
 
             mMediaPlayer.setDataSource(stream_url);
@@ -294,25 +287,22 @@
     }
 
     public void testPlayHlsStream() throws Throwable {
-        if (!hasH264(false)) {
-            Log.i(TAG, "Skipping testPlayHlsStream(): No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+            return; // skip
         }
         localHlsTest("hls.m3u8", false, false);
     }
 
     public void testPlayHlsStreamWithQueryString() throws Throwable {
-        if (!hasH264(false)) {
-            Log.i(TAG, "Skipping testPlayHlsStreamWithQueryString(): No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+            return; // skip
         }
         localHlsTest("hls.m3u8", true, false);
     }
 
     public void testPlayHlsStreamWithRedirect() throws Throwable {
-        if (!hasH264(false)) {
-            Log.i(TAG, "Skipping testPlayHlsStreamWithRedirect(): No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+            return; // skip
         }
         localHlsTest("hls.m3u8", false, true);
     }
diff --git a/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java b/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java
index 586b9ef..133b91d 100644
--- a/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java
+++ b/tests/tests/media/src/android/media/cts/Vp8CodecTestBase.java
@@ -53,10 +53,8 @@
 public class Vp8CodecTestBase extends AndroidTestCase {
 
     protected static final String TAG = "VP8CodecTestBase";
-    protected static final String VP8_MIME = "video/x-vnd.on2.vp8";
-    private static final String VPX_SW_DECODER_NAME = "OMX.google.vp8.decoder";
-    private static final String VPX_SW_ENCODER_NAME = "OMX.google.vp8.encoder";
-    private static final String OMX_SW_CODEC_PREFIX = "OMX.google";
+    protected static final String VP8_MIME = MediaFormat.MIMETYPE_VIDEO_VP8;
+    private static final String GOOGLE_CODEC_PREFIX = "omx.google.";
     protected static final String SDCARD_DIR =
             Environment.getExternalStorageDirectory().getAbsolutePath();
 
@@ -93,29 +91,6 @@
     }
 
     /**
-     * Returns the first codec capable of encoding the specified MIME type, or null if no
-     * match was found.
-     */
-    protected static MediaCodecInfo selectCodec(String mimeType) {
-        int numCodecs = MediaCodecList.getCodecCount();
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; j++) {
-                if (types[j].equalsIgnoreCase(mimeType)) {
-                    return codecInfo;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
      *  VP8 codec properties generated by getVp8CodecProperties() function.
      */
     private class CodecProperties {
@@ -123,8 +98,8 @@
             this.codecName = codecName;
             this.colorFormat = colorFormat;
         }
-        public boolean  isGoogleSwCodec() {
-            return codecName.startsWith(OMX_SW_CODEC_PREFIX);
+        public boolean  isGoogleCodec() {
+            return codecName.toLowerCase().startsWith(GOOGLE_CODEC_PREFIX);
         }
 
         public final String codecName; // OpenMax component name for VP8 codec.
@@ -135,76 +110,75 @@
      * Function to find VP8 codec.
      *
      * Iterates through the list of available codecs and tries to find
-     * VP8 codec, which can support either YUV420 planar or NV12 color formats.
-     * If forceSwGoogleCodec parameter set to true the function always returns
-     * Google sw VP8 codec.
-     * If forceSwGoogleCodec parameter set to false the functions looks for platform
-     * specific VP8 codec first. If no platform specific codec exist, falls back to
-     * Google sw VP8 codec.
+     * VPX codec, which can support either YUV420 planar or NV12 color formats.
+     * If forceGoogleCodec parameter set to true the function always returns
+     * Google VPX codec.
+     * If forceGoogleCodec parameter set to false the functions looks for platform
+     * specific VPX codec first. If no platform specific codec exist, falls back to
+     * Google VPX codec.
      *
      * @param isEncoder     Flag if encoder is requested.
-     * @param forceSwGoogleCodec  Forces to use Google sw codec.
+     * @param forceGoogleCodec  Forces to use Google codec.
      */
-    private CodecProperties getVp8CodecProperties(boolean isEncoder,
-            boolean forceSwGoogleCodec) throws Exception {
+    private CodecProperties getVpxCodecProperties(
+            boolean isEncoder,
+            MediaFormat format,
+            boolean forceGoogleCodec) throws Exception {
         CodecProperties codecProperties = null;
+        String mime = format.getString(MediaFormat.KEY_MIME);
 
-        if (!forceSwGoogleCodec) {
-            // Loop through the list of omx components in case platform specific codec
-            // is requested.
-            for (int i = 0; i < MediaCodecList.getCodecCount(); i++) {
-                MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-                if (isEncoder != codecInfo.isEncoder()) {
+        // Loop through the list of omx components in case platform specific codec
+        // is requested.
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        for (MediaCodecInfo codecInfo : mcl.getCodecInfos()) {
+            if (isEncoder != codecInfo.isEncoder()) {
+                continue;
+            }
+            Log.v(TAG, codecInfo.getName());
+            // TODO: remove dependence of Google from the test
+            // Check if this is Google codec - we should ignore it.
+            boolean isGoogleCodec =
+                codecInfo.getName().toLowerCase().startsWith(GOOGLE_CODEC_PREFIX);
+            if (!isGoogleCodec && forceGoogleCodec) {
+                continue;
+            }
+
+            for (String type : codecInfo.getSupportedTypes()) {
+                if (!type.equalsIgnoreCase(mime)) {
                     continue;
                 }
-                Log.v(TAG, codecInfo.getName());
-                // Check if this is sw Google codec - we should ignore it.
-                boolean isGoogleSwCodec = codecInfo.getName().startsWith(OMX_SW_CODEC_PREFIX);
-                if (isGoogleSwCodec) {
+                CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(type);
+                if (!capabilities.isFormatSupported(format)) {
                     continue;
                 }
 
-                for (String type : codecInfo.getSupportedTypes()) {
-                    if (!type.equalsIgnoreCase(VP8_MIME)) {
-                        continue;
-                    }
-                    CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(VP8_MIME);
+                // Get candidate codec properties.
+                Log.v(TAG, "Found candidate codec " + codecInfo.getName());
+                for (int colorFormat: capabilities.colorFormats) {
+                    Log.v(TAG, "   Color: 0x" + Integer.toHexString(colorFormat));
+                }
 
-                    // Get candidate codec properties.
-                    Log.v(TAG, "Found candidate codec " + codecInfo.getName());
-                    for (int colorFormat : capabilities.colorFormats) {
-                        Log.v(TAG, "   Color: 0x" + Integer.toHexString(colorFormat));
-                    }
-
-                    // Check supported color formats.
-                    for (int supportedColorFormat : mSupportedColorList) {
-                        for (int codecColorFormat : capabilities.colorFormats) {
-                            if (codecColorFormat == supportedColorFormat) {
-                                codecProperties = new CodecProperties(codecInfo.getName(),
-                                        codecColorFormat);
-                                Log.v(TAG, "Found target codec " + codecProperties.codecName +
-                                        ". Color: 0x" + Integer.toHexString(codecColorFormat));
+                // Check supported color formats.
+                for (int supportedColorFormat : mSupportedColorList) {
+                    for (int codecColorFormat : capabilities.colorFormats) {
+                        if (codecColorFormat == supportedColorFormat) {
+                            codecProperties = new CodecProperties(codecInfo.getName(),
+                                    codecColorFormat);
+                            Log.v(TAG, "Found target codec " + codecProperties.codecName +
+                                    ". Color: 0x" + Integer.toHexString(codecColorFormat));
+                            // return first HW codec found
+                            if (!isGoogleCodec) {
                                 return codecProperties;
                             }
                         }
                     }
-                    // HW codec we found does not support one of necessary color formats.
-                    throw new RuntimeException("No hw codec with YUV420 or NV12 color formats");
                 }
             }
         }
-        // If no hw vp8 codec exist or sw codec is requested use default Google sw codec.
         if (codecProperties == null) {
-            Log.v(TAG, "Use SW VP8 codec");
-            if (isEncoder) {
-                codecProperties = new CodecProperties(VPX_SW_ENCODER_NAME,
-                        CodecCapabilities.COLOR_FormatYUV420Planar);
-            } else {
-                codecProperties = new CodecProperties(VPX_SW_DECODER_NAME,
-                        CodecCapabilities.COLOR_FormatYUV420Planar);
-            }
+            Log.i(TAG, "no suitable " + (forceGoogleCodec ? "google " : "")
+                    + (isEncoder ? "encoder " : "decoder ") + "found for " + format);
         }
-
         return codecProperties;
     }
 
@@ -223,8 +197,8 @@
         int inputResourceId;
         // Name of the IVF file to write encoded bitsream
         public String outputIvfFilename;
-        // Force to use Google SW VP8 encoder.
-        boolean forceSwEncoder;
+        // Force to use Google VP8 encoder.
+        boolean forceGoogleEncoder;
         // Number of frames to encode.
         int frameCount;
         // Frame rate of input file in frames per second.
@@ -286,7 +260,7 @@
             params.inputResourceId = R.raw.football_qvga;
             params.outputIvfFilename = SDCARD_DIR + File.separator +
                     outputIvfBaseName + resolutionScales[i] + ".ivf";
-            params.forceSwEncoder = false;
+            params.forceGoogleEncoder = false;
             params.frameCount = encodeSeconds * frameRate;
             params.frameRate = frameRate;
             params.frameWidth = Math.min(frameWidth * resolutionScales[i], 1280);
@@ -532,15 +506,15 @@
      * @param inputIvfFilename  The name of the IVF file containing encoded bitsream.
      * @param outputYuvFilename The name of the output YUV file (optional).
      * @param frameRate         Frame rate of input file in frames per second
-     * @param forceSwDecoder    Force to use Googlw sw VP8 decoder.
+     * @param forceGoogleDecoder    Force to use Google VP8 decoder.
      */
     protected ArrayList<MediaCodec.BufferInfo> decode(
             String inputIvfFilename,
             String outputYuvFilename,
             int frameRate,
-            boolean forceSwDecoder) throws Exception {
+            boolean forceGoogleDecoder) throws Exception {
         ArrayList<MediaCodec.BufferInfo> bufferInfos = new ArrayList<MediaCodec.BufferInfo>();
-        CodecProperties properties = getVp8CodecProperties(false, forceSwDecoder);
+
         // Open input/output.
         IvfReader ivf = new IvfReader(inputIvfFilename);
         int frameWidth = ivf.getWidth();
@@ -548,21 +522,27 @@
         int frameCount = ivf.getFrameCount();
         int frameStride = frameWidth;
         int frameSliceHeight = frameHeight;
-        int frameColorFormat = properties.colorFormat;
         assertTrue(frameWidth > 0);
         assertTrue(frameHeight > 0);
         assertTrue(frameCount > 0);
 
+        // Create decoder.
+        MediaFormat format = MediaFormat.createVideoFormat(
+                VP8_MIME, ivf.getWidth(), ivf.getHeight());
+        CodecProperties properties = getVpxCodecProperties(
+                false /* encoder */, format, forceGoogleDecoder);
+        if (properties == null) {
+            ivf.close();
+            return null;
+        }
+        int frameColorFormat = properties.colorFormat;
+        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat);
+
         FileOutputStream yuv = null;
         if (outputYuvFilename != null) {
             yuv = new FileOutputStream(outputYuvFilename, false);
         }
 
-        // Create decoder.
-        MediaFormat format = MediaFormat.createVideoFormat(VP8_MIME,
-                                                           ivf.getWidth(),
-                                                           ivf.getHeight());
-        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat);
         Log.d(TAG, "Creating decoder " + properties.codecName +
                 ". Color format: 0x" + Integer.toHexString(frameColorFormat) +
                 ". " + frameWidth + " x " + frameHeight);
@@ -1282,11 +1262,20 @@
             EncoderOutputStreamParameters streamParams) throws Exception {
 
         ArrayList<MediaCodec.BufferInfo> bufferInfos = new ArrayList<MediaCodec.BufferInfo>();
-        CodecProperties properties = getVp8CodecProperties(true, streamParams.forceSwEncoder);
-        Log.d(TAG, "Source reslution: " + streamParams.frameWidth + " x " +
+        Log.d(TAG, "Source resolution: "+streamParams.frameWidth + " x " +
                 streamParams.frameHeight);
         int bitrate = streamParams.bitrateSet[0];
 
+        // Create minimal media format signifying desired output.
+        MediaFormat format = MediaFormat.createVideoFormat(
+                VP8_MIME, streamParams.frameWidth, streamParams.frameHeight);
+        format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+        CodecProperties properties = getVpxCodecProperties(
+                true, format, streamParams.forceGoogleEncoder);
+        if (properties == null) {
+            return null;
+        }
+
         // Open input/output
         InputStream yuvStream = OpenFileOrResourceId(
                 streamParams.inputYuvFilename, streamParams.inputResourceId);
@@ -1294,9 +1283,6 @@
                 streamParams.outputIvfFilename, streamParams.frameWidth, streamParams.frameHeight);
 
         // Create a media format signifying desired output.
-        MediaFormat format = MediaFormat.createVideoFormat(
-                VP8_MIME, streamParams.frameWidth, streamParams.frameHeight);
-        format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
         if (streamParams.bitrateType == VIDEO_ControlRateConstant) {
             format.setInteger("bitrate-mode", VIDEO_ControlRateConstant); // set CBR
         }
@@ -1451,19 +1437,25 @@
         }
 
         ArrayList<MediaCodec.BufferInfo> bufferInfos = new ArrayList<MediaCodec.BufferInfo>();
-        CodecProperties properties = getVp8CodecProperties(true, streamParams.forceSwEncoder);
-        Log.d(TAG, "Source reslution: " + streamParams.frameWidth + " x " +
+        Log.d(TAG, "Source resolution: "+streamParams.frameWidth + " x " +
                 streamParams.frameHeight);
         int bitrate = streamParams.bitrateSet[0];
 
+        // Create minimal media format signifying desired output.
+        MediaFormat format = MediaFormat.createVideoFormat(
+                VP8_MIME, streamParams.frameWidth, streamParams.frameHeight);
+        format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+        CodecProperties properties = getVpxCodecProperties(
+                true, format, streamParams.forceGoogleEncoder);
+        if (properties == null) {
+            return null;
+        }
+
         // Open input/output
         IvfWriter ivf = new IvfWriter(
                 streamParams.outputIvfFilename, streamParams.frameWidth, streamParams.frameHeight);
 
         // Create a media format signifying desired output.
-        MediaFormat format = MediaFormat.createVideoFormat(
-                VP8_MIME, streamParams.frameWidth, streamParams.frameHeight);
-        format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
         if (streamParams.bitrateType == VIDEO_ControlRateConstant) {
             format.setInteger("bitrate-mode", VIDEO_ControlRateConstant); // set CBR
         }
@@ -1546,9 +1538,22 @@
         boolean bufferConsumedTotal = false;
         CodecProperties[] codecProperties = new CodecProperties[numEncoders];
 
-        for (int i = 0; i < numEncoders; i++) {
-            EncoderOutputStreamParameters params = encodingParams.get(i);
-            CodecProperties properties = getVp8CodecProperties(true, params.forceSwEncoder);
+        numEncoders = 0;
+        for (EncoderOutputStreamParameters params : encodingParams) {
+            int i = numEncoders;
+            Log.d(TAG, "Source resolution: " + params.frameWidth + " x " +
+                    params.frameHeight);
+            int bitrate = params.bitrateSet[0];
+
+            // Create minimal media format signifying desired output.
+            format[i] = MediaFormat.createVideoFormat(VP8_MIME,
+                    params.frameWidth, params.frameHeight);
+            format[i].setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+            CodecProperties properties = getVpxCodecProperties(
+                    true, format[i], params.forceGoogleEncoder);
+            if (properties == null) {
+                continue;
+            }
 
             // Check if scaled image was created
             int scale = params.frameWidth / srcFrameWidth;
@@ -1574,10 +1579,6 @@
             srcFrame[i] = new byte[frameSize];
 
             // Create a media format signifying desired output.
-            int bitrate = params.bitrateSet[0];
-            format[i] = MediaFormat.createVideoFormat(VP8_MIME,
-                    params.frameWidth, params.frameHeight);
-            format[i].setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
             if (params.bitrateType == VIDEO_ControlRateConstant) {
                 format[i].setInteger("bitrate-mode", VIDEO_ControlRateConstant); // set CBR
             }
@@ -1607,6 +1608,11 @@
             codecProperties[i] = new CodecProperties(properties.codecName, properties.colorFormat);
 
             inputConsumed[i] = true;
+            ++numEncoders;
+        }
+        if (numEncoders == 0) {
+            Log.i(TAG, "no suitable encoders found for any of the streams");
+            return null;
         }
 
         while (!sawOutputEOSTotal) {
@@ -1644,7 +1650,8 @@
                     // Convert YUV420 to NV12 if necessary
                     if (codecProperties[i].colorFormat !=
                             CodecCapabilities.COLOR_FormatYUV420Planar) {
-                        srcFrame[i] = YUV420ToNV(params.frameWidth, params.frameHeight, srcFrame[i]);
+                        srcFrame[i] =
+                            YUV420ToNV(params.frameWidth, params.frameHeight, srcFrame[i]);
                     }
                 }
 
diff --git a/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java b/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
index 57e397f..be7e721 100644
--- a/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/Vp8EncoderTest.java
@@ -18,6 +18,8 @@
 
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
 import android.util.Log;
 import com.android.cts.media.R;
 
@@ -52,13 +54,13 @@
     private static final int[] TEST_BITRATES_SET = { 300000, 500000, 700000, 900000 };
     // Maximum allowed bitrate variation from the target value.
     private static final double MAX_BITRATE_VARIATION = 0.2;
-    // Average PSNR values for reference SW VP8 codec for the above bitrates.
+    // Average PSNR values for reference Google VP8 codec for the above bitrates.
     private static final double[] REFERENCE_AVERAGE_PSNR = { 33.1, 35.2, 36.6, 37.8 };
-    // Minimum PSNR values for reference SW VP8 codec for the above bitrates.
+    // Minimum PSNR values for reference Google VP8 codec for the above bitrates.
     private static final double[] REFERENCE_MINIMUM_PSNR = { 25.9, 27.5, 28.4, 30.3 };
-    // Maximum allowed average PSNR difference of HW encoder comparing to reference SW encoder.
+    // Maximum allowed average PSNR difference of encoder comparing to reference Google encoder.
     private static final double MAX_AVERAGE_PSNR_DIFFERENCE = 2;
-    // Maximum allowed minimum PSNR difference of HW encoder comparing to reference SW encoder.
+    // Maximum allowed minimum PSNR difference of encoder comparing to reference Google encoder.
     private static final double MAX_MINIMUM_PSNR_DIFFERENCE = 4;
     // Maximum allowed average PSNR difference of the encoder running in a looper thread with 0 ms
     // buffer dequeue timeout comparing to the encoder running in a callee's thread with 100 ms
@@ -80,13 +82,8 @@
      * Also checks the average bitrate is within MAX_BITRATE_VARIATION of the target value.
      */
     public void testBasic() throws Exception {
-        MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
-        if (codecInfo == null) {
-            Log.w(TAG, "Codec " + VP8_MIME + " not supported. Return from testBasic.");
-            return;
-        }
-
         int encodeSeconds = 9;
+        boolean skipped = true;
 
         for (int targetBitrate : TEST_BITRATES_SET) {
             EncoderOutputStreamParameters params = getDefaultEncodingParameters(
@@ -100,6 +97,11 @@
                     targetBitrate,
                     true);
             ArrayList<MediaCodec.BufferInfo> bufInfo = encode(params);
+            if (bufInfo == null) {
+                continue;
+            }
+            skipped = false;
+
             Vp8EncodingStatistics statistics = computeEncodingStatistics(bufInfo);
 
             assertEquals("Stream bitrate " + statistics.mAverageBitrate +
@@ -107,7 +109,11 @@
                     targetBitrate, statistics.mAverageBitrate,
                     MAX_BITRATE_VARIATION * targetBitrate);
 
-            decode(params.outputIvfFilename, null, FPS, params.forceSwEncoder);
+            decode(params.outputIvfFilename, null, FPS, params.forceGoogleEncoder);
+        }
+
+        if (skipped) {
+            Log.i(TAG, "SKIPPING testBasic(): codec is not supported");
         }
     }
 
@@ -119,12 +125,6 @@
      * does not change much for two different ways of the encoder call.
      */
     public void testAsyncEncoding() throws Exception {
-        MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
-        if (codecInfo == null) {
-            Log.w(TAG, "Codec " + VP8_MIME + " not supported. Return from testAsyncEncoding.");
-            return;
-        }
-
         int encodeSeconds = 9;
 
         // First test the encoder running in a looper thread with buffer callbacks enabled.
@@ -140,8 +140,12 @@
                 BITRATE,
                 syncEncoding);
         ArrayList<MediaCodec.BufferInfo> bufInfos = encodeAsync(params);
+        if (bufInfos == null) {
+            Log.i(TAG, "SKIPPING testAsyncEncoding(): no suitable encoder found");
+            return;
+        }
         computeEncodingStatistics(bufInfos);
-        decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceSwEncoder);
+        decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceGoogleEncoder);
         Vp8DecodingStatistics statisticsAsync = computeDecodingStatistics(
                 params.inputYuvFilename, R.raw.football_qvga, OUTPUT_YUV,
                 params.frameWidth, params.frameHeight);
@@ -160,8 +164,12 @@
                 BITRATE,
                 syncEncoding);
         bufInfos = encode(params);
+        if (bufInfos == null) {
+            Log.i(TAG, "SKIPPING testAsyncEncoding(): no suitable encoder found");
+            return;
+        }
         computeEncodingStatistics(bufInfos);
-        decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceSwEncoder);
+        decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceGoogleEncoder);
         Vp8DecodingStatistics statisticsSync = computeDecodingStatistics(
                 params.inputYuvFilename, R.raw.football_qvga, OUTPUT_YUV,
                 params.frameWidth, params.frameHeight);
@@ -186,12 +194,6 @@
      * The test does not verify the output stream.
      */
     public void testSyncFrame() throws Exception {
-        MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
-        if (codecInfo == null) {
-            Log.w(TAG, "Codec " + VP8_MIME + " not supported. Return from testSyncFrame.");
-            return;
-        }
-
         int encodeSeconds = 9;
 
         EncoderOutputStreamParameters params = getDefaultEncodingParameters(
@@ -207,6 +209,11 @@
         params.syncFrameInterval = encodeSeconds * FPS;
         params.syncForceFrameInterval = FPS;
         ArrayList<MediaCodec.BufferInfo> bufInfo = encode(params);
+        if (bufInfo == null) {
+            Log.i(TAG, "SKIPPING testSyncFrame(): no suitable encoder found");
+            return;
+        }
+
         Vp8EncodingStatistics statistics = computeEncodingStatistics(bufInfo);
 
         // First check if we got expected number of key frames.
@@ -236,12 +243,6 @@
      * bitrate after 6 seconds and ensure the encoder responds.
      */
     public void testDynamicBitrateChange() throws Exception {
-        MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
-        if (codecInfo == null) {
-            Log.w(TAG, "Codec " + VP8_MIME + " not supported. Return from testDynamicBitrateChange.");
-            return;
-        }
-
         int encodeSeconds = 12;    // Encoding sequence duration in seconds.
         int[] bitrateTargetValues = { 400000, 800000 };  // List of bitrates to test.
 
@@ -268,6 +269,11 @@
         }
 
         ArrayList<MediaCodec.BufferInfo> bufInfo = encode(params);
+        if (bufInfo == null) {
+            Log.i(TAG, "SKIPPING testDynamicBitrateChange(): no suitable encoder found");
+            return;
+        }
+
         Vp8EncodingStatistics statistics = computeEncodingStatistics(bufInfo);
 
         // Calculate actual average bitrates  for every [stepSeconds] second.
@@ -304,10 +310,12 @@
       * Compares average bitrate and PSNR for sequential and parallel runs.
       */
      public void testParallelEncodingAndDecoding() throws Exception {
-         MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
-         if (codecInfo == null) {
-             Log.w(TAG, "Codec " + VP8_MIME + " not supported. "
-                     + "Return from testParallelEncodingAndDecoding.");
+         // check for encoder up front, as by the time we detect lack of
+         // encoder support, we may have already started decoding.
+         MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+         MediaFormat format = MediaFormat.createVideoFormat(VP8_MIME, WIDTH, HEIGHT);
+         if (mcl.findEncoderForFormat(format) == null) {
+             Log.i(TAG, "SKIPPING testParallelEncodingAndDecoding(): no suitable encoder found");
              return;
          }
 
@@ -343,7 +351,7 @@
          Runnable runDecoder = new Runnable() {
              public void run() {
                  try {
-                     decode(inputIvfFilename, OUTPUT_YUV, FPS, params.forceSwEncoder);
+                     decode(inputIvfFilename, OUTPUT_YUV, FPS, params.forceGoogleEncoder);
                      Vp8DecodingStatistics statistics = computeDecodingStatistics(
                             params.inputYuvFilename, R.raw.football_qvga, OUTPUT_YUV,
                             params.frameWidth, params.frameHeight);
@@ -400,21 +408,17 @@
      * Run the the encoder for 9 seconds for each bitrate and calculate PSNR
      * for each encoded stream.
      * Video streams with higher bitrates should have higher PSNRs.
-     * Also compares average and minimum PSNR of HW codec with PSNR values of reference SW codec.
+     * Also compares average and minimum PSNR of codec with PSNR values of reference Google codec.
      */
     public void testEncoderQuality() throws Exception {
-        MediaCodecInfo codecInfo = selectCodec(VP8_MIME);
-        if (codecInfo == null) {
-            Log.w(TAG, "Codec " + VP8_MIME + " not supported. Return from testEncoderQuality.");
-            return;
-        }
-
         int encodeSeconds = 9;      // Encoding sequence duration in seconds for each bitrate.
         double[] psnrPlatformCodecAverage = new double[TEST_BITRATES_SET.length];
         double[] psnrPlatformCodecMin = new double[TEST_BITRATES_SET.length];
+        boolean[] completed = new boolean[TEST_BITRATES_SET.length];
+        boolean skipped = true;
 
         // Run platform specific encoder for different bitrates
-        // and compare PSNR of hw codec with PSNR of reference sw codec.
+        // and compare PSNR of codec with PSNR of reference Google codec.
         for (int i = 0; i < TEST_BITRATES_SET.length; i++) {
             EncoderOutputStreamParameters params = getDefaultEncodingParameters(
                     INPUT_YUV,
@@ -426,9 +430,15 @@
                     BITRATE_MODE,
                     TEST_BITRATES_SET[i],
                     true);
-            encode(params);
+            if (encode(params) == null) {
+                // parameters not supported, try other bitrates
+                completed[i] = false;
+                continue;
+            }
+            completed[i] = true;
+            skipped = false;
 
-            decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceSwEncoder);
+            decode(params.outputIvfFilename, OUTPUT_YUV, FPS, params.forceGoogleEncoder);
             Vp8DecodingStatistics statistics = computeDecodingStatistics(
                     params.inputYuvFilename, R.raw.football_qvga, OUTPUT_YUV,
                     params.frameWidth, params.frameHeight);
@@ -436,9 +446,20 @@
             psnrPlatformCodecMin[i] = statistics.mMinimumPSNR;
         }
 
+        if (skipped) {
+            Log.i(TAG, "SKIPPING testEncoderQuality(): no bitrates supported");
+            return;
+        }
+
         // First do a sanity check - higher bitrates should results in higher PSNR.
         for (int i = 1; i < TEST_BITRATES_SET.length ; i++) {
+            if (!completed[i]) {
+                continue;
+            }
             for (int j = 0; j < i; j++) {
+                if (!completed[j]) {
+                    continue;
+                }
                 double differenceBitrate = TEST_BITRATES_SET[i] - TEST_BITRATES_SET[j];
                 double differencePSNR = psnrPlatformCodecAverage[i] - psnrPlatformCodecAverage[j];
                 if (differenceBitrate * differencePSNR < 0) {
@@ -450,12 +471,16 @@
             }
         }
 
-        // Then compare average and minimum PSNR of platform codec with reference sw codec -
+        // Then compare average and minimum PSNR of platform codec with reference Google codec -
         // average PSNR for platform codec should be no more than 2 dB less than reference PSNR
         // and minumum PSNR - no more than 4 dB less than reference minimum PSNR.
         // These PSNR difference numbers are arbitrary for now, will need further estimation
-        // when more devices with hw VP8 codec will appear.
+        // when more devices with HW VP8 codec will appear.
         for (int i = 0; i < TEST_BITRATES_SET.length ; i++) {
+            if (!completed[i]) {
+                continue;
+            }
+
             Log.d(TAG, "Bitrate " + TEST_BITRATES_SET[i]);
             Log.d(TAG, "Reference: Average: " + REFERENCE_AVERAGE_PSNR[i] + ". Minimum: " +
                     REFERENCE_MINIMUM_PSNR[i]);
@@ -470,7 +495,7 @@
             if (psnrPlatformCodecMin[i] < REFERENCE_MINIMUM_PSNR[i] -
                     MAX_MINIMUM_PSNR_DIFFERENCE) {
                 throw new RuntimeException("Low minimum PSNR " + psnrPlatformCodecMin[i] +
-                        " comparing to sw PSNR " + REFERENCE_MINIMUM_PSNR[i] +
+                        " comparing to reference PSNR " + REFERENCE_MINIMUM_PSNR[i] +
                         " for bitrate " + TEST_BITRATES_SET[i]);
             }
         }
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java b/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
index 09cc8b8..d39bc16 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
@@ -19,15 +19,13 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
-import android.graphics.Bitmap;
+import android.media.MediaFormat;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.PowerManager;
 import android.util.Log;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
-import android.view.ViewGroup;
-import android.widget.ImageView;
 
 import com.android.cts.mediastress.R;
 
@@ -85,7 +83,7 @@
     }
 
     public void startPlayback(String filename){
-      String mimetype = "audio/mpeg";
+      String mimetype = MediaFormat.MIMETYPE_AUDIO_MPEG;
       Uri path = Uri.parse(filename);
       Intent intent = new Intent(Intent.ACTION_VIEW);
       intent.setDataAndType(path, mimetype);
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaTest.java b/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaTest.java
index 2119d75..05145f5 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaTest.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaTest.java
@@ -17,11 +17,11 @@
 
 import android.app.Instrumentation;
 import android.content.Intent;
+import android.cts.util.MediaUtils;
 import android.media.CamcorderProfile;
+import android.media.MediaFormat;
 import android.media.MediaRecorder.AudioEncoder;
 import android.media.MediaRecorder.VideoEncoder;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
 import android.os.Environment;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
@@ -30,31 +30,11 @@
 
 public class NativeMediaTest extends ActivityInstrumentationTestCase2<NativeMediaActivity> {
     private static final String TAG = "NativeMediaTest";
-    private static final String MIME_TYPE = "video/h264";
+    private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
     private static final int VIDEO_CODEC = VideoEncoder.H264;
     private static final int NUMBER_PLAY_PAUSE_REPEATITIONS = 10;
     private static final long PLAY_WAIT_TIME_MS = 4000;
 
-    private static boolean hasCodec(String mimeType) {
-        int numCodecs = MediaCodecList.getCodecCount();
-
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; j++) {
-                if (types[j].equalsIgnoreCase(mimeType)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     public NativeMediaTest() {
         super(NativeMediaActivity.class);
     }
@@ -77,9 +57,8 @@
 
     private void runPlayTest(int quality) throws InterruptedException {
         // Don't run the test if the codec isn't supported.
-        if (!hasCodec(MIME_TYPE)) {
-            Log.w(TAG, "Codec " + MIME_TYPE + " not supported.");
-            return;
+        if (!MediaUtils.checkDecoder(MIME_TYPE)) {
+            return; // skip
         }
         // Don't run the test if the quality level isn't supported.
         if (quality != 0) {
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
index b6175be..974eeb7 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
@@ -22,6 +22,7 @@
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.cts.util.FileCopyHelper;
+import android.cts.util.MediaUtils;
 import android.database.Cursor;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecList;
@@ -38,32 +39,13 @@
 
 public class MediaStore_Video_ThumbnailsTest extends AndroidTestCase {
     private static final String TAG = "MediaStore_Video_ThumbnailsTest";
-    private static final String MIME_TYPE = "video/3gpp";
 
     private ContentResolver mResolver;
 
     private FileCopyHelper mFileHelper;
 
-    // TODO: Make a public method selectCodec() in common libraries (e.g. cts/libs/), to avoid
-    // redundant function definitions in this and other media related test files.
-    private static boolean hasCodec(String mimeType) {
-        int numCodecs = MediaCodecList.getCodecCount();
-
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; j++) {
-                if (types[j].equalsIgnoreCase(mimeType)) {
-                    return true;
-                }
-            }
-        }
-        return false;
+    private boolean hasCodec() {
+        return MediaUtils.hasCodecForResourceAndDomain(mContext, R.raw.testvideo, "video/");
     }
 
     @Override
@@ -98,10 +80,10 @@
         int count = getThumbnailCount(Thumbnails.EXTERNAL_CONTENT_URI);
 
         // Don't run the test if the codec isn't supported.
-        if (!hasCodec(MIME_TYPE)) {
+        if (!hasCodec()) {
             // Calling getThumbnail should not generate a new thumbnail.
             assertNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MINI_KIND, null));
-            Log.w(TAG, "Codec " + MIME_TYPE + " not supported. Return from testGetThumbnail.");
+            Log.i(TAG, "SKIPPING testGetThumbnail(): codec not supported");
             return;
         }
 
diff --git a/tests/tests/widget/src/android/widget/cts/VideoViewTest.java b/tests/tests/widget/src/android/widget/cts/VideoViewTest.java
index 6e514f8..d9af514 100644
--- a/tests/tests/widget/src/android/widget/cts/VideoViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/VideoViewTest.java
@@ -21,6 +21,7 @@
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.content.Context;
+import android.cts.util.MediaUtils;
 import android.cts.util.PollingCheck;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecList;
@@ -53,8 +54,6 @@
     private static final int    TEST_VIDEO_DURATION = 11047;
     /** The full name of R.raw.testvideo. */
     private static final String VIDEO_NAME   = "testvideo.3gp";
-    /** The MIME type. */
-    private static final String MIME_TYPE = "video/3gpp";
     /** delta for duration in case user uses different decoders on different
         hardware that report a duration that's different by a few milliseconds */
     private static final int DURATION_DELTA = 100;
@@ -101,26 +100,8 @@
         }
     }
 
-    // TODO: Make a public method selectCodec() in common libraries (e.g. cts/libs/), to avoid
-    // redundant function definitions in this and other media related test files.
-    private static boolean hasCodec(String mimeType) {
-        int numCodecs = MediaCodecList.getCodecCount();
-
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-
-            if (!codecInfo.isEncoder()) {
-                continue;
-            }
-
-            String[] types = codecInfo.getSupportedTypes();
-            for (int j = 0; j < types.length; j++) {
-                if (types[j].equalsIgnoreCase(mimeType)) {
-                    return true;
-                }
-            }
-        }
-        return false;
+    private boolean hasCodec() {
+        return MediaUtils.hasCodecsForResource(mActivity, R.raw.testvideo);
     }
 
     /**
@@ -204,8 +185,8 @@
     public void testPlayVideo1() throws Throwable {
         makeVideoView();
         // Don't run the test if the codec isn't supported.
-        if (!hasCodec(MIME_TYPE)) {
-            Log.w(TAG, "Codec " + MIME_TYPE + " not supported. Return from testPlayVideo1.");
+        if (!hasCodec()) {
+            Log.i(TAG, "SKIPPING testPlayVideo1(): codec is not supported");
             return;
         }
 
@@ -266,8 +247,8 @@
     public void testGetBufferPercentage() throws Throwable {
         makeVideoView();
         // Don't run the test if the codec isn't supported.
-        if (!hasCodec(MIME_TYPE)) {
-            Log.w(TAG, MIME_TYPE + " not supported. Return from testGetBufferPercentage.");
+        if (!hasCodec()) {
+            Log.i(TAG, "SKIPPING testGetBufferPercentage(): codec is not supported");
             return;
         }
 
@@ -309,8 +290,8 @@
 
     public void testGetDuration() throws Throwable {
         // Don't run the test if the codec isn't supported.
-        if (!hasCodec(MIME_TYPE)) {
-            Log.w(TAG, "Codec " + MIME_TYPE + " not supported. Return from testGetDuration.");
+        if (!hasCodec()) {
+            Log.i(TAG, "SKIPPING testGetDuration(): codec is not supported");
             return;
         }