am 8f037002: am f518d4e9: Merge "media: run media tests based on device type and support" into lmp-sprout-dev

* commit '8f037002d11affbec6cb5d79d68dfab4ddfe5783':
  media: run media tests based on device type and support
diff --git a/libs/deviceutil/src/android/cts/util/MediaUtils.java b/libs/deviceutil/src/android/cts/util/MediaUtils.java
index 8e88b47..eab4808 100644
--- a/libs/deviceutil/src/android/cts/util/MediaUtils.java
+++ b/libs/deviceutil/src/android/cts/util/MediaUtils.java
@@ -17,9 +17,11 @@
 
 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;
@@ -29,7 +31,12 @@
 import java.io.IOException;
 
 public class MediaUtils {
-    final public static String TAG = "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.
@@ -117,11 +124,33 @@
         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) {
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
         for (int i = 0; i < ex.getTrackCount(); ++i) {
             MediaFormat format = ex.getTrackFormat(i);
             // only check for audio and video codecs
@@ -129,8 +158,7 @@
             if (!mime.startsWith("audio/") && !mime.startsWith("video/")) {
                 continue;
             }
-            if (mcl.findDecoderForFormat(format) == null) {
-                Log.i(TAG, "no decoder for " + format);
+            if (!canDecode(format)) {
                 return false;
             }
         }
@@ -142,46 +170,69 @@
      */
     public static boolean hasCodecForMediaAndDomain(MediaExtractor ex, String mimePrefix) {
         mimePrefix = mimePrefix.toLowerCase();
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
         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 (mcl.findDecoderForFormat(format) == null) {
-                    Log.i(TAG, "no decoder for " + format);
-                } else {
+                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) {
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        try {
-            AssetFileDescriptor afd = null;
-            MediaExtractor ex = null;
-            try {
-                afd = context.getResources().openRawResourceFd(resourceId);
-                ex = new MediaExtractor();
-                ex.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
-                return hasCodecsForMedia(ex);
-            } finally {
-                if (ex != null) {
-                    ex.release();
-                }
-                if (afd != null) {
-                    afd.close();
-                }
-            }
-        } catch (IOException e) {
-            Log.i(TAG, "could not open resource");
-        }
-        return false;
+        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");
     }
 
     /**
@@ -189,26 +240,90 @@
      */
     public static boolean hasCodecForResourceAndDomain(
             Context context, int resourceId, String mimePrefix) {
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        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 {
-            AssetFileDescriptor afd = null;
-            MediaExtractor ex = null;
-            try {
-                afd = context.getResources().openRawResourceFd(resourceId);
-                ex = new MediaExtractor();
-                ex.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
-                return hasCodecForMediaAndDomain(ex, mimePrefix);
-            } finally {
-                if (ex != null) {
-                    ex.release();
-                }
-                if (afd != null) {
-                    afd.close();
-                }
+            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 resource");
+            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/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 70cb10f..ea7b063 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -22,11 +22,11 @@
 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;
@@ -168,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();
@@ -225,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 {
@@ -848,6 +855,10 @@
     }
 
     private void testDecode(int testVideo, int frameNum) throws Exception {
+        if (!MediaUtils.checkCodecForResource(mContext, testVideo, 0 /* track */)) {
+            return; // skip
+        }
+
         // Decode to Surface.
         Surface s = getActivity().getSurfaceHolder().getSurface();
         int frames1 = countFrames(testVideo, RESET_MODE_NONE, -1 /* eosframe */, s);
@@ -859,483 +870,293 @@
     }
 
     public void testCodecBasicH264() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "SKIPPING testCodecBasicH264(): No codec found.");
-            return;
-        }
         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;
-        }
         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;
-        }
         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;
-        }
         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;
-        }
         testDecode(R.raw.video_480x360_webm_vp8_333kbps_25fps_vorbis_stereo_128kbps_44100hz, 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_44100hz, 240);
     }
 
     public void testH264Decode320x240() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "SKIPPING testH264Decode320x240(): No codec found.");
