Merge remote branch 'goog/honeycomb-mr2' into ics-mr0

Conflicts:
	apps/CtsVerifier/jni/verifier/com_android_cts_verifier_os_FileUtils.cpp

Change-Id: I2d92aea5a045dca9e758f7cc2d2746ddb52bd726
diff --git a/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_os_FileUtils.cpp b/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_os_FileUtils.cpp
index 9c69f1a..f2b8034 100644
--- a/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_os_FileUtils.cpp
+++ b/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_os_FileUtils.cpp
@@ -20,6 +20,7 @@
 #include <sys/stat.h>
 #include <grp.h>
 #include <pwd.h>
+#include <unistd.h>
 
 static jfieldID gFileStatusDevFieldID;
 static jfieldID gFileStatusInoFieldID;
@@ -33,6 +34,7 @@
 static jfieldID gFileStatusAtimeFieldID;
 static jfieldID gFileStatusMtimeFieldID;
 static jfieldID gFileStatusCtimeFieldID;
+static jfieldID gFileStatusExecutableID;
 
 /* Copied from hidden API: frameworks/base/core/jni/android_os_FileUtils.cpp */
 jboolean com_android_cts_verifier_os_FileUtils_getFileStatus(JNIEnv* env, jobject thiz,
@@ -60,6 +62,11 @@
             env->SetLongField(fileStatus, gFileStatusMtimeFieldID, s.st_mtime);
             env->SetLongField(fileStatus, gFileStatusCtimeFieldID, s.st_ctime);
         }
+        if (access(pathStr, X_OK) == 0) {
+            env->SetBooleanField(fileStatus, gFileStatusExecutableID, JNI_TRUE);
+        } else {
+            env->SetBooleanField(fileStatus, gFileStatusExecutableID, JNI_FALSE);
+        }
     }
 
     env->ReleaseStringUTFChars(path, pathStr);
@@ -107,6 +114,7 @@
     gFileStatusAtimeFieldID = env->GetFieldID(fileStatusClass, "atime", "J");
     gFileStatusMtimeFieldID = env->GetFieldID(fileStatusClass, "mtime", "J");
     gFileStatusCtimeFieldID = env->GetFieldID(fileStatusClass, "ctime", "J");
+    gFileStatusExecutableID = env->GetFieldID(fileStatusClass, "executable", "Z");
 
     return env->RegisterNatives(clazz, gMethods, 
             sizeof(gMethods) / sizeof(JNINativeMethod)); 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/os/FileUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/os/FileUtils.java
index c767e7a..5633c16 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/os/FileUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/os/FileUtils.java
@@ -62,6 +62,7 @@
         private long atime;
         private long mtime;
         private long ctime;
