Merge "add more PollingCheck" into jb-dev
diff --git a/hostsidetests/monkey/src/com/android/cts/monkey/PackageTest.java b/hostsidetests/monkey/src/com/android/cts/monkey/PackageTest.java
index 0e8f276..3859f19 100644
--- a/hostsidetests/monkey/src/com/android/cts/monkey/PackageTest.java
+++ b/hostsidetests/monkey/src/com/android/cts/monkey/PackageTest.java
@@ -16,22 +16,32 @@
 
 package com.android.cts.monkey;
 
+import java.util.regex.Pattern;
+
 public class PackageTest extends AbstractMonkeyTest {
 
+    private static final Pattern ALLOW_MONKEY =
+            Pattern.compile("^.*Allowing.*cmp=com\\.android\\.cts\\.monkey/\\.MonkeyActivity.*$",
+                    Pattern.MULTILINE);
+
+    private static final Pattern ALLOW_CHIMP =
+            Pattern.compile("^.*Allowing.*cmp=com\\.android\\.cts\\.monkey2/\\.ChimpActivity.*$",
+                    Pattern.MULTILINE);
+
     public void testSinglePackage() throws Exception {
         String out = mDevice.executeShellCommand("monkey -v -p " + PKGS[0] + " 5000");
-        assertTrue(out, out.contains("cmp=com.android.cts.monkey/.MonkeyActivity"));
-        assertFalse(out, out.contains("cmp=com.android.cts.monkey2/.ChimpActivity"));
+        assertTrue(out, ALLOW_MONKEY.matcher(out).find());
+        assertFalse(out, ALLOW_CHIMP.matcher(out).find());
 
         out = mDevice.executeShellCommand("monkey -v -p " + PKGS[1] + " 5000");
-        assertFalse(out, out.contains("cmp=com.android.cts.monkey/.MonkeyActivity"));
-        assertTrue(out, out.contains("cmp=com.android.cts.monkey2/.ChimpActivity"));
+        assertFalse(out, ALLOW_MONKEY.matcher(out).find());
+        assertTrue(out, ALLOW_CHIMP.matcher(out).find());
     }
 
     public void testMultiplePackages() throws Exception {
         String out = mDevice.executeShellCommand("monkey -v -p " + PKGS[0]
                 + " -p " + PKGS[1] + " 5000");
-        assertTrue(out, out.contains("cmp=com.android.cts.monkey/.MonkeyActivity"));
-        assertTrue(out, out.contains("cmp=com.android.cts.monkey2/.ChimpActivity"));
+        assertTrue(out, ALLOW_MONKEY.matcher(out).find());
+        assertTrue(out, ALLOW_CHIMP.matcher(out).find());
     }
 }
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index d742509..9228564 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -67,6 +67,11 @@
       "org.apache.harmony.luni.tests.java.net.URLConnectionTest",
       "org.apache.harmony.xnet.provider.jsse.NativeCryptoTest#test_SSL_do_handshake_server_timeout"
     ]