-            return;
-        }
         testDecode(R.raw.video_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
     public void testH264Decode720x480() throws Exception {
-        if (!hasH264(false)) {
-            Log.i(TAG, "SKIPPING testH264Decode720x480(): No codec found.");
-            return;
-        }
         testDecode(R.raw.video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
     public void testH264Decode30fps1280x720Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 30)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 30));
         }
     }
 
     public void testH264Decode30fps1280x720() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 30)) {
-            Log.i(TAG, "SKIPPING testH264Decode30fps1280x720(): Unsupported profile.");
-            return;
-        }
-
         testDecode(R.raw.video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
     public void testH264Decode60fps1280x720Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 60)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 60));
         }
     }
 
     public void testH264Decode60fps1280x720() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720, 60)) {
-            Log.i(TAG, "SKIPPING testH264Decode60fps1280x720(): Unsupported profile.");
-            return;
-        }
         testDecode(R.raw.video_1280x720_mp4_h264_8192kbps_60fps_aac_stereo_128kbps_44100hz, 596);
     }
 
     public void testH264Decode30fps1920x1080Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 30)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 30));
         }
     }
 
     public void testH264Decode30fps1920x1080() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 30)) {
-            Log.i(TAG, "SKIPPING testH264Decode30fps1920x1080(): Unsupported profile.");
-            return;
-        }
         testDecode(R.raw.video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
     public void testH264Decode60fps1920x1080Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 60)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 60));
         }
     }
 
     public void testH264Decode60fps1920x1080() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_AVC, 1920, 1080, 60)) {
-            Log.i(TAG, "SKIPPING testH264Decode60fps1920x1080(): Unsupported profile.");
-            return;
-        }
         testDecode(R.raw.video_1920x1080_mp4_h264_20480kbps_60fps_aac_stereo_128kbps_44100hz, 596);
     }
 
     public void testVP8Decode320x240() throws Exception {
-        if (!hasVP8(false)) {
-            Log.i(TAG, "SKIPPING testVP8Decode320x240(): No codec found.");
-            return;
-        }
         testDecode(R.raw.video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
     }
 
     public void testVP8Decode640x360() throws Exception {
-        if (!hasVP8(false)) {
-            Log.i(TAG, "SKIPPING testVP8Decode640x360(): No codec found.");
-            return;
-        }
         testDecode(R.raw.video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
     }
 
     public void testVP8Decode30fps1280x720Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 30)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 30));
         }
     }
 
     public void testVP8Decode30fps1280x720() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 30)) {
-            Log.i(TAG, "SKIPPING testVP8Decode30fps1280x720(): Unsupported profile.");
-            return;
-        }
         testDecode(R.raw.video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
     }
 
     public void testVP8Decode60fps1280x720Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 60)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 60));
         }
     }
 
     public void testVP8Decode60fps1280x720() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1280, 720, 60)) {
-            Log.i(TAG, "SKIPPING testVP8Decode60fps1280x720(): Unsupported profile.");
-            return;
-        }
         testDecode(R.raw.video_1280x720_webm_vp8_8192kbps_60fps_vorbis_stereo_128kbps_44100hz, 249);
     }
 
     public void testVP8Decode30fps1920x1080Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 30)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 30));
         }
     }
 
     public void testVP8Decode30fps1920x1080() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 30)) {
-            Log.i(TAG, "SKIPPING testVP8Decode30fps1920x1080(): Unsupported profile.");
-            return;
-        }
         testDecode(R.raw.video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_44100hz,
                 249);
     }
 
     public void testVP8Decode60fps1920x1080Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 60)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 60));
         }
     }
 
     public void testVP8Decode60fps1920x1080() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP8, 1920, 1080, 60)) {
-            Log.i(TAG, "SKIPPING testVP8Decode60fps1920x1080(): Unsupported profile.");
-            return;
-        }
         testDecode(R.raw.video_1920x1080_webm_vp8_20480kbps_60fps_vorbis_stereo_128kbps_44100hz,
                 249);
     }
 
     public void testVP9Decode320x240() throws Exception {
-        if (!hasVP9(false)) {
-            Log.i(TAG, "SKIPPING testVP9Decode320x240(): No codec found.");
-            return;
-        }
         testDecode(R.raw.video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
     }
 
     public void testVP9Decode640x360() throws Exception {
-        if (!hasVP9(false)) {
-            Log.i(TAG, "SKIPPING testVP9Decode640x360(): No codec found.");
-            return;
-        }
         testDecode(R.raw.video_640x360_webm_vp9_1638kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
     }
 
     public void testVP9Decode30fps1280x720Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP9, 1280, 720, 30)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_VP9, 1280, 720, 30));
         }
     }
 
     public void testVP9Decode30fps1280x720() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP9, 1280, 720, 30)) {
-            Log.i(TAG, "SKIPPING testVP8Decode30fps1920x1080(): Unsupported profile.");
-            return;
-        }
         testDecode(R.raw.video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_44100hz, 249);
     }
 
     public void testVP9Decode30fps1920x1080() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP9, 1920, 1080, 30)) {
-            Log.d(TAG, "SKIPPING testVP9Decode30fps1920x1080(): Unsupported optional profile.");
-            return;
-        }
-
         testDecode(R.raw.video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_44100hz,
                 249);
     }
 
     public void testVP9Decode30fps3840x2160() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_VP9, 3840, 2160, 30)) {
-            Log.d(TAG, "SKIPPING testVP9Decode30fps3840x2160(): Unsupported optional profile.");
-            return;
-        }
-
         testDecode(R.raw.video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_44100hz,
                 249);
     }
 
     public void testHEVCDecode352x288() throws Exception {
-        if (!hasHEVC(false)) {
-            Log.i(TAG, "SKIPPING testHEVCDecode352x288(): No codec found.");
-            return;
-        }
         testDecode(R.raw.video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
     public void testHEVCDecode720x480() throws Exception {
-        if (!hasHEVC(false)) {
-            Log.i(TAG, "SKIPPING testHEVCDecode720x480(): No codec found.");
-            return;
-        }
         testDecode(R.raw.video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
     public void testHEVCDecode30fps1280x720Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, 1280, 720, 30)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_HEVC, 1280, 720, 30));
         }
     }
 
     public void testHEVCDecode30fps1280x720() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, 1280, 720, 30)) {
-            Log.i(TAG, "SKIPPING testHEVCDecode30fps1280x720(): Unsupported profile.");
-            return;
-        }
         testDecode(R.raw.video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
     public void testHEVCDecode30fps1920x1080Tv() throws Exception {
-        if (isTv() && !isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, 1920, 1080, 30)) {
-            fail("Profile is required for TV device.");
+        if (checkTv()) {
+            assertTrue(MediaUtils.canDecodeVideo(MediaFormat.MIMETYPE_VIDEO_HEVC, 1920, 1080, 30));
         }
     }
 
     public void testHEVCDecode30fps1920x1080() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, 1920, 1080, 30)) {
-            Log.i(TAG, "SKIPPING testHEVCDecode30fps1920x1080(): Unsupported profile.");
-            return;
-        }
         testDecode(R.raw.video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
     public void testHEVCDecode30fps2840x2160() throws Exception {
-        if (!isDecodeFormatSupported(MediaFormat.MIMETYPE_VIDEO_HEVC, 2840, 2160, 30)) {
-            Log.i(TAG, "SKIPPING testHEVCDecode30fps2840x2160(): Unsupported optional profile.");
-            return;
-        }
         testDecode(R.raw.video_2840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz, 299);
     }
 
-    public void testCodecEarlyEOSH263() throws Exception {
-        if (!hasH263(false)) {
-            Log.i(TAG, "SKIPPING testCodecEarlyEOSH263(): No codec found.");
-            return;
+    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(
+        int frames1 = countFrames(resid, RESET_MODE_NONE, eosFrame, s);
+        assertEquals("wrong number of frames decoded", eosFrame, frames1);
+    }
+
+    public void testCodecEarlyEOSH263() throws Exception {
+        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(
+        testCodecEarlyEOS(
                 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);
+                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(
+        testCodecEarlyEOS(
                 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);
+                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);
     }
 
     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);
     }
 
     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);
     }
 
     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);