+        private boolean executable;
 
         public int getUid() {
             return uid;
@@ -90,6 +91,10 @@
         public boolean isSetGid() {
             return hasModeFlag(mode, S_ISGID);
         }
+
+        public boolean isExecutableByCTS() {
+            return executable;
+        }
     }
 
     /**
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/suid/SuidFilesActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/suid/SuidFilesActivity.java
index 7d99c2d..ac290f2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/suid/SuidFilesActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/suid/SuidFilesActivity.java
@@ -231,9 +231,11 @@
             @Override
             public boolean accept(File pathname) {
                 if (FileUtils.getFileStatus(pathname.getPath(), status, true)) {
+                    // only files with setUid which can be executable by CTS are reported.
                     return !status.isDirectory()
                             && !status.isSymbolicLink()
-                            && status.isSetUid();
+                            && status.isSetUid()
+                            && status.isExecutableByCTS();
                 } else {
                     Log.w(TAG, "Could not stat " + pathname);
                     return false;
diff --git a/tests/res/raw/a_4_aac.mp4 b/tests/res/raw/a_4_aac.mp4
new file mode 100644
index 0000000..05a776f
--- /dev/null
+++ b/tests/res/raw/a_4_aac.mp4
Binary files differ
diff --git a/tests/res/raw/b_5_aac.mp4 b/tests/res/raw/b_5_aac.mp4
new file mode 100644
index 0000000..9bce44d
--- /dev/null
+++ b/tests/res/raw/b_5_aac.mp4
Binary files differ
diff --git a/tests/res/raw/c_sharp_5_aac.mp4 b/tests/res/raw/c_sharp_5_aac.mp4
new file mode 100644
index 0000000..1e7f988
--- /dev/null
+++ b/tests/res/raw/c_sharp_5_aac.mp4
Binary files differ
diff --git a/tests/res/raw/e_5_aac.mp4 b/tests/res/raw/e_5_aac.mp4
new file mode 100644
index 0000000..95bad2a
--- /dev/null
+++ b/tests/res/raw/e_5_aac.mp4
Binary files differ
diff --git a/tests/res/raw/g_sharp_5_aac.mp4 b/tests/res/raw/g_sharp_5_aac.mp4
new file mode 100644
index 0000000..a357912
--- /dev/null
+++ b/tests/res/raw/g_sharp_5_aac.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/SoundPoolAacTest.java b/tests/tests/media/src/android/media/cts/SoundPoolAacTest.java
new file mode 100644
index 0000000..edd4d58
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/SoundPoolAacTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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 com.android.cts.stub.R;
+
+public class SoundPoolAacTest extends SoundPoolTest {
+
+    @Override
+    protected int getSoundA() {
+        return R.raw.a_4_aac;
+    }
+
+    @Override
+    protected int getSoundCs() {
+        return R.raw.c_sharp_5_aac;
+    }
+
+    @Override
+    protected int getSoundE() {
+        return R.raw.e_5_aac;
+    }
+
+    @Override
+    protected int getSoundB() {
+        return R.raw.b_5_aac;
+    }
+
+    @Override
+    protected int getSoundGs() {
+        return R.raw.g_sharp_5_aac;
+    }
+
+    @Override
+    protected String getFileName() {
+        return "a_4_aac.mp4";
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/SoundPoolOggTest.java b/tests/tests/media/src/android/media/cts/SoundPoolOggTest.java
new file mode 100644
index 0000000..14bb47e
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/SoundPoolOggTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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 com.android.cts.stub.R;
+
+public class SoundPoolOggTest extends SoundPoolTest {
+
+    @Override
+    protected int getSoundA() {
+        return R.raw.a_4;
+    }
+
+    @Override
+    protected int getSoundCs() {
+        return R.raw.c_sharp_5;
+    }
+
+    @Override
+    protected int getSoundE() {
+        return R.raw.e_5;
+    }
+
+    @Override
+    protected int getSoundB() {
+        return R.raw.b_5;
+    }
+
+    @Override
+    protected int getSoundGs() {
+        return R.raw.g_sharp_5;
+    }
+
+    @Override
+    protected String getFileName() {
+        return "a_4.ogg";
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/SoundPoolTest.java b/tests/tests/media/src/android/media/cts/SoundPoolTest.java
index 2764c8b..d5b33b4 100644
--- a/tests/tests/media/src/android/media/cts/SoundPoolTest.java
+++ b/tests/tests/media/src/android/media/cts/SoundPoolTest.java
@@ -36,29 +36,46 @@
 import java.io.InputStream;
 
 @TestTargetClass(SoundPool.class)
-public class SoundPoolTest extends AndroidTestCase {
+abstract class SoundPoolTest extends AndroidTestCase {
 
     private static final int SOUNDPOOL_STREAMS = 4;
-    private static final int SOUND_A = R.raw.a_4;
-    private static final int SOUND_CS = R.raw.c_sharp_5;
-    private static final int SOUND_E = R.raw.e_5;
-    private static final int SOUND_B = R.raw.b_5;
-    private static final int SOUND_GS = R.raw.g_sharp_5;
     private static final int PRIORITY = 1;
     private static final int LOUD = 20;
     private static final int QUIET = LOUD / 2;
     private static final int SILENT = 0;
-
-    private static final int[] SOUNDS = { SOUND_A, SOUND_CS, SOUND_E, SOUND_B, SOUND_GS };
-
-    private static final String FILE_NAME = "a_4.ogg";
     private File mFile;
     private SoundPool mSoundPool;
 
+    /**
+     * function to return resource ID for A4 sound.
+     * should be implemented by child class
+     * @return resource ID
+     */
+    protected abstract int getSoundA();
+
+    protected abstract int getSoundCs();
+
+    protected abstract int getSoundE();
+
+    protected abstract int getSoundB();
+
+    protected abstract int getSoundGs();
+
+    protected abstract String getFileName();
+
+    private int[] getSounds() {
+        int[] sounds = { getSoundA(),
+                         getSoundCs(),
+                         getSoundE(),
+                         getSoundB(),
+                         getSoundGs() };
+        return sounds;
+    }
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mFile = new File(mContext.getFilesDir(), FILE_NAME);
+        mFile = new File(mContext.getFilesDir(), getFileName());
     }
 
     @Override