+  },
+  {
+    description: "MediaPlayerFlakyNetworkTest tests",
+    name: "android.media.cts.MediaPlayerFlakyNetworkTest",
+    bug: 6782035
   }
 ]
 
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
new file mode 100644
index 0000000..d89d992
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+
+import android.media.MediaCodecList;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecProfileLevel;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.File;
+import java.util.List;
+import java.util.ArrayList;
+
+public class MediaCodecListTest extends AndroidTestCase {
+
+    private static final String TAG = "MediaCodecListTest";
+    private static final String MEDIA_CODEC_XML_FILE = "/etc/media_codecs.xml";
+
+    class CodecType {
+        CodecType(String type, boolean isEncoder) {
+            mMimeTypeName = type;
+            mIsEncoder = isEncoder;
+        }
+
+        boolean equals(CodecType codecType) {
+            return (mMimeTypeName.compareTo(codecType.mMimeTypeName) == 0) &&
+                    mIsEncoder == codecType.mIsEncoder;
+        }
+
+        String mMimeTypeName;
+        boolean mIsEncoder;
+    };
+
+    public static void testMediaCodecXmlFileExist() {
+        File file = new File(MEDIA_CODEC_XML_FILE);
+        assertTrue("/etc/media_codecs.xml does not exist", file.exists());
+    }
+
+    public void testRequiredMediaCodecList() {
+        List<CodecType> requiredList = getRequiredCodecTypes();
+        List<CodecType> supportedList = getSupportedCodecTypes();
+        assertTrue(areRequiredCodecTypesSupported(requiredList, supportedList));
+    }
+
+    // H263 baseline profile must be supported
+    public void testIsH263BaselineProfileSupported() {
+        int profile = CodecProfileLevel.H263ProfileBaseline;
+        assertTrue(checkProfileSupported("video/3gpp", false, profile));
+        assertTrue(checkProfileSupported("video/3gpp", true, profile));
+    }
+
+    // AVC baseline profile must be supported
+    public void testIsAVCBaselineProfileSupported() {
+        int profile = CodecProfileLevel.AVCProfileBaseline;
+        assertTrue(checkProfileSupported("video/avc", false, profile));
+        assertTrue(checkProfileSupported("video/avc", true, profile));
+    }
+
+    // MPEG4 simple profile must be supported
+    public void testIsM4VSimpleProfileSupported() {
+        int profile = CodecProfileLevel.MPEG4ProfileSimple;
+        assertTrue(checkProfileSupported("video/mp4v-es", false, profile));
+
+        // FIXME: no support for M4v simple profile video encoder
+        // assertTrue(checkProfileSupported("video/mp4v-es", true, profile));
+    }
+
+    /*
+     * Find whether the given codec is supported
+     */
+    private boolean checkProfileSupported(
+        String codecName, boolean isEncoder, int profile) {
+
+        boolean isSupported = false;
+
+        int codecCount = MediaCodecList.getCodecCount();
+        for (int i = 0; i < codecCount; ++i) {
+            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+            String[] types = info.getSupportedTypes();
+
+            if (isEncoder != info.isEncoder()) {
+                continue;
+            }
+
+            for (int j = 0; j < types.length; ++j) {
+                if (types[j].compareTo(codecName) == 0) {
+                    CodecCapabilities cap = info.getCapabilitiesForType(types[j]);
+                    CodecProfileLevel[] profileLevels = cap.profileLevels;
+                    for (int k = 0; k < profileLevels.length; ++k) {
+                        if (profileLevels[k].profile == profile) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /*
+     * Find whether all required media codec types are supported
+     */
+    private boolean areRequiredCodecTypesSupported(
+        List<CodecType> requiredList, List<CodecType> supportedList) {
+        for (CodecType requiredCodec: requiredList) {
+            boolean isSupported = false;
+            for (CodecType supportedCodec: supportedList) {
+                if (requiredCodec.equals(supportedCodec)) {
+                    isSupported = true;
+                }
+            }
+            if (!isSupported) {
+                String codec = requiredCodec.mMimeTypeName
+                                + ", " + (requiredCodec.mIsEncoder? "encoder": "decoder");
+                Log.e(TAG, "Media codec (" + codec + ") is not supported");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /*
+     * Find all the media codec types are supported.
+     */
+    private List<CodecType> getSupportedCodecTypes() {
+        int codecCount = MediaCodecList.getCodecCount();
+        assertTrue("Unexpected media codec count", codecCount > 0);
+        List<CodecType> supportedList = new ArrayList<CodecType>(codecCount);
+        for (int i = 0; i < codecCount; ++i) {
+            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+            String[] types = info.getSupportedTypes();
+            assertTrue("Unexpected number of supported types", types.length > 0);
+            boolean isEncoder = info.isEncoder();
+            for (int j = 0; j < types.length; ++j) {
+                supportedList.add(new CodecType(types[j], isEncoder));
+            }
+        }
+        return supportedList;
+    }
+
+    /*
+     * This list should be kept in sync with the CCD document
+     * See http://developer.android.com/guide/appendix/media-formats.html
+     */
+    private List<CodecType> getRequiredCodecTypes() {
+        List<CodecType> list = new ArrayList<CodecType>(16);
+
+        // Mandatory audio codecs
+        list.add(new CodecType("audio/amr-wb", false));         // amrwb decoder
+        list.add(new CodecType("audio/amr-wb", true));          // amrwb encoder
+
+        // flac decoder is not omx-based yet
+        // list.add(new CodecType("audio/flac", false));        // flac decoder
+        list.add(new CodecType("audio/flac", true));            // flac encoder
+        list.add(new CodecType("audio/mpeg", false));           // mp3 decoder
+        list.add(new CodecType("audio/mp4a-latm", false));      // aac decoder
+        list.add(new CodecType("audio/mp4a-latm", true));       // aac encoder
+        list.add(new CodecType("audio/vorbis", false));         // vorbis decoder
+        list.add(new CodecType("audio/3gpp", false));           // amrnb decoder
+        list.add(new CodecType("audio/3gpp", true));            // amrnb encoder
+
+        // Mandatory video codecs
+        list.add(new CodecType("video/avc", false));            // avc decoder
+        list.add(new CodecType("video/avc", true));             // avc encoder
+        list.add(new CodecType("video/3gpp", false));           // h263 decoder
+        list.add(new CodecType("video/3gpp", true));            // h263 encoder
+        list.add(new CodecType("video/mp4v-es", false));        // m4v decoder
+        list.add(new CodecType("video/mp4v-es", true));         // m4v encoder
+        list.add(new CodecType("video/x-vnd.on2.vp8", false));  // vp8 decoder
+
+        return list;
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index bbeffe0..4808bc0 100755
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -29,6 +29,7 @@
 import android.telephony.SmsMessage;
 import android.telephony.TelephonyManager;
 import android.test.AndroidTestCase;
+import android.util.Log;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -41,6 +42,7 @@
  */
 public class SmsManagerTest extends AndroidTestCase {
 
+    private static final String TAG = "SmsManagerTest";
     private static final String LONG_TEXT =
         "This is a very long text. This text should be broken into three " +
         "separate messages.This is a very long text. This text should be broken into " +
@@ -82,7 +84,30 @@
                     "310000",   // Tracfone
                     "46003",    // China Telecom
                     "311230",   // C SPire Wireless + Celluar South
-                    "310600"    // Cellcom
+                    "310600",    // Cellcom
+                    // Verizon
+                    "310004",
+                    "310012",
+                    "311280",
+                    "311281",
+                    "311282",
+                    "311283",
+                    "311284",
+                    "311285",
+                    "311286",
+                    "311287",
+                    "311288",
+                    "311289",
+                    "311480",
+                    "311481",
+                    "311482",
+                    "311483",
+                    "311484",
+                    "311485",
+                    "311486",
+                    "311487",
+                    "311488",
+                    "311489"
             );
 
     // List of network operators that doesn't support Data(binary) SMS message
@@ -96,7 +121,30 @@
                     "30237",    // Fido
                     "45008",    // KT
                     "45005",    // SKT Mobility
-                    "45002"     // SKT Mobility
+                    "45002",     // SKT Mobility
+                    // Verizon
+                    "310004",
+                    "310012",
+                    "311280",
+                    "311281",
+                    "311282",
+                    "311283",
+                    "311284",
+                    "311285",
+                    "311286",
+                    "311287",
+                    "311288",
+                    "311289",
+                    "311480",
+                    "311481",
+                    "311482",
+                    "311483",
+                    "311484",
+                    "311485",
+                    "311486",
+                    "311487",
+                    "311488",
+                    "311489"
             );
 
     // List of network operators that doesn't support Maltipart SMS message
@@ -323,12 +371,11 @@
                 mReceivedDataSms = true;
                 mReceivedText=sb.toString();
             }
+            Log.i(TAG, "onReceive " + intent.getAction());
             if (intent.getAction().equals(mAction)) {
                 synchronized (mLock) {
                     mCalls += 1;
-                    if (mCalls >= mExpectedCalls) {
-                        mLock.notify();
-                    }
+                    mLock.notify();
                 }
             }
         }
diff --git a/tests/tests/view/src/android/view/cts/SurfaceViewTest.java b/tests/tests/view/src/android/view/cts/SurfaceViewTest.java
index 05769db..2d61559 100644
--- a/tests/tests/view/src/android/view/cts/SurfaceViewTest.java
+++ b/tests/tests/view/src/android/view/cts/SurfaceViewTest.java
@@ -143,10 +143,10 @@
         new PollingCheck() {
             @Override
             protected boolean check() {
-                return mockSurfaceView.isDetachedFromWindow();
+                return mockSurfaceView.isDetachedFromWindow() &&
+                       !mockSurfaceView.isShown();
             }
         }.run();
-        assertFalse(mockSurfaceView.isShown());
     }
 
     private void sleep(long time) {
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index da07f3b..ebb35e2 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -142,7 +142,7 @@
 
     @Option(name = "reboot-wait-time", description =
             "Additional wait time in ms after boot complete. Meaningful only with reboot-per-package option")
-    private int mRebootWaitTimeMSec = 120000;
+    private int mRebootWaitTimeMSec = 2 * 60 * 1000;
 
     @Option(name = "reboot-interval", description =
             "Interval between each reboot in min. Meaningful only with reboot-per-package option")
@@ -348,6 +348,10 @@
             // always collect the device info, even for resumed runs, since test will likely be
             // running on a different device
             collectDeviceInfo(getDevice(), mCtsBuild, listener);
+            if (mRemainingTestPkgs.size() > 1) {
+                Log.i(LOG_TAG, "Initial reboot for multiple packages");
+                rebootDevice();
+            }
             long prevTime = System.currentTimeMillis();
             long intervalInMSec = mRebootIntervalMin * 60 * 1000;
             while (!mRemainingTestPkgs.isEmpty()) {
@@ -369,27 +373,7 @@
                     if ((currentTime - prevTime) > intervalInMSec) {
                         Log.i(LOG_TAG, String.format("Rebooting after running package %s",
                                 knownTests.getPackageDef().getName()));
-                        final int TIMEOUT_MS = 4 * 60 * 1000;
-                        TestDeviceOptions options = mDevice.getOptions();
-                        // store default value and increase time-out for reboot
-                        int rebootTimeout = options.getRebootTimeout();
-                        long onlineTimeout = options.getOnlineTimeout();
-                        options.setRebootTimeout(TIMEOUT_MS);
-                        options.setOnlineTimeout(TIMEOUT_MS);
-                        mDevice.setOptions(options);
-
-                        mDevice.reboot();
-
-                        // restore default values
-                        options.setRebootTimeout(rebootTimeout);
-                        options.setOnlineTimeout(onlineTimeout);
-                        mDevice.setOptions(options);
-                        Log.i(LOG_TAG, "Rebooting done");
-                        try {
-                            Thread.sleep(mRebootWaitTimeMSec);
-                        } catch (InterruptedException e) {
-                            Log.i(LOG_TAG, "Boot wait interrupted");
-                        }
+                        rebootDevice();
                         prevTime = System.currentTimeMillis();
                     }
                 }
@@ -411,6 +395,30 @@
         }
     }
 
+    private void rebootDevice() throws DeviceNotAvailableException {
+        final int TIMEOUT_MS = 4 * 60 * 1000;
+        TestDeviceOptions options = mDevice.getOptions();
+        // store default value and increase time-out for reboot
+        int rebootTimeout = options.getRebootTimeout();
+        long onlineTimeout = options.getOnlineTimeout();
+        options.setRebootTimeout(TIMEOUT_MS);
+        options.setOnlineTimeout(TIMEOUT_MS);
+        mDevice.setOptions(options);
+
+        mDevice.reboot();
+
+        // restore default values
+        options.setRebootTimeout(rebootTimeout);
+        options.setOnlineTimeout(onlineTimeout);
+        mDevice.setOptions(options);
+        Log.i(LOG_TAG, "Rebooting done");
+        try {
+            Thread.sleep(mRebootWaitTimeMSec);
+        } catch (InterruptedException e) {
+            Log.i(LOG_TAG, "Boot wait interrupted");
+        }
+    }
+
     /**
      * Build the list of test packages to run
      */