@@ -1364,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);
@@ -1443,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>();
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 f966108..afed27b 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
@@ -16,9 +16,13 @@
 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;
@@ -33,52 +37,43 @@
 public class MediaCodecCapabilitiesTest extends MediaPlayerTestBase {
 
     private static final String TAG = "MediaCodecCapabilitiesTest";
-    private static final String AVC_MIME  = MediaFormat.MIMETYPE_VIDEO_AVC;
-    private static final String HEVC_MIME = MediaFormat.MIMETYPE_VIDEO_HEVC;
     private static final int PLAY_TIME_MS = 30000;
 
     // 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 (!hasH264(true /* isEncoder */)) {
-            Log.d(TAG, "SKIPPING testH264EncoderProfileAndLevel: No codec found.");
-            return;
-        }
-        boolean testLevel = true;
-        if (!supports(AVC_MIME, true /* isEncoder */, CodecProfileLevel.AVCProfileBaseline,
-                CodecProfileLevel.AVCLevel3, testLevel)) {
-            fail("H.264 Baseline Profile Level 3 support is required by CDD");
+        if (!MediaUtils.checkEncoder(MIMETYPE_VIDEO_AVC)) {
+            return; // skip
         }
 
-        if (supports(AVC_MIME, true /* isEncoder */, CodecProfileLevel.AVCProfileMain,
-                    CodecProfileLevel.AVCLevel4, testLevel)) {
-            if (!supports(AVC_MIME, false, CodecProfileLevel.AVCProfileMain,
-                    CodecProfileLevel.AVCLevel4, testLevel)) {
-                fail("If H.264 Main Profile Level 4 encoding is supported, " +
-                        "the device must also support is the same profile and level for decoding.");
-            }
+        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 (!hasH264(false /* isEncoder */)) {
-            Log.d(TAG, "SKIPPING testH264DecoderProfileAndLevel: No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MIMETYPE_VIDEO_AVC)) {
+            return; // skip
         }
-        if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline,
-                CodecProfileLevel.AVCLevel3)) {
-            fail("H.264 Baseline Profile Level 3 support is required by CDD");
-        }
+
+        assertTrue(
+                "H.264 must support Baseline Profile Level 3",
+                hasDecoder(MIMETYPE_VIDEO_AVC, AVCProfileBaseline, AVCLevel3));
+
         if (isTv()) {
-            if (!supports(AVC_MIME, CodecProfileLevel.AVCProfileHigh,
-                    CodecProfileLevel.AVCLevel42)) {
-                fail("H.264 High Profile Level 4.2 support is required by CDD for " +
-                        "television devices");
-            }
-      }
+            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
@@ -87,53 +82,39 @@
     // When the UHD video decoding profile is supported, it MUST support Main10 Level 5 Main
     // Tier profile.
     public void testH265DecoderProfileAndLevel() throws Exception {
-        MediaCodecInfo info = getMediaCodecInfo(HEVC_MIME, false /* isEncoder */);
-        if (info == null) {
-            Log.d(TAG, "SKIPPING testH265DecoderProfileAndLevel: No codec found.");
-            return;
+        if (!MediaUtils.checkDecoder(MIMETYPE_VIDEO_HEVC)) {
+            return; // skip
         }
 
-        if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel3)) {
-            fail("H.265 Main Profile Level 3 Main tier support is required by CDD");
-        }
+        assertTrue(
+                "H.265 must support Main Profile Main Tier Level 3",
+                hasDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel3));
+
         if (isTv()) {
-            if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                    CodecProfileLevel.HEVCMainTierLevel41)) {
-                fail("H.265 Main Profile Level 4.1 Main tier support is required by CDD for " +
-                        "television devices");
-            }
+            assertTrue(
+                    "H.265 must support Main Profile Main Tier Level 4.1 on TV",
+                    hasDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel41));
         }
 