@@ -110,12 +127,12 @@
     public void testLoad() throws Exception {
         int srcQuality = 100;
         mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, srcQuality);
-        int sampleId1 = mSoundPool.load(mContext, SOUND_A, PRIORITY);
+        int sampleId1 = mSoundPool.load(mContext, getSoundA(), PRIORITY);
         waitUntilLoaded(sampleId1);
         // should return true, but returns false
         mSoundPool.unload(sampleId1);
 
-        AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(SOUND_CS);
+        AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(getSoundCs());
         int sampleId2;
         sampleId2 = mSoundPool.load(afd, PRIORITY);
         waitUntilLoaded(sampleId2);
@@ -141,7 +158,7 @@
         FileOutputStream fOutput = null;
         try {
             fOutput = new FileOutputStream(f);
-            InputStream is = mContext.getResources().openRawResource(SOUND_A);
+            InputStream is = mContext.getResources().openRawResource(getSoundA());
             byte[] buffer = new byte[1024];
             int length = is.read(buffer);
             while (length != -1) {
@@ -211,7 +228,7 @@
     public void testSoundPoolOp() throws Exception {
         int srcQuality = 100;
         mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, srcQuality);
-        int sampleID = loadSampleSync(SOUND_A, PRIORITY);
+        int sampleID = loadSampleSync(getSoundA(), PRIORITY);
 
         int waitMsec = 1000;
         float leftVolume = SILENT;
@@ -276,8 +293,8 @@
     public void testMultiSound() throws Exception {
         int srcQuality = 100;
         mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, srcQuality);
-        int sampleID1 = loadSampleSync(SOUND_A, PRIORITY);
-        int sampleID2 = loadSampleSync(SOUND_CS, PRIORITY);
+        int sampleID1 = loadSampleSync(getSoundA(), PRIORITY);
+        int sampleID2 = loadSampleSync(getSoundCs(), PRIORITY);
         long waitMsec = 1000;
         Thread.sleep(waitMsec);
 
@@ -317,10 +334,11 @@
     })
     public void testLoadMore() throws Exception {
         mSoundPool = new SoundPool(SOUNDPOOL_STREAMS, AudioManager.STREAM_MUSIC, 0);
-        int[] soundIds = new int[SOUNDS.length];
-        int[] streamIds = new int[SOUNDS.length];
-        for (int i = 0; i < SOUNDS.length; i++) {
-            soundIds[i] = loadSampleSync(SOUNDS[i], PRIORITY);
+        int[] sounds = getSounds();
+        int[] soundIds = new int[sounds.length];
+        int[] streamIds = new int[sounds.length];
+        for (int i = 0; i < sounds.length; i++) {
+            soundIds[i] = loadSampleSync(sounds[i], PRIORITY);
             System.out.println("load: " + soundIds[i]);
         }
         for (int i = 0; i < soundIds.length; i++) {
diff --git a/tests/tests/os/src/android/os/cts/StatFsTest.java b/tests/tests/os/src/android/os/cts/StatFsTest.java
index e879611..5f0d781 100644
--- a/tests/tests/os/src/android/os/cts/StatFsTest.java
+++ b/tests/tests/os/src/android/os/cts/StatFsTest.java
@@ -82,6 +82,6 @@
         assertTrue(blockSize > 0);
         assertTrue(totalBlocks > 0);
         assertTrue(freeBlocks >= availableBlocks);
-        assertTrue(availableBlocks > 0);
+        assertTrue(availableBlocks >= 0);
     }
 }
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index c222e7b..2e3bbdb 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -197,10 +197,26 @@
                     "/data/dalvik-cache",
                     "/data/data/.drm",
                     "/data/data/.drm/.wmdrm",
+                    "/data/data/cw",
+                    "/data/data/com.android.htcprofile",
+                    "/data/data/com.htc.android.qxdm2sd",
+                    "/data/data/com.htc.android.qxdm2sd/bin",
+                    "/data/data/com.htc.android.qxdm2sd/data",
+                    "/data/data/com.htc.android.qxdm2sd/tmp",
+                    "/data/data/com.htc.android.netlogger/data",
+                    "/data/data/com.htc.messagecs/att",
+                    "/data/data/com.htc.messagecs/pdu",
+                    "/data/data/com.htc.loggers/bin",
+                    "/data/data/com.htc.loggers/data",
+                    "/data/data/com.htc.loggers/htclog",
+                    "/data/data/com.htc.loggers/tmp",
+                    "/data/data/com.htc.loggers/htcghost",
+                    "/data/data/com.android.providers.drm/rights",
                     "/data/dontpanic",
                     "/data/drm",
                     "/data/drm/rights",
                     "/data/dump",
+                    "/data/htcfs",
                     "/data/local",
                     "/data/local/tmp/com.nuance.android.vsuite.vsuiteapp",
                     "/data/log",
@@ -218,11 +234,13 @@
                     "/data/wiper",
                     "/data/wpstiles",
                     "/dbdata/databases",
+                    "/efs/.android",
                     "/mnt_ext",
                     "/mnt_ext/badablk2",
                     "/mnt_ext/badablk3",
                     "/mnt_ext/cache",
-                    "/mnt_ext/data"
+                    "/mnt_ext/data",
+                    "/system/etc/security/drm"
             )
     );
 
diff --git a/tests/tests/security/src/android/security/cts/VoldExploitTest.java b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
index 8fbf874..3957bbe 100644
--- a/tests/tests/security/src/android/security/cts/VoldExploitTest.java
+++ b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
@@ -25,7 +25,9 @@
 import android.os.storage.StorageManager;
 import android.test.AndroidTestCase;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.lang.reflect.InvocationTargetException;
@@ -50,8 +52,7 @@
      * is the typical failure for this test.
      */
     public void testZergRushCrash() throws Exception {
-        Set<Integer> pids = getPids();
-        assertTrue(pids.size() > 1);  // at least vold and netd should exist
+        int pid = findVold();
 
         StorageManager sm = (StorageManager) getContext().getSystemService(Context.STORAGE_SERVICE);
         try {
@@ -63,19 +64,17 @@
                     + "AAAA AAAA AAAA AAAA"
                     + "AAAA AAAA AAAA AAAA"
                     + "AAAA AAAA AAAA AAAA");
-            fail("Should have gotten an IllegalStateException");
         } catch (IllegalStateException e) {
             // expected
         }
 
-        // Check to see if all the processes are still alive.  If
-        // any of them have died, we found an exploitable bug.
-        for (int i : pids) {
-            assertTrue(
-                    "PID=" + i + " crashed due to a malformed mount message."
-                    + " Detected unpatched ZergRush vulnerability (CVE-2011-3874).",
-                    new File("/proc/" + i + "/cmdline").exists());
-        }
+        Thread.sleep(2000);  // give vold some time to crash
+
+        // Check to see if vold is still alive.
+        assertTrue(
+                "PID=" + pid + " crashed due to a malformed mount message."
+                        + " Detected unpatched ZergRush vulnerability (CVE-2011-3874).",
+                new File("/proc/" + pid + "/cmdline").exists());
     }
 
     /**
@@ -91,15 +90,14 @@
      *
      * This test accomplishes the same thing as {@link #testZergRushCrash()}
      */