-        MediaCodecInfo.CodecCapabilities cCaps = info.getCapabilitiesForType(HEVC_MIME);
-        MediaCodecInfo.VideoCapabilities vCaps = cCaps.getVideoCapabilities();
-        if (vCaps.areSizeAndRateSupported(3840, 2160, 30)) {
-            if (!supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain10,
-                    CodecProfileLevel.HEVCMainTierLevel5)) {
-                fail("H.265 Main10 Level 5 Main Tier support is required by CDD when " +
-                        "the UHD video decoding profile is supported");
-            }
+        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 (hasCodec(AVC_MIME) && !supports(AVC_MIME, CodecProfileLevel.AVCProfileBaseline,
-                CodecProfileLevel.AVCLevel1)) {
-            fail("AVCLevel1 support is required by CDD");
+        if (!checkDecoder(MIMETYPE_VIDEO_AVC, AVCProfileBaseline, AVCLevel1)) {
+            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 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"
@@ -145,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"
@@ -163,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"
@@ -182,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"
@@ -204,127 +170,118 @@
     }
 
     public void testHevcMain1() throws Exception {
-        if (hasCodec(HEVC_MIME) && !supports(HEVC_MIME, CodecProfileLevel.HEVCProfileMain,
-                CodecProfileLevel.HEVCMainTierLevel1)) {
-            fail("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, false /* isEncoder */, 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, false /* isEncoder */, profile, level, true);
+    private boolean hasDecoder(String mime, int profile, int level) {
+        return supports(mime, false /* isEncoder */, profile, level);
     }
 
-    private boolean supports(String mimeType, boolean isEncoder,
-            int profile, int level, boolean testLevel) {
-        int numCodecs = MediaCodecList.getCodecCount();
-        for (int i = 0; i < numCodecs; i++) {
-            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
-            if (isEncoder != 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 1019f3f..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()) {
@@ -375,29 +394,40 @@
         List<CodecType> list = new ArrayList<CodecType>(16);
 
         // Mandatory audio codecs
-        list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AMR_WB, false));   // amrwb decoder
-        list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AMR_WB, true));    // amrwb encoder
 
         // flac decoder is not omx-based yet
         // list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_FLAC, false));  // flac decoder
-        list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_FLAC, true));      // flac encoder
         list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_MPEG, false));     // mp3 decoder