-    public void testZergRushUsingRelection() {
+    public void testZergRushUsingRelection() throws Exception {
         // This test assumes we have the MOUNT_UNMOUNT_FILESYSTEMS permission
         // Check it first so we know we're reaching the vulnerable code.
         assertEquals(PackageManager.PERMISSION_GRANTED,
                 getContext().checkCallingOrSelfPermission(
                         android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS));
 
-        Set<Integer> pids = getPids();
-        assertTrue(pids.size() > 1);  // at least vold and netd should exist
+        int pid = findVold();
 
         try {
             Object iBinderObj = Class.forName("android.os.ServiceManager")
@@ -143,14 +141,13 @@
             // remote failure. Assume not exploitable.
         }
 
-        // Check to see if all the processes are still alive.  If
-        // any of them have died, we found an exploitable bug.
-        for (int i : pids) {
-            assertTrue(
-                    "PID=" + i + " crashed due to a malformed mount message."
-                    + " Detected unpatched ZergRush vulnerability (CVE-2011-3874).",
-                    new File("/proc/" + i + "/cmdline").exists());
-        }
+        Thread.sleep(2000);  // give vold some time to crash
+
+        // Check to see if vold is still alive.
+        assertTrue(
+                "PID=" + pid + " crashed due to a malformed mount message."
+                        + " Detected unpatched ZergRush vulnerability (CVE-2011-3874).",
+                new File("/proc/" + pid + "/cmdline").exists());
     }
 
     /**
@@ -282,6 +279,29 @@
         }
     }
 
+    private static int findVold() throws IOException {
+        File f = new File("/proc");
+        for (File d : f.listFiles()) {
+            String cmdLineString = d.getAbsolutePath() + "/cmdline";
+            File cmdLine = new File(cmdLineString);
+            if (cmdLine.exists()) {
+                BufferedReader in = null;
+                try {
+                    in = new BufferedReader(new FileReader(cmdLine));
+                    String line = in.readLine();
+                    if ((line != null) && line.startsWith("/system/bin/vold")) {
+                        return Integer.decode(d.getName());
+                    }
+                } finally {
+                    if (in != null) {
+                        in.close();
+                    }
+                }
+            }
+        }
+        throw new RuntimeException("should never get here");
+    }
+
     /**
      * Extract all the PIDs listening for netlink messages.
      */
diff --git a/tests/tests/text/src/android/text/method/cts/TextKeyListenerTest.java b/tests/tests/text/src/android/text/method/cts/TextKeyListenerTest.java
index 1d239f7..932e5c0 100644
--- a/tests/tests/text/src/android/text/method/cts/TextKeyListenerTest.java
+++ b/tests/tests/text/src/android/text/method/cts/TextKeyListenerTest.java
@@ -244,11 +244,6 @@
         }
     }
 
-    private int getKeyboardType() {
-        KeyCharacterMap kmap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
-        return kmap.getKeyboardType();
-    }
-
     /**
      * Check point:
      * 1. press KEYCODE_4 once. if it's ALPHA key board, text will be "4", if it's
@@ -274,7 +269,6 @@
     public void testPressKey() {
         final TextKeyListener textKeyListener
                 = TextKeyListener.getInstance(false, Capitalize.NONE);
-        int keyType = getKeyboardType();
 
         mActivity.runOnUiThread(new Runnable() {
             public void run() {
@@ -290,7 +284,9 @@
         sendKeys(KeyEvent.KEYCODE_4);
         waitForListenerTimeout();
         String text = mTextView.getText().toString();
-        if (KeyCharacterMap.ALPHA == keyType) {
+        int keyType = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD).getKeyboardType();
+        if (KeyCharacterMap.ALPHA == keyType
+                || KeyCharacterMap.FULL == keyType) {
             assertEquals("4", text);
         } else if (KeyCharacterMap.NUMERIC == keyType) {
             assertEquals("g", text);