-        list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AAC, false));      // aac decoder
-        list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_AAC, true));       // aac encoder
         list.add(new CodecType(MediaFormat.MIMETYPE_AUDIO_VORBIS, false));   // vorbis decoder
-        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_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(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_HEVC, false));   // hevc decoder
-        list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_H263, false));   // h263 decoder
-        list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_H263, true));    // h263 encoder
-        list.add(new CodecType(MediaFormat.MIMETYPE_VIDEO_MPEG4, false));  // m4v decoder
-        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
+
+        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 33a0ee4..1ff5048 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -1005,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/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 986cd08..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,81 +293,6 @@
     }
 
     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 MediaCodecInfo getMediaCodecInfo(String mimeType, boolean isEncoder) {
-        MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        for (MediaCodecInfo info : list.getCodecInfos()) {
-            if (isEncoder != info.isEncoder()) {
-                continue;
-            }
-            for (String type : info.getSupportedTypes()) {
-                if (type.equalsIgnoreCase(mimeType)) {
-                    return info;
-                }
-            }
-        }
-        return null;
-    }
-
-    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()
@@ -377,23 +300,12 @@
     }
 
     public boolean isTv() {
-        PackageManager packageManager = getInstrumentation().getTargetContext().getPackageManager();
-        return packageManager.hasSystemFeature("android.hardware.type.television") ||
-                packageManager.hasSystemFeature("android.software.leanback");
+        PackageManager pm = getInstrumentation().getTargetContext().getPackageManager();
+        return pm.hasSystemFeature(pm.FEATURE_TELEVISION)
+                && pm.hasSystemFeature(pm.FEATURE_LEANBACK);
     }
 
-    private static boolean isFormatSupported(
-            String mimeType, int w, int h, int frameRate, boolean isEncoder) {
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        MediaFormat format = MediaFormat.createVideoFormat(mimeType, w, h);
-        format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
-        String codec = isEncoder
-                ? mcl.findEncoderForFormat(format)
-                : mcl.findDecoderForFormat(format);
-        return (codec != null);
-    }
-
-    public static boolean isDecodeFormatSupported(String mimeType, int w, int h, int frameRate) {
-        return isFormatSupported(mimeType, w, h, frameRate, false /* isEncoder */);
+    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..2d901f6 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;
@@ -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_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);
+        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_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);
+        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/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) {