am fb4663a1: am f6147419: am 27090c92: am 451b9477: Merge "Farewell Magnetometer Test" into gingerbread

* commit 'fb4663a10a59dd662f281514a5ce262113f8bd56':
  Farewell Magnetometer Test
diff --git a/CtsTestCoverage.mk b/CtsTestCoverage.mk
index 7053fea..1648230 100644
--- a/CtsTestCoverage.mk
+++ b/CtsTestCoverage.mk
@@ -19,20 +19,28 @@
 
 include cts/CtsTestCaseList.mk
 
-CTS_API_COVERAGE_EXE := $(HOST_OUT_EXECUTABLES)/cts-api-coverage
-DEXDEPS_EXE := $(HOST_OUT_EXECUTABLES)/dexdeps
+cts_api_coverage_exe := $(HOST_OUT_EXECUTABLES)/cts-api-coverage
+dexdeps_exe := $(HOST_OUT_EXECUTABLES)/dexdeps
 
-COVERAGE_OUT := $(HOST_OUT)/cts-api-coverage
-cts-test-coverage-report := $(COVERAGE_OUT)/test-coverage.html
-cts-verifier-coverage-report := $(COVERAGE_OUT)/verifier-coverage.html
+coverage_out := $(HOST_OUT)/cts-api-coverage
 
-CTS_API_COVERAGE_DEPENDENCIES := $(CTS_API_COVERAGE_EXE) $(DEXDEPS_EXE) $(ACP)
+api_text_description := $(SRC_API_DIR)/current.txt
+api_xml_description := $(coverage_out)/api.xml
+$(api_xml_description) : $(api_text_description) $(APICHECK)
+	$(hide) echo "Converting API file to XML: $@"
+	$(hide) mkdir -p $(coverage_out)
+	$(hide) $(APICHECK_COMMAND) -convert2xml $(api_text_description) $(api_xml_description)
 
-$(cts-test-coverage-report) : $(CTS_COVERAGE_TEST_CASE_LIST) $(CTS_API_COVERAGE_DEPENDENCIES)
+cts-test-coverage-report := $(coverage_out)/test-coverage.html
+cts-verifier-coverage-report := $(coverage_out)/verifier-coverage.html
+
+cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description) $(ACP)
+
+$(cts-test-coverage-report) : $(CTS_COVERAGE_TEST_CASE_LIST) $(cts_api_coverage_dependencies)
 	$(call generate-coverage-report,"CTS Tests API Coverage Report",\
 			$(CTS_COVERAGE_TEST_CASE_LIST),html,test-coverage.html)
 
-$(cts-verifier-coverage-report) : CtsVerifier $(CTS_API_COVERAGE_DEPENDENCIES)
+$(cts-verifier-coverage-report) : CtsVerifier $(cts_api_coverage_dependencies)
 	$(call generate-coverage-report,"CTS Verifier API Coverage Report",\
 			CtsVerifier,html,verifier-coverage.html)
 
@@ -55,11 +63,11 @@
 #  4 - Output file name of the report
 define generate-coverage-report
 	$(foreach testcase,$(2),$(eval $(call add-testcase-apk,$(testcase))))
-	$(hide) mkdir -p $(COVERAGE_OUT)
-	$(hide) $(CTS_API_COVERAGE_EXE) -d $(DEXDEPS_EXE) -f $(3) -o $(COVERAGE_OUT)/$(4) $(TEST_APKS)
-	$(hide) echo $(1): file://$(ANDROID_BUILD_TOP)/$(COVERAGE_OUT)/$(4)
+	$(hide) mkdir -p $(coverage_out)
+	$(hide) $(cts_api_coverage_exe) -d $(dexdeps_exe) -a $(api_xml_description) -f $(3) -o $(coverage_out)/$(4) $(text_apks)
+	$(hide) echo $(1): file://$(ANDROID_BUILD_TOP)/$(coverage_out)/$(4)
 endef
 
 define add-testcase-apk
-	TEST_APKS += $(call intermediates-dir-for,APPS,$(1))/package.apk
+	text_apks += $(call intermediates-dir-for,APPS,$(1))/package.apk
 endef
diff --git a/apps/CtsVerifier/jni/audioquality/Android.mk b/apps/CtsVerifier/jni/audioquality/Android.mk
index 565cec2..8e827f7 100644
--- a/apps/CtsVerifier/jni/audioquality/Android.mk
+++ b/apps/CtsVerifier/jni/audioquality/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_MODULE    := libaudioquality
 LOCAL_SRC_FILES := Fft.cpp Window.cpp GlitchTest.cpp MeasureRms.cpp \
diff --git a/apps/CtsVerifier/jni/verifier/Android.mk b/apps/CtsVerifier/jni/verifier/Android.mk
index 98a4678..da4687d 100644
--- a/apps/CtsVerifier/jni/verifier/Android.mk
+++ b/apps/CtsVerifier/jni/verifier/Android.mk
@@ -21,7 +21,7 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_SRC_FILES := \
 		CtsVerifierJniOnLoad.cpp \
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 14e58eb..9c69f1a 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
@@ -21,7 +21,6 @@
 #include <grp.h>
 #include <pwd.h>
 
-static jclass gFileStatusClass;
 static jfieldID gFileStatusDevFieldID;
 static jfieldID gFileStatusInoFieldID;
 static jfieldID gFileStatusModeFieldID;
@@ -95,19 +94,19 @@
 {
     jclass clazz = env->FindClass("com/android/cts/verifier/os/FileUtils");
 
-    gFileStatusClass = env->FindClass("com/android/cts/verifier/os/FileUtils$FileStatus");
-    gFileStatusDevFieldID = env->GetFieldID(gFileStatusClass, "dev", "I");
-    gFileStatusInoFieldID = env->GetFieldID(gFileStatusClass, "ino", "I");
-    gFileStatusModeFieldID = env->GetFieldID(gFileStatusClass, "mode", "I");
-    gFileStatusNlinkFieldID = env->GetFieldID(gFileStatusClass, "nlink", "I");
-    gFileStatusUidFieldID = env->GetFieldID(gFileStatusClass, "uid", "I");
-    gFileStatusGidFieldID = env->GetFieldID(gFileStatusClass, "gid", "I");
-    gFileStatusSizeFieldID = env->GetFieldID(gFileStatusClass, "size", "J");
-    gFileStatusBlksizeFieldID = env->GetFieldID(gFileStatusClass, "blksize", "I");
-    gFileStatusBlocksFieldID = env->GetFieldID(gFileStatusClass, "blocks", "J");
-    gFileStatusAtimeFieldID = env->GetFieldID(gFileStatusClass, "atime", "J");
-    gFileStatusMtimeFieldID = env->GetFieldID(gFileStatusClass, "mtime", "J");
-    gFileStatusCtimeFieldID = env->GetFieldID(gFileStatusClass, "ctime", "J");
+    jclass fileStatusClass = env->FindClass("com/android/cts/verifier/os/FileUtils$FileStatus");
+    gFileStatusDevFieldID = env->GetFieldID(fileStatusClass, "dev", "I");
+    gFileStatusInoFieldID = env->GetFieldID(fileStatusClass, "ino", "I");
+    gFileStatusModeFieldID = env->GetFieldID(fileStatusClass, "mode", "I");
+    gFileStatusNlinkFieldID = env->GetFieldID(fileStatusClass, "nlink", "I");
+    gFileStatusUidFieldID = env->GetFieldID(fileStatusClass, "uid", "I");
+    gFileStatusGidFieldID = env->GetFieldID(fileStatusClass, "gid", "I");
+    gFileStatusSizeFieldID = env->GetFieldID(fileStatusClass, "size", "J");
+    gFileStatusBlksizeFieldID = env->GetFieldID(fileStatusClass, "blksize", "I");
+    gFileStatusBlocksFieldID = env->GetFieldID(fileStatusClass, "blocks", "J");
+    gFileStatusAtimeFieldID = env->GetFieldID(fileStatusClass, "atime", "J");
+    gFileStatusMtimeFieldID = env->GetFieldID(fileStatusClass, "mtime", "J");
+    gFileStatusCtimeFieldID = env->GetFieldID(fileStatusClass, "ctime", "J");
 
     return env->RegisterNatives(clazz, gMethods, 
             sizeof(gMethods) / sizeof(JNINativeMethod)); 
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 6f302a6..756401b 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -653,6 +653,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.webkit.cts.WebDriverStubActivity"
+            android:label="WebDriverStubActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="android.app.cts.ChildActivity"
                         android:label="ChildActivity" />
 
diff --git a/tests/SignatureTest/Android.mk b/tests/SignatureTest/Android.mk
index 4166002..3ebab34 100644
--- a/tests/SignatureTest/Android.mk
+++ b/tests/SignatureTest/Android.mk
@@ -31,7 +31,7 @@
 # To be passed in on command line
 CTS_API_VERSION ?= current
 
-android_api_description := $(SRC_API_DIR)/$(CTS_API_VERSION).xml
+android_api_description := $(SRC_API_DIR)/$(CTS_API_VERSION).txt
 
 # Can't call local-intermediates-dir directly here because we have to
 # include BUILD_PACAKGE first.  Can't include BUILD_PACKAGE first
@@ -67,9 +67,15 @@
 # sure the generated resources rule depend on it, we can ensure that
 # the proper version of the api resource gets generated.
 $(api_ver_file):
-	@rm -f $(api_ver_path)/api_ver_is_*
+	$(hide) rm -f $(api_ver_path)/api_ver_is_*
 	$(hide) touch $@
 
+android_api_xml_description := $(intermediates.COMMON)/api.xml
+$(android_api_xml_description): PRIVATE_INPUT_FILE := $(android_api_description)
+$(android_api_xml_description): $(android_api_description) $(APICHECK)
+	$(hide) echo "Convert api file to xml: $@"
+	$(hide) $(APICHECK_COMMAND) -convert2xml $(PRIVATE_INPUT_FILE) $@
+
 static_res_deps := $(call find-subdir-assets,$(LOCAL_PATH)/res)
 $(copied_res_stamp): PRIVATE_PATH := $(LOCAL_PATH)
 $(copied_res_stamp): PRIVATE_MODULE := $(LOCAL_MODULE)
@@ -77,11 +83,11 @@
 $(copied_res_stamp): FAKE_RESOURCE_DIR := $(dir $(fake_resource_check))
 $(copied_res_stamp): FAKE_RESOURCE_CHECK := $(fake_resource_check)
 $(copied_res_stamp): $(foreach res,$(static_res_deps),$(LOCAL_PATH)/res/${res}) | $(ACP)
-	@echo "Copy resources: $(PRIVATE_MODULE)"
-	@rm -f $@
-	@rm -rf $(PRIVATE_RES_DIR)
-	@mkdir -p $(PRIVATE_RES_DIR)
-	@if [ ! -f $(FAKE_RESOURCE_CHECK) ]; \
+	$(hide) echo "Copy resources: $(PRIVATE_MODULE)"
+	$(hide) rm -f $@
+	$(hide) rm -rf $(PRIVATE_RES_DIR)
+	$(hide) mkdir -p $(PRIVATE_RES_DIR)
+	$(hide) if [ ! -f $(FAKE_RESOURCE_CHECK) ]; \
 	  then mkdir -p $(FAKE_RESOURCE_DIR); \
 	  touch $(FAKE_RESOURCE_CHECK); \
 	fi
@@ -94,11 +100,11 @@
 $(generated_res_stamp): PRIVATE_MODULE := $(LOCAL_MODULE)
 $(generated_res_stamp): PRIVATE_RES_DIR := $(signature_res_dir)
 $(generated_res_stamp): $(api_ver_file)
-$(generated_res_stamp): $(copied_res_stamp) $(android_api_description)
-	@echo "Copy generated resources: $(PRIVATE_MODULE)"
-	@rm -f $@
+$(generated_res_stamp): $(copied_res_stamp) $(android_api_xml_description)
+	$(hide) echo "Copy generated resources: $(PRIVATE_MODULE)"
+	$(hide) rm -f $@
 	$(hide) python cts/tools/utils/android_api_description_splitter.py \
-		$(android_api_description) $(PRIVATE_RES_DIR) package
+		$(android_api_xml_description) $(PRIVATE_RES_DIR) package
 	$(hide) touch $@
 
 $(R_file_stamp): $(generated_res_stamp) $(copied_res_stamp)
diff --git a/tests/assets/sphere.a3d b/tests/assets/sphere.a3d
new file mode 100644
index 0000000..3d78b01
--- /dev/null
+++ b/tests/assets/sphere.a3d
Binary files differ
diff --git a/tests/assets/webkit/form_page.html b/tests/assets/webkit/form_page.html
new file mode 100644
index 0000000..b7a32a3
--- /dev/null
+++ b/tests/assets/webkit/form_page.html
@@ -0,0 +1,41 @@
+<!-- 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.
+-->
+
+<html>
+<head>
+    <title>Test Page</title>
+</head>
+<body>
+  <a name="text" />
+  <a id=someTextId>Some text&nbsp;</a>
+  <a id=nestedLinkId>Is not nested, and is not unique!</a>
+  <div id=divId>A div
+    <a id=nestedLinkId>Nested text</a>
+  </div>
+  <p id="spaces">     </p>
+  <p id="empty"></p>
+  <a href="foo" id="linkWithEqualsSign">Link=equalssign</a>
+  <p id="self-closed" />Here is some content that should not be in the previous p tag
+
+  <p class=" spaceAround ">Spaced out</p>
+
+  <span id="my_span">
+    <div>first_div</div>
+    <div>second_div</div>
+    <span>first_span</span>
+    <span>second_span</span>
+  </span>
+</body>
+</html>
diff --git a/tests/core/ctscore.mk b/tests/core/ctscore.mk
index 337b3f5..11fc253 100644
--- a/tests/core/ctscore.mk
+++ b/tests/core/ctscore.mk
@@ -39,16 +39,14 @@
 $(PACKAGE_RESOURCES): PRIVATE_PRIVATE_KEY := $(private_key)
 $(PACKAGE_RESOURCES): PRIVATE_CERTIFICATE := $(certificate)
 $(PACKAGE_RESOURCES): $(LOCAL_BUILT_MODULE) $(CORETESTS_INTERMEDIATES)/javalib.jar
+# Remove .class files from javalib.jar, we only want the resources
 	@echo "Add resources to package ($@)"
 	@rm -rf $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses
-# javalib.jar should only contain .dex files, but the harmony tests also include
-# some .class files, so get rid of them
 	$(call unzip-jar-files,$(PRIVATE_CORETESTS_INTERMEDIATES_COMMON)/javalib.jar,\
 		$(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses)
 	@find $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses -type f -name "*.class" -delete
-	@rm -f $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses/classes.dex
-	@cp $< $@
-	@jar uf $@ -C $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses .
+	$(hide) cp $< $@
+	$(hide) jar uf $@ -C $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses .
 	$(sign-package)
 	$(align-package)
 	$(hide) cp $@ $<
diff --git a/tests/core/dom/AndroidManifest.xml b/tests/core/dom/AndroidManifest.xml
deleted file mode 100644
index 8fa00e3..0000000
--- a/tests/core/dom/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.core.tests.dom">
-    <uses-permission android:name="android.permission.INTERNET" />
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
-                     android:targetPackage="android.core.tests.runner"
-                     android:label="cts framework tests"/>
-
-</manifest>
diff --git a/tests/core/dom/Android.mk b/tests/core/libcore/Android.mk
similarity index 67%
rename from tests/core/dom/Android.mk
rename to tests/core/libcore/Android.mk
index 69d4af3..5b59965 100644
--- a/tests/core/dom/Android.mk
+++ b/tests/core/libcore/Android.mk
@@ -19,17 +19,12 @@
 endif
 
 #
-# DOM Tests
+# libcore tests
 ##########################################################
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-java-files-under,../../../../libcore/dom/src/test/java) \
-	$(call all-java-files-under,../../../../libcore/junit/src/test/java/junit) \
-	$(call all-java-files-under,../../../../libcore/support/src/test/java/)
-
-LOCAL_PACKAGE_NAME := android.core.tests.dom
-
-# for java.* javax.* support classes in libcore/support/src/test/java
-LOCAL_DX_FLAGS := --core-library
+LOCAL_SRC_FILES := src/Dummy.java
+LOCAL_PACKAGE_NAME := android.core.tests.libcore
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
 
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/xml/AndroidManifest.xml b/tests/core/libcore/AndroidManifest.xml
similarity index 96%
rename from tests/core/xml/AndroidManifest.xml
rename to tests/core/libcore/AndroidManifest.xml
index 0f6085e..d0ce941 100644
--- a/tests/core/xml/AndroidManifest.xml
+++ b/tests/core/libcore/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.core.tests.xml">
+    package="android.core.tests.libcore">
     <uses-permission android:name="android.permission.INTERNET" />
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/tests/core/libcore/src/Dummy.java b/tests/core/libcore/src/Dummy.java
new file mode 100644
index 0000000..cfe0c81
--- /dev/null
+++ b/tests/core/libcore/src/Dummy.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/**
+ * We really just want the core-tests classes from the static java
+ * library, but the build system currently needs at least one input
+ * file, not just becuase its a sanity check, but because the static
+ * class files and resources are included in the output of the local
+ * java compilation.
+ */
+public final class Dummy {}
diff --git a/tests/core/luni-io/Android.mk b/tests/core/luni-io/Android.mk
deleted file mode 100644
index 6669c6a..0000000
--- a/tests/core/luni-io/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2009 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-#
-# Luni-Io Tests
-##########################################################
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,../../../../libcore/luni/src/test/java/tests/api/java/io) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/libcore/java/io) \
-	$(call all-java-files-under,../../../../libcore/support/src/test/java/) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/org/apache/harmony/luni/tests/pkg1) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/org/apache/harmony/luni/tests/pkg2) \
-	../../../../libcore/luni/src/test/java/tests/luni/AllTestsIo.java
-
-LOCAL_PACKAGE_NAME := android.core.tests.luni.io
-
-# for java.* javax.* support classes in libcore/support/src/test/java
-LOCAL_DX_FLAGS := --core-library
-
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/luni-io/AndroidManifest.xml b/tests/core/luni-io/AndroidManifest.xml
deleted file mode 100644
index 1224aa5..0000000
--- a/tests/core/luni-io/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.core.tests.luni.io">
-    <uses-permission android:name="android.permission.INTERNET" />
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
-                     android:targetPackage="android.core.tests.runner"
-                     android:label="cts framework tests"/>
-
-</manifest>
diff --git a/tests/core/luni-lang/Android.mk b/tests/core/luni-lang/Android.mk
deleted file mode 100644
index c3528ec..0000000
--- a/tests/core/luni-lang/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2009 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-#
-# Luni-Lang Tests
-##########################################################
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/tests/api/java/lang) \
-	$(call all-java-files-under,../../../../libcore/support/src/test/java/) \
-	../../../../libcore/luni/src/test/java/tests/luni/AllTestsLang.java
-
-LOCAL_PACKAGE_NAME := android.core.tests.luni.lang
-
-# for java.* javax.* support classes in libcore/support/src/test/java
-LOCAL_DX_FLAGS := --core-library
-
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/luni-lang/AndroidManifest.xml b/tests/core/luni-lang/AndroidManifest.xml
deleted file mode 100644
index cb79f5f..0000000
--- a/tests/core/luni-lang/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.core.tests.luni.lang">
-    <uses-permission android:name="android.permission.INTERNET" />
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
-                     android:targetPackage="android.core.tests.runner"
-                     android:label="cts framework tests"/>
-
-</manifest>
diff --git a/tests/core/luni-net/Android.mk b/tests/core/luni-net/Android.mk
deleted file mode 100644
index 8a6508c..0000000
--- a/tests/core/luni-net/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2009 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-#
-# Luni-Net Tests
-##########################################################
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/libcore/java/net) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/http) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/org/apache/harmony/luni/tests/internal/net/www/protocol/https) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/net) \
-	$(call all-java-files-under,../../../../libcore/support/src/test/java/) \
-	../../../../libcore/luni/src/test/java/tests/luni/AllTestsNet.java
-
-LOCAL_PACKAGE_NAME := android.core.tests.luni.net
-
-# for java.* javax.* support classes in libcore/support/src/test/java
-LOCAL_DX_FLAGS := --core-library
-
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/luni-net/AndroidManifest.xml b/tests/core/luni-net/AndroidManifest.xml
deleted file mode 100644
index ca0d17a..0000000
--- a/tests/core/luni-net/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.core.tests.luni.net">
-    <uses-permission android:name="android.permission.INTERNET" />
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
-                     android:targetPackage="android.core.tests.runner"
-                     android:label="cts framework tests"/>
-
-</manifest>
diff --git a/tests/core/luni-util/Android.mk b/tests/core/luni-util/Android.mk
deleted file mode 100644
index 5468c17..0000000
--- a/tests/core/luni-util/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2009 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-#
-# Luni-Util Tests
-##########################################################
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,../../../../libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/util) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/tests/api/java/util) \
-	$(call all-java-files-under,../../../../libcore/support/src/test/java/) \
-	../../../../libcore/luni/src/test/java/tests/luni/AllTestsUtil.java
-
-LOCAL_PACKAGE_NAME := android.core.tests.luni.util
-
-# for java.* javax.* support classes in libcore/support/src/test/java
-LOCAL_DX_FLAGS := --core-library
-
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/luni-util/AndroidManifest.xml b/tests/core/luni-util/AndroidManifest.xml
deleted file mode 100644
index 8b4daad..0000000
--- a/tests/core/luni-util/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.core.tests.luni.util">
-    <uses-permission android:name="android.permission.INTERNET" />
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
-                     android:targetPackage="android.core.tests.runner"
-                     android:label="cts framework tests"/>
-
-</manifest>
diff --git a/tests/core/xml/Android.mk b/tests/core/xml/Android.mk
deleted file mode 100644
index 0f643a0..0000000
--- a/tests/core/xml/Android.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2009 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
-    $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-#
-# Xml Tests
-##########################################################
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,../../../../libcore/xml/src/test/java) \
-	$(call all-java-files-under,../../../../libcore/dom/src/test) \
-	$(call all-java-files-under,../../../../libcore/junit/src/test/java/junit) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/tests/api/javax/xml/parsers) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/tests/api/org/xml/sax) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/tests/api/org/xml/sax/support) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/tests/org/w3c/dom) \
-	$(call all-java-files-under,../../../../libcore/luni/src/test/java/tests/xml) \
-	$(call all-java-files-under,../../../../libcore/support/src/test/java)
-
-LOCAL_PACKAGE_NAME := android.core.tests.xml
-
-# for java.* javax.* support classes in libcore/support/src/test/java
-LOCAL_DX_FLAGS := --core-library
-
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/jni/Android.mk b/tests/jni/Android.mk
index de1d373..ed4c46f 100644
--- a/tests/jni/Android.mk
+++ b/tests/jni/Android.mk
@@ -21,9 +21,6 @@
 # Don't include this package in any configuration by default.
 LOCAL_MODULE_TAGS := optional
 
-# This isn't part of the system, so don't prelink it.
-LOCAL_PRELINK_MODULE := false
-
 LOCAL_SRC_FILES := \
 		CtsJniOnLoad.cpp \
 		android_os_cts_FileUtils.cpp
diff --git a/tests/res/raw/samplefont.ttf b/tests/res/raw/samplefont.ttf
new file mode 100644
index 0000000..49f1c62
--- /dev/null
+++ b/tests/res/raw/samplefont.ttf
Binary files differ
diff --git a/tests/res/raw/sphere.a3d b/tests/res/raw/sphere.a3d
new file mode 100644
index 0000000..3d78b01
--- /dev/null
+++ b/tests/res/raw/sphere.a3d
Binary files differ
diff --git a/tests/src/android/opengl/cts/GLSurfaceViewStubActivity.java b/tests/src/android/opengl/cts/GLSurfaceViewStubActivity.java
index 5a8f310..79da413 100644
--- a/tests/src/android/opengl/cts/GLSurfaceViewStubActivity.java
+++ b/tests/src/android/opengl/cts/GLSurfaceViewStubActivity.java
@@ -25,6 +25,7 @@
 
 /**
  * A minimal activity for testing {@link android.opengl.GLSurfaceView}.
+ * Also accepts non-blank renderers to allow its use for more complex tests.
  */
 public class GLSurfaceViewStubActivity extends Activity {
 
@@ -45,11 +46,60 @@
 
     private GLSurfaceView mView;
 
+    /** To override the blank renderer, or other settings, these
+     * static set* methods must be called before onCreate() is called.
+     * If using ActivityInstrumentationTestCase2, that means the set
+     * methods need to be called before calling getActivity in the
+     * test setUp().
+     */
+    private static GLSurfaceView.Renderer mRenderer = null;
+    public static void setRenderer(GLSurfaceView.Renderer renderer) {
+        mRenderer = renderer;
+    }
+    public static void resetRenderer() {
+        mRenderer = null;
+    }
+
+    private static int mRenderMode = 0;
+    private static boolean mRenderModeSet = false;
+    public static void setRenderMode(int renderMode) {
+        mRenderModeSet = true;
+        mRenderMode = renderMode;
+    }
+    public static void resetRenderMode() {
+        mRenderModeSet = false;
+        mRenderMode = 0;
+    }
+
+    private static int mGlVersion = 0;
+    private static boolean mGlVersionSet = false;
+    public static void setGlVersion(int glVersion) {
+        mGlVersionSet = true;
+        mGlVersion = glVersion;
+    }
+    public static void resetGlVersion() {
+        mGlVersionSet = false;
+        mGlVersion = 0;
+    }
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mView = new GLSurfaceView(this);
-        mView.setRenderer(new Renderer());
+        // Only set this if explicitly asked for
+        if (mGlVersionSet) {
+            mView.setEGLContextClientVersion(mGlVersion);
+        }
+        // Use no-op renderer by default
+        if (mRenderer == null) {
+            mView.setRenderer(new Renderer());
+        } else {
+            mView.setRenderer(mRenderer);
+        }
+        // Only set this if explicitly asked for
+        if (mRenderModeSet) {
+            mView.setRenderMode(mRenderMode);
+        }
         setContentView(mView);
     }
 
diff --git a/tests/src/android/renderscript/cts/graphics_runner.rs b/tests/src/android/renderscript/cts/graphics_runner.rs
new file mode 100644
index 0000000..b8ec15f
--- /dev/null
+++ b/tests/src/android/renderscript/cts/graphics_runner.rs
@@ -0,0 +1,45 @@
+// 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.
+
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+
+#include "structs.rsh"
+
+static void drawQuad() {
+    float startX = 0, startY = 0;
+    float width = 4, height = 4;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+                         startX, startY + height, 0, 0, 1,
+                         startX + width, startY + height, 0, 1, 1,
+                         startX + width, startY, 0, 1, 0);
+}
+
+void testProgramVertex(rs_program_vertex pv) {
+    rsDebug("Set Program Vertex, drew quad", 0);
+    rsgBindProgramVertex(pv);
+    drawQuad();
+}
+
+void testProgramFragment(rs_program_fragment pf) {
+    rsDebug("Set Program Fragment, drew quad", 0);
+    rsgBindProgramFragment(pf);
+    drawQuad();
+}
+
+// Just draw a quad with previously setup state
+int root(int launchID) {
+    rsDebug("Running script", 0);
+    return 0;
+}
diff --git a/tests/src/android/renderscript/cts/primitives.rs b/tests/src/android/renderscript/cts/primitives.rs
old mode 100644
new mode 100755
index d2ffd26..55710cd
--- a/tests/src/android/renderscript/cts/primitives.rs
+++ b/tests/src/android/renderscript/cts/primitives.rs
@@ -1,4 +1,5 @@
 #include "shared.rsh"
+#include "structs.rsh"
 
 // Testing primitive types
 float floatTest = 1.99f;
@@ -47,9 +48,65 @@
     return failed;
 }
 
+static bool test_vector_types() {
+    bool failed = false;
+    start();
+    _RS_ASSERT(avt->b2.x == 1);
+    _RS_ASSERT(avt->b2.y == 2);
+    _RS_ASSERT(avt->b3.x == 1);
+    _RS_ASSERT(avt->b3.y == 2);
+    _RS_ASSERT(avt->b3.z == 3);
+    _RS_ASSERT(avt->b4.x == 1);
+    _RS_ASSERT(avt->b4.y == 2);
+    _RS_ASSERT(avt->b4.z == 3);
+    _RS_ASSERT(avt->b4.w == 4);
+
+    _RS_ASSERT(avt->s2.x == 1);
+    _RS_ASSERT(avt->s2.y == 2);
+    _RS_ASSERT(avt->s3.x == 1);
+    _RS_ASSERT(avt->s3.y == 2);
+    _RS_ASSERT(avt->s3.z == 3);
+    _RS_ASSERT(avt->s4.x == 1);
+    _RS_ASSERT(avt->s4.y == 2);
+    _RS_ASSERT(avt->s4.z == 3);
+    _RS_ASSERT(avt->s4.w == 4);
+
+    _RS_ASSERT(avt->i2.x == 1);
+    _RS_ASSERT(avt->i2.y == 2);
+    _RS_ASSERT(avt->i3.x == 1);
+    _RS_ASSERT(avt->i3.y == 2);
+    _RS_ASSERT(avt->i3.z == 3);
+    _RS_ASSERT(avt->i4.x == 1);
+    _RS_ASSERT(avt->i4.y == 2);
+    _RS_ASSERT(avt->i4.z == 3);
+    _RS_ASSERT(avt->i4.w == 4);
+
+    _RS_ASSERT(avt->f2.x == 1.0f);
+    _RS_ASSERT(avt->f2.y == 2.0f);
+    _RS_ASSERT(avt->f3.x == 1.0f);
+    _RS_ASSERT(avt->f3.y == 2.0f);
+    _RS_ASSERT(avt->f3.z == 3.0f);
+    _RS_ASSERT(avt->f4.x == 1.0f);
+    _RS_ASSERT(avt->f4.y == 2.0f);
+    _RS_ASSERT(avt->f4.z == 3.0f);
+    _RS_ASSERT(avt->f4.w == 4.0f);
+
+    float time = end();
+
+    if (failed) {
+        rsDebug("test_vector_types FAILED", time);
+    }
+    else {
+        rsDebug("test_vector_types PASSED", time);
+    }
+
+    return failed;
+}
+
 void test() {
     bool failed = false;
     failed |= test_primitive_types();
+    failed |= test_vector_types();
 
     if (failed) {
         rsSendToClientBlocking(RS_MSG_TEST_FAILED);
diff --git a/tests/src/android/renderscript/cts/structs.rsh b/tests/src/android/renderscript/cts/structs.rsh
new file mode 100755
index 0000000..58f6186
--- /dev/null
+++ b/tests/src/android/renderscript/cts/structs.rsh
@@ -0,0 +1,56 @@
+// 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.
+
+typedef struct ConstMatrix {
+    rs_matrix4x4 MVP;
+} ConstMatrix_s;
+ConstMatrix_s *c1;
+
+typedef struct ConstComplex {
+    rs_matrix4x4 MVP;
+    rs_matrix4x4 EXTRA;
+    float extra1;
+    float2 extra2;
+    float3 extra3;
+    float4 extra4;
+} ConstComplex_s;
+ConstComplex_s *c2;
+
+typedef struct ConstExtra {
+    rs_matrix4x4 EXTRA;
+    float extra1;
+    float2 extra2;
+    float3 extra3;
+    float4 extra4;
+} ConstExtra_s;
+ConstExtra_s *c3;
+
+typedef struct AllVectorTypes {
+    char2 b2;
+    char3 b3;
+    char4 b4;
+
+    short2 s2;
+    short3 s3;
+    short4 s4;
+
+    int2 i2;
+    int3 i3;
+    int4 i4;
+
+    float2 f2;
+    float3 f3;
+    float4 f4;
+} AllVectorTypes_s;
+AllVectorTypes_s *avt;
diff --git a/tests/src/android/webkit/cts/WebDriverStubActivity.java b/tests/src/android/webkit/cts/WebDriverStubActivity.java
new file mode 100644
index 0000000..092156b
--- /dev/null
+++ b/tests/src/android/webkit/cts/WebDriverStubActivity.java
@@ -0,0 +1,55 @@
+/*
+ * 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.webkit.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.webdriver.WebDriver;
+
+/**
+ * A stub activity for WebDriver tests.
+ */
+public class WebDriverStubActivity extends Activity {
+    private WebDriver mDriver;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        WebView view = new WebView(this);
+
+        WebSettings settings = view.getSettings();
+        settings.setJavaScriptCanOpenWindowsAutomatically(true);
+        settings.setSupportMultipleWindows(true);
+        settings.setBuiltInZoomControls(true);
+        settings.setJavaScriptEnabled(true);
+        settings.setAppCacheEnabled(true);
+        settings.setDatabaseEnabled(true);
+        settings.setDomStorageEnabled(true);
+        settings.setGeolocationEnabled(true);
+        settings.setSaveFormData(true);
+
+        mDriver = new WebDriver(view);
+
+        setContentView(view);
+    }
+
+    public WebDriver getDriver() {
+        return mDriver;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraGLTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraGLTest.java
new file mode 100644
index 0000000..545ac48
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraGLTest.java
@@ -0,0 +1,864 @@
+/*
+ * 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.hardware.cts;
+
+import android.content.Context;
+import android.graphics.SurfaceTexture;
+import android.hardware.Camera;
+import android.hardware.Camera.Parameters;
+import android.hardware.Camera.Size;
+
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.Matrix;
+import android.opengl.cts.GLSurfaceViewStubActivity;
+
+import android.os.ConditionVariable;
+import android.os.Environment;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.MoreAsserts;
+import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * This test case must run with hardware. It can't be tested in emulator
+ */
+@LargeTest
+@TestTargetClass(Camera.class)
+public class CameraGLTest extends ActivityInstrumentationTestCase2<GLSurfaceViewStubActivity> {
+    private static final String TAG = "CameraGLTest";
+    private static final String PACKAGE = "com.android.cts.stub";
+    private static final boolean LOGV = false;
+    private static final boolean LOGVV = false;
+    private static final int EGL_OPENGL_ES2_BIT = 0x0004;
+
+    private boolean mSurfaceTextureCallbackResult = false;
+
+    private static final int WAIT_FOR_COMMAND_TO_COMPLETE = 1500;  // Milliseconds.
+    private static final int WAIT_FOR_FOCUS_TO_COMPLETE = 3000;
+    private static final int WAIT_FOR_SNAPSHOT_TO_COMPLETE = 5000;
+
+    private SurfaceTextureCallback mSurfaceTextureCallback = new SurfaceTextureCallback();
+    private SurfaceTextureBurstCallback mSurfaceTextureBurstCallback = new SurfaceTextureBurstCallback();
+    private PreviewCallback mPreviewCallback = new PreviewCallback();
+
+    private Looper mLooper = null;
+    private final ConditionVariable mSurfaceTextureDone = new ConditionVariable();
+    private final ConditionVariable mPreviewDone = new ConditionVariable();
+
+    Camera mCamera;
+    SurfaceTexture mSurfaceTexture;
+    Renderer mRenderer;
+    GLSurfaceView mGLView;
+
+    public CameraGLTest() {
+        super(PACKAGE, GLSurfaceViewStubActivity.class);
+        if (LOGV) Log.v(TAG, "CameraGLTest Constructor");
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // Set up renderer instance
+        mRenderer = this.new Renderer();
+        GLSurfaceViewStubActivity.setRenderer(mRenderer);
+        GLSurfaceViewStubActivity.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+        GLSurfaceViewStubActivity.setGlVersion(2);
+        // Start CameraStubActivity.
+        GLSurfaceViewStubActivity stubActivity = getActivity();
+        // Store a link to the view so we can redraw it when needed
+        mGLView = stubActivity.getView();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mCamera != null) {
+            mCamera.release();
+            mCamera = null;
+        }
+        // Clean up static values in stub so it can be reused
+        GLSurfaceViewStubActivity.resetRenderMode();
+        GLSurfaceViewStubActivity.resetRenderer();
+        GLSurfaceViewStubActivity.resetGlVersion();
+
+        super.tearDown();
+    }
+
+    /**
+     * Initializes the message looper so that the Camera object can
+     * receive the callback messages.
+     */
+    private void initializeMessageLooper(final int cameraId) {
+        final ConditionVariable startDone = new ConditionVariable();
+        new Thread() {
+            @Override
+            public void run() {
+                Log.v(TAG, "Start camera/surfacetexture thread");
+                // Set up a looper to be used by camera.
+                Looper.prepare();
+                // Save the looper so that we can terminate this thread
+                // after we are done with it.
+                mLooper = Looper.myLooper();
+                // These must be instantiated outside the UI thread, since the
+                // UI thread will be doing a lot of waiting, stopping callbacks.
+                mCamera = Camera.open(cameraId);
+                mSurfaceTexture = new SurfaceTexture(mRenderer.getTextureID());
+                Log.v(TAG, "Camera " + cameraId + " is opened.");
+                startDone.open();
+                Looper.loop(); // Blocks forever until Looper.quit() is called.
+                Log.v(TAG, "Stop camera/surfacetexture thread");
+            }
+        }.start();
+
+        Log.v(TAG, "start waiting for looper");
+        if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
+            fail("initializeMessageLooper: start timeout");
+        }
+    }
+
+    /**
+     * Terminates the message looper thread.
+     */
+    private void terminateMessageLooper() throws Exception {
+        mCamera.release();
+        mLooper.quit();
+        // Looper.quit() is asynchronous. The looper may still has some
+        // preview callbacks in the queue after quit is called. The preview
+        // callback still uses the camera object (setHasPreviewCallback).
+        // After camera is released, RuntimeException will be thrown from
+        // the method. So we need to join the looper thread here.
+        mLooper.getThread().join();
+        mCamera = null;
+        mSurfaceTexture = null;
+    }
+
+    /** The camera preview callback. Stops capture after the first callback */
+    private final class PreviewCallback
+            implements android.hardware.Camera.PreviewCallback {
+        public void onPreviewFrame(byte [] data, Camera camera) {
+            if (LOGV) Log.v(TAG, "PreviewCallback");
+            assertNotNull(data);
+            Size size = camera.getParameters().getPreviewSize();
+            assertEquals(size.width * size.height * 3 / 2, data.length);
+            mCamera.stopPreview();
+            mPreviewDone.open();
+        }
+    }
+
+    /** A simple SurfaceTexture listener callback, meant to be used together with the camera preview
+     * callback */
+    private final class SurfaceTextureCallback
+            implements android.graphics.SurfaceTexture.OnFrameAvailableListener {
+        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
+            if (LOGV) Log.v(TAG, "SurfaceTextureCallback");
+            mSurfaceTextureDone.open();
+            // Assumes preview is stopped elsewhere
+        }
+    }
+
+    /** A burst SurfaceTexture listener callback, used for multiple-frame capture */
+    private final class SurfaceTextureBurstCallback
+            implements android.graphics.SurfaceTexture.OnFrameAvailableListener {
+
+        public void setBurstCount(int burstCount) {
+            mBurstCount = burstCount;
+        }
+
+        public int getBurstCount() {
+            return mBurstCount;
+        }
+
+        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
+            if (LOGVV) Log.v(TAG, "SurfaceTextureBurstCallback, frame #" + mBurstCount);
+            mBurstCount--;
+            if (!mSurfaceTextureCallbackResult) {
+                if (mBurstCount <= 0) {
+                    if (LOGV) Log.v(TAG, "SurfaceTextureBurstCallback stopping preview.");
+                    mCamera.stopPreview();
+                    if (LOGVV) Log.v(TAG, "SurfaceTextureBurstCallback preview stopped.");
+                    mSurfaceTextureCallbackResult = true;
+                }
+                mSurfaceTextureDone.open();
+            }
+        }
+
+        private int mBurstCount = 0;
+    }
+
+    /** Waits until surface texture callbacks have fired */
+    private boolean waitForSurfaceTextureDone() {
+        if (LOGVV) Log.v(TAG, "Wait for surface texture callback");
+        if (!mSurfaceTextureDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
+            // timeout could be expected or unexpected. The caller will decide.
+            Log.v(TAG, "waitForSurfaceTextureDone: timeout");
+            return false;
+        }
+        mSurfaceTextureDone.close();
+        return true;
+    }
+
+    /** Waits until the camera preview callback has fired */
+    private boolean waitForPreviewDone() {
+        if (LOGVV) Log.v(TAG, "Wait for preview callback");
+        if (!mPreviewDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
+            // timeout could be expected or unexpected. The caller will decide.
+            Log.v(TAG, "waitForPreviewDone: timeout");
+            return false;
+        }
+        mPreviewDone.close();
+        return true;
+    }
+
+    /** @return OpenGL ES major version 1 or 2 or some negative number for error */
+    private static int getDetectedVersion() {
+        /*
+         * Get all the device configurations and check if any of the attributes specify the
+         * the EGL_OPENGL_ES2_BIT to determine whether the device supports 2.0.
+         */
+        EGL10 egl = (EGL10) EGLContext.getEGL();
+        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+        int[] numConfigs = new int[1];
+
+        if (egl.eglInitialize(display, null)) {
+            try {
+                if (egl.eglGetConfigs(display, null, 0, numConfigs)) {
+                    EGLConfig[] configs = new EGLConfig[numConfigs[0]];
+                    if (egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
+                        int[] value = new int[1];
+                        for (int i = 0; i < numConfigs[0]; i++) {
+                            if (egl.eglGetConfigAttrib(display, configs[i],
+                                    EGL10.EGL_RENDERABLE_TYPE, value)) {
+                                if ((value[0] & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT) {
+                                    return 2;
+                                }
+                            } else {
+                                Log.w(TAG, "Getting config attribute with "
+                                        + "EGL10#eglGetConfigAttrib failed "
+                                        + "(" + i + "/" + numConfigs[0] + "): "
+                                        + egl.eglGetError());
+                            }
+                        }
+                        return 1;
+                    } else {
+                        Log.e(TAG, "Getting configs with EGL10#eglGetConfigs failed: "
+                                + egl.eglGetError());
+                        return -1;
+                    }
+                } else {
+                    Log.e(TAG, "Getting number of configs with EGL10#eglGetConfigs failed: "
+                            + egl.eglGetError());
+                    return -2;
+                }
+              } finally {
+                  egl.eglTerminate(display);
+              }
+        } else {
+            Log.e(TAG, "Couldn't initialize EGL.");
+            return -3;
+        }
+    }
+
+    /** Generic per-camera test interface */
+    private interface RunPerCamera {
+        void run(int cameraId) throws Exception;
+    }
+
+    /** Generic camera test runner, to minimize boilerplace duplication */
+    private void runForAllCameras(RunPerCamera test) throws Exception {
+        /* Currently OpenGL ES 2.0 is supported for this test, so just skip it
+           if only 1.0 is available. */
+        int glVersion = getDetectedVersion();
+        assertTrue(glVersion > 0);
+        if (glVersion != 2) {
+            Log.w(TAG, "Skipping test because OpenGL ES 2 is not supported");
+            return;
+        }
+
+        /* Make sure the screen stays on while testing - otherwise the OpenGL context may disappear */
+        PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
+        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "CameraGLTest");
+        wl.acquire();
+        try {
+            /* Run the requested test per camera */
+            int nCameras = Camera.getNumberOfCameras();
+            for (int id = 0; id < nCameras; id++) {
+                Log.v(TAG, "Camera id=" + id);
+                test.run(id);
+            }
+        } finally {
+            wl.release();
+        }
+    }
+
+    /** Test Camera.setPreviewTexture in conjunction with the standard Camera preview callback */
+    @UiThreadTest
+    public void testSetPreviewTexturePreviewCallback() throws Exception {
+        runForAllCameras(testSetPreviewTexturePreviewCallbackByCamera);
+    }
+
+    private RunPerCamera testSetPreviewTexturePreviewCallbackByCamera = new RunPerCamera() {
+        public void run(int cameraId) throws Exception {
+            boolean noTimeout;
+            // Check the order: startPreview->setPreviewTexture, with a PreviewCallback as well
+            mPreviewDone.close();
+            initializeMessageLooper(cameraId);
+            mCamera.setPreviewCallback(mPreviewCallback);
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            noTimeout = waitForPreviewDone();
+            assertTrue(noTimeout);
+            terminateMessageLooper();
+
+            // Check the order: setPreviewTexture->startPreview.
+            initializeMessageLooper(cameraId);
+            mCamera.setPreviewCallback(mPreviewCallback);
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            mCamera.startPreview();
+            noTimeout = waitForPreviewDone();
+            assertTrue(noTimeout);
+
+            // Check the order: setting preview display to null->startPreview->
+            // setPreviewTexture.
+            mCamera.setPreviewCallback(mPreviewCallback);
+            mCamera.setPreviewTexture(null);
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            noTimeout = waitForPreviewDone();
+            assertTrue(noTimeout);
+            terminateMessageLooper();
+        }
+    };
+
+    /** Test Camera.setPreviewTexture in conjunction with both the standard Camera preview callback,
+        and the SurfaceTexture onFrameAvailable callback */
+    @UiThreadTest
+    public void testSetPreviewTextureBothCallbacks() throws Exception {
+        runForAllCameras(testSetPreviewTextureBothCallbacksByCamera);
+    }
+
+    private RunPerCamera testSetPreviewTextureBothCallbacksByCamera = new RunPerCamera() {
+        public void run(int cameraId) throws Exception {
+            boolean noTimeout;
+            // Check SurfaceTexture callback together with preview callback
+            // Check the order: setPreviewTexture->startPreview
+            mSurfaceTextureDone.close();
+            initializeMessageLooper(cameraId);
+            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+            mCamera.setPreviewCallback(mPreviewCallback);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            mCamera.startPreview();
+
+            noTimeout = waitForSurfaceTextureDone();
+            assertTrue(noTimeout);
+            noTimeout = waitForPreviewDone();
+            assertTrue(noTimeout);
+
+            mGLView.requestRender();
+            terminateMessageLooper();
+
+            // Check the order: startPreview->setPreviewTexture
+            mSurfaceTextureDone.close();
+            initializeMessageLooper(cameraId);
+            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+            mCamera.setPreviewCallback(mPreviewCallback);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+
+            noTimeout = waitForSurfaceTextureDone();
+            assertTrue(noTimeout);
+            noTimeout = waitForPreviewDone();
+            assertTrue(noTimeout);
+
+            mGLView.requestRender();
+
+            // Check the order: setting preview to null->startPreview->setPreviewTexture
+            mCamera.setPreviewCallback(mPreviewCallback);
+            mCamera.setPreviewTexture(null);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            noTimeout = waitForPreviewDone();
+            assertTrue(noTimeout);
+            terminateMessageLooper();
+        }
+    };
+
+    /** Test Camera.setPreviewTexture in conjunction with just the SurfaceTexture onFrameAvailable callback */
+    @UiThreadTest
+    public void testSetPreviewTextureTextureCallback() throws Exception {
+        runForAllCameras(testSetPreviewTextureTextureCallbackByCamera);
+    }
+
+    private RunPerCamera testSetPreviewTextureTextureCallbackByCamera = new RunPerCamera() {
+        public void run(int cameraId) throws Exception {
+            boolean noTimeout;
+            // Check that SurfaceTexture callbacks work with no standard
+            // preview callback
+            mSurfaceTextureCallbackResult = false;
+            mSurfaceTextureDone.close();
+            initializeMessageLooper(cameraId);
+            mSurfaceTextureBurstCallback.setBurstCount(1);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+            mCamera.startPreview();
+
+            noTimeout = waitForSurfaceTextureDone();
+            mGLView.requestRender();
+            assertTrue(noTimeout);
+
+            terminateMessageLooper();
+            assertTrue(mSurfaceTextureCallbackResult);
+
+            // Check that SurfaceTexture callbacks also work with
+            // startPreview->setPreviewTexture
+            mSurfaceTextureCallbackResult = false;
+            mSurfaceTextureDone.close();
+            initializeMessageLooper(cameraId);
+            mSurfaceTextureBurstCallback.setBurstCount(1);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
+            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+
+            noTimeout = waitForSurfaceTextureDone();
+            assertTrue(noTimeout);
+
+            terminateMessageLooper();
+            assertTrue(mSurfaceTextureCallbackResult);
+
+            // Check that SurfaceTexture callbacks also work with
+            // null->startPreview->setPreviewTexture
+            mSurfaceTextureCallbackResult = false;
+            mSurfaceTextureDone.close();
+            initializeMessageLooper(cameraId);
+            mSurfaceTextureBurstCallback.setBurstCount(1);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
+            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+            mCamera.setPreviewTexture(null);
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+
+            noTimeout = waitForSurfaceTextureDone();
+            assertTrue(noTimeout);
+
+            terminateMessageLooper();
+            assertTrue(mSurfaceTextureCallbackResult);
+        }
+    };
+
+    /** Test all preview sizes and framerates along with SurfaceTexture-provided metadata (texture
+     * transforms and timestamps) */
+    @UiThreadTest
+    public void testCameraToSurfaceTextureMetadata() throws Exception {
+        runForAllCameras(testCameraToSurfaceTextureMetadataByCamera);
+    }
+
+    private RunPerCamera testCameraToSurfaceTextureMetadataByCamera = new RunPerCamera() {
+        public void run(int cameraId) throws Exception {
+            int kLoopCount = 100; // Number of frames to test over
+            boolean noTimeout;
+            initializeMessageLooper(cameraId);
+            Parameters parameters = mCamera.getParameters();
+
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
+            mCamera.setPreviewTexture(mSurfaceTexture);
+
+            for (Size size: parameters.getSupportedPreviewSizes()) {
+                for (int[] fps: parameters.getSupportedPreviewFpsRange()) {
+                    if (LOGV) {
+                        Log.v(TAG, "Testing camera #" + cameraId +
+                              ", preview size:" + size.width + "x" + size.height +
+                              ", frame rate range: [" +
+                              (fps[Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.) + "," +
+                              (fps[Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.) + "]");
+                    }
+                    parameters.setPreviewSize(size.width, size.height);
+                    parameters.setPreviewFpsRange(fps[Parameters.PREVIEW_FPS_MIN_INDEX],
+                                                  fps[Parameters.PREVIEW_FPS_MAX_INDEX]);
+                    mCamera.setParameters(parameters);
+
+                    assertEquals(size, mCamera.getParameters().getPreviewSize());
+
+                    int[] actualFps = new int[2];
+                    mCamera.getParameters().getPreviewFpsRange(actualFps);
+                    assertEquals(fps[Parameters.PREVIEW_FPS_MIN_INDEX],
+                                 actualFps[Parameters.PREVIEW_FPS_MIN_INDEX]);
+                    assertEquals(fps[Parameters.PREVIEW_FPS_MAX_INDEX],
+                                 actualFps[Parameters.PREVIEW_FPS_MAX_INDEX]);
+
+                    mSurfaceTextureBurstCallback.setBurstCount(kLoopCount);
+                    mSurfaceTextureCallbackResult = false;
+                    mSurfaceTextureDone.close();
+
+                    mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+                    if (LOGV) Log.v(TAG, "Starting preview");
+                    mCamera.startPreview();
+                    if (LOGVV) Log.v(TAG, "Preview started");
+
+                    long[] timestamps = new long[kLoopCount];
+                    for (int i = 0; i < kLoopCount; i++) {
+                        noTimeout = waitForSurfaceTextureDone();
+                        assertTrue("Timeout waiting for frame " + i +
+                                   " (burst callback thinks " +
+                                   (kLoopCount - mSurfaceTextureBurstCallback.getBurstCount()) +
+                                   ")! (Size " + size.width + "x" + size.height + ", fps [" +
+                                   (fps[Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.) + ", " +
+                                   (fps[Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.) + "])",
+                                   noTimeout);
+
+                        if (LOGVV) Log.v(TAG, "Frame #" + i + " completed");
+                        // Draw the frame (and update the SurfaceTexture)
+                        mGLView.requestRender();
+                        // Wait until frame is drawn, so that the SurfaceTexture has new
+                        // metadata
+                        noTimeout = mRenderer.waitForDrawDone();
+                        assertTrue(noTimeout);
+
+                        // Store timestamps for later
+                        timestamps[i] = mSurfaceTexture.getTimestamp();
+                        // Verify that the surfaceTexture transform has at least one non-zero
+                        // entry
+                        float[] transform = new float[16];
+                        mSurfaceTexture.getTransformMatrix(transform);
+                        boolean nonZero = false;
+                        for (int k = 0; k < 16; k++) {
+                            if (transform[k] != 0.f) {
+                                nonZero = true;
+                                break;
+                            }
+                        }
+                        assertTrue(nonZero);
+                    }
+                    assertTrue(mSurfaceTextureCallbackResult);
+
+                    float expectedMaxFrameDurationMs = 1000.f * 1000.f /
+                            fps[Parameters.PREVIEW_FPS_MIN_INDEX];
+                    float expectedMinFrameDurationMs = 1000.f * 1000.f /
+                            fps[Parameters.PREVIEW_FPS_MAX_INDEX];
+
+                    for (int i = 1; i < kLoopCount; i++) {
+                        float frameDurationMs = (timestamps[i] - timestamps[i - 1]) / 1000000.f;
+                        if (LOGVV) {
+                            Log.v(TAG, "Frame " + i + " duration: " + frameDurationMs +
+                                  " ms, expecting [" + expectedMinFrameDurationMs + "," +
+                                  expectedMaxFrameDurationMs + "]");
+                        }
+                        assertTrue("Frame " + i + " duration out of bounds! ("+
+                                   frameDurationMs + " ms, expecting [" +
+                                   expectedMinFrameDurationMs + "," +
+                                   expectedMaxFrameDurationMs + "] ms)",
+                                   (frameDurationMs > expectedMinFrameDurationMs) &&
+                                   (frameDurationMs < expectedMaxFrameDurationMs) );
+                    }
+                }
+            }
+            terminateMessageLooper();
+        } // void run(int cameraId)
+    };
+
+    /** Basic OpenGL ES 2.0 renderer to draw SurfaceTexture-sourced frames to the screen */
+    private class Renderer implements GLSurfaceView.Renderer {
+        public Renderer() {
+            mTriangleVertices =
+                    ByteBuffer.allocateDirect(mTriangleVerticesData.length * FLOAT_SIZE_BYTES).
+                    order(ByteOrder.nativeOrder()).asFloatBuffer();
+            mTriangleVertices.put(mTriangleVerticesData).position(0);
+
+            Matrix.setIdentityM(mSTMatrix, 0);
+            Matrix.setIdentityM(mMMatrix, 0);
+
+            mTextureID = 0;
+        }
+
+        public void setCameraSizing(Camera.Size previewSize) {
+            mCameraRatio = (float)previewSize.width/previewSize.height;
+        }
+
+        public boolean waitForDrawDone() {
+            if (!mDrawDone.block(WAIT_FOR_COMMAND_TO_COMPLETE) ) {
+                // timeout could be expected or unexpected. The caller will decide.
+                Log.e(TAG, "waitForDrawDone: timeout");
+                return false;
+            }
+            mDrawDone.close();
+            return true;
+        }
+
+        private final ConditionVariable mDrawDone = new ConditionVariable();
+
+        public void onDrawFrame(GL10 glUnused) {
+            if (LOGVV) Log.v(TAG, "onDrawFrame()");
+            if (CameraGLTest.this.mSurfaceTexture != null) {
+                CameraGLTest.this.mSurfaceTexture.updateTexImage();
+                CameraGLTest.this.mSurfaceTexture.getTransformMatrix(mSTMatrix);
+                mDrawDone.open();
+            }
+
+            // Ignore the passed-in GL10 interface, and use the GLES20
+            // class's static methods instead.
+            GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
+            GLES20.glUseProgram(mProgram);
+            checkGlError("glUseProgram");
+
+            GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+            GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
+
+            mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
+            GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
+                                         TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+            checkGlError("glVertexAttribPointer maPosition");
+            GLES20.glEnableVertexAttribArray(maPositionHandle);
+            checkGlError("glEnableVertexAttribArray maPositionHandle");
+
+            mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
+            GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false,
+                                         TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+            checkGlError("glVertexAttribPointer maTextureHandle");
+            GLES20.glEnableVertexAttribArray(maTextureHandle);
+            checkGlError("glEnableVertexAttribArray maTextureHandle");
+
+            Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
+            Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
+
+            GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
+            GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
+            GLES20.glUniform1f(muCRatioHandle, mCameraRatio);
+
+            GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+            checkGlError("glDrawArrays");
+        }
+
+        public void onSurfaceChanged(GL10 glUnused, int width, int height) {
+            if (LOGV) Log.v(TAG, "onSurfaceChanged()");
+            // Ignore the passed-in GL10 interface, and use the GLES20
+            // class's static methods instead.
+            GLES20.glViewport(0, 0, width, height);
+            mRatio = (float) width / height;
+            Matrix.frustumM(mProjMatrix, 0, -mRatio, mRatio, -1, 1, 3, 7);
+        }
+
+        public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
+            if (LOGV) Log.v(TAG, "onSurfaceCreated()");
+            // Ignore the passed-in GL10 interface, and use the GLES20
+            // class's static methods instead.
+
+            /* Set up shaders and handles to their variables */
+            mProgram = createProgram(mVertexShader, mFragmentShader);
+            if (mProgram == 0) {
+                return;
+            }
+            maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
+            checkGlError("glGetAttribLocation aPosition");
+            if (maPositionHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for aPosition");
+            }
+            maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
+            checkGlError("glGetAttribLocation aTextureCoord");
+            if (maTextureHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for aTextureCoord");
+            }
+
+            muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
+            checkGlError("glGetUniformLocation uMVPMatrix");
+            if (muMVPMatrixHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for uMVPMatrix");
+            }
+
+            muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
+            checkGlError("glGetUniformLocation uSTMatrix");
+            if (muMVPMatrixHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for uSTMatrix");
+            }
+
+            muCRatioHandle = GLES20.glGetUniformLocation(mProgram, "uCRatio");
+            checkGlError("glGetUniformLocation uCRatio");
+            if (muMVPMatrixHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for uCRatio");
+            }
+
+            /*
+             * Create our texture. This has to be done each time the
+             * surface is created.
+             */
+
+            int[] textures = new int[1];
+            GLES20.glGenTextures(1, textures, 0);
+
+            mTextureID = textures[0];
+            GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
+            checkGlError("glBindTexture mTextureID");
+
+            // Can't do mipmapping with camera source
+            GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
+                                   GLES20.GL_NEAREST);
+            GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
+                                   GLES20.GL_LINEAR);
+            // Clamp to edge is the only option
+            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
+                                   GLES20.GL_CLAMP_TO_EDGE);
+            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
+                                   GLES20.GL_CLAMP_TO_EDGE);
+            checkGlError("glTexParameteri mTextureID");
+
+            Matrix.setLookAtM(mVMatrix, 0, 0, 0, 4f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+        }
+
+        public int getTextureID() {
+            return mTextureID;
+        }
+
+        private int loadShader(int shaderType, String source) {
+            int shader = GLES20.glCreateShader(shaderType);
+            if (shader != 0) {
+                GLES20.glShaderSource(shader, source);
+                GLES20.glCompileShader(shader);
+                int[] compiled = new int[1];
+                GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
+                if (compiled[0] == 0) {
+                    Log.e(TAG, "Could not compile shader " + shaderType + ":");
+                    Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
+                    GLES20.glDeleteShader(shader);
+                    shader = 0;
+                }
+            }
+            return shader;
+        }
+
+        private int createProgram(String vertexSource, String fragmentSource) {
+            int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
+            if (vertexShader == 0) {
+                return 0;
+            }
+            int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
+            if (pixelShader == 0) {
+                return 0;
+            }
+
+            int program = GLES20.glCreateProgram();
+            if (program != 0) {
+                GLES20.glAttachShader(program, vertexShader);
+                checkGlError("glAttachShader");
+                GLES20.glAttachShader(program, pixelShader);
+                checkGlError("glAttachShader");
+                GLES20.glLinkProgram(program);
+                int[] linkStatus = new int[1];
+                GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
+                if (linkStatus[0] != GLES20.GL_TRUE) {
+                    Log.e(TAG, "Could not link program: ");
+                    Log.e(TAG, GLES20.glGetProgramInfoLog(program));
+                    GLES20.glDeleteProgram(program);
+                    program = 0;
+                }
+            }
+            return program;
+        }
+
+        private void checkGlError(String op) {
+            int error;
+            while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+                Log.e(TAG, op + ": glError " + error);
+                throw new RuntimeException(op + ": glError " + error);
+            }
+        }
+
+        private static final int FLOAT_SIZE_BYTES = 4;
+        private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
+        private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
+        private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
+        private final float[] mTriangleVerticesData = {
+            // X, Y, Z, U, V
+            -1.0f, -1.0f, 0, 0.f, 0.f,
+            1.0f, -1.0f, 0, 1.f, 0.f,
+            -1.0f,  1.0f, 0, 0.f, 1.f,
+            1.0f,   1.0f, 0, 1.f, 1.f,
+        };
+
+        private FloatBuffer mTriangleVertices;
+
+        private final String mVertexShader =
+                "uniform mat4 uMVPMatrix;\n" +
+                "uniform mat4 uSTMatrix;\n" +
+                "uniform float uCRatio;\n" +
+                "attribute vec4 aPosition;\n" +
+                "attribute vec4 aTextureCoord;\n" +
+                "varying vec2 vTextureCoord;\n" +
+                "void main() {\n" +
+                "  gl_Position = vec4(uCRatio,1,1,1) * uMVPMatrix * aPosition;\n" +
+                "  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
+                "}\n";
+
+        private final String mFragmentShader =
+                "#extension GL_OES_EGL_image_external : require\n" +
+                "precision mediump float;\n" +
+                "varying vec2 vTextureCoord;\n" +
+                "uniform samplerExternalOES sTexture;\n" +
+                "void main() {\n" +
+                "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
+                "}\n";
+
+        private float[] mMVPMatrix = new float[16];
+        private float[] mProjMatrix = new float[16];
+        private float[] mMMatrix = new float[16];
+        private float[] mVMatrix = new float[16];
+        private float[] mSTMatrix = new float[16];
+
+        private int mProgram;
+        private int mTextureID;
+        private int muMVPMatrixHandle;
+        private int muSTMatrixHandle;
+        private int muCRatioHandle;
+        private int maPositionHandle;
+        private int maTextureHandle;
+
+        private float mRatio = 1.0f;
+        private float mCameraRatio = 1.0f;
+
+        private Context mContext;
+        private static final String TAG = "CameraGLTest.Renderer";
+
+        // Magic key
+        private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
+    }
+
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
index d75b5bc..cc6eef4 100644
--- a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
@@ -127,6 +127,7 @@
                 // after we are done with it.
                 mLooper = Looper.myLooper();
                 mCamera = Camera.open(cameraId);
+                mCamera.setErrorCallback(mErrorCallback);
                 Log.v(TAG, "camera is opened");
                 startDone.open();
                 Looper.loop(); // Blocks forever until Looper.quit() is called.
@@ -390,7 +391,6 @@
     private void testPreviewCallbackByCamera(int cameraId) throws Exception {
         initializeMessageLooper(cameraId);
         mCamera.setPreviewCallback(mPreviewCallback);
-        mCamera.setErrorCallback(mErrorCallback);
         checkPreviewCallback();
         terminateMessageLooper();
         assertTrue(mPreviewCallbackResult);
@@ -1917,7 +1917,6 @@
     private void testGetParameterDuringFocusByCamera(int cameraId) throws Exception {
         initializeMessageLooper(cameraId);
         mCamera.setPreviewDisplay(getActivity().getSurfaceView().getHolder());
-        mCamera.setErrorCallback(mErrorCallback);
         mCamera.startPreview();
         Parameters parameters = mCamera.getParameters();
         for (String focusMode: parameters.getSupportedFocusModes()) {
@@ -1952,7 +1951,6 @@
     private void testPreviewFormatsByCamera(int cameraId) throws Exception {
         initializeMessageLooper(cameraId);
         mCamera.setPreviewDisplay(getActivity().getSurfaceView().getHolder());
-        mCamera.setErrorCallback(mErrorCallback);
         Parameters parameters = mCamera.getParameters();
         for (int format: parameters.getSupportedPreviewFormats()) {
             Log.v(TAG, "Test preview format " + format);
@@ -1965,4 +1963,68 @@
         }
         terminateMessageLooper();
     }
+
+    @UiThreadTest
+    public void testMultiCameraRelease() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        if (nCameras < 2) {
+            Log.i(TAG, "Test multi-camera release: Skipping test because only 1 camera available");
+            return;
+        }
+        // Start first camera
+        initializeMessageLooper(0);
+        mCamera.setPreviewDisplay(getActivity().getSurfaceView().getHolder());
+        SimplePreviewStreamCb callback0 = new SimplePreviewStreamCb(0);
+        mCamera.setPreviewCallback(callback0);
+        mCamera.startPreview();
+        // Run preview for a bit
+        for (int f = 0; f < 100; f++) {
+            mPreviewDone.close();
+            assertTrue("First camera preview timed out on frame " + f + "!",
+                       mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE));
+        }
+        mCamera.stopPreview();
+        // Save message looper and camera to deterministically release them, instead
+        // of letting GC do it at some point.
+        Camera firstCamera = mCamera;
+        Looper firstLooper = mLooper;
+        //terminateMessageLooper(); // Intentionally not calling this
+
+        // Start second camera without releasing the first one (will
+        // set mCamera and mLooper to new objects)
+        initializeMessageLooper(1);
+        mCamera.setPreviewDisplay(getActivity().getSurfaceView().getHolder());
+        SimplePreviewStreamCb callback1 = new SimplePreviewStreamCb(1);
+        mCamera.setPreviewCallback(callback1);
+        mCamera.startPreview();
+        // Run preview for a bit - GC of first camera instance should not impact the second's
+        // operation.
+        for (int f = 0; f < 100; f++) {
+            mPreviewDone.close();
+            assertTrue("Second camera preview timed out on frame " + f + "!",
+                       mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE));
+            if (f == 50) {
+                // Release first camera mid-preview, should cause no problems
+                firstCamera.release();
+            }
+        }
+        mCamera.stopPreview();
+
+        firstLooper.quit();
+        terminateMessageLooper();
+    }
+
+    // This callback just signals on the condition variable, making it useful for checking that
+    // preview callbacks don't stop unexpectedly
+    private final class SimplePreviewStreamCb
+            implements android.hardware.Camera.PreviewCallback {
+        private int mId;
+        public SimplePreviewStreamCb(int id) {
+            mId = id;
+        }
+        public void onPreviewFrame(byte[] data, android.hardware.Camera camera) {
+            if (LOGV) Log.v(TAG, "Preview frame callback, id " + mId + ".");
+            mPreviewDone.open();
+        }
+    }
 }
diff --git a/tests/tests/jni/libjnitest/Android.mk b/tests/tests/jni/libjnitest/Android.mk
index 84856b3..d7d1bad 100644
--- a/tests/tests/jni/libjnitest/Android.mk
+++ b/tests/tests/jni/libjnitest/Android.mk
@@ -25,9 +25,6 @@
 # Don't include this package in any configuration by default.
 LOCAL_MODULE_TAGS := optional
 
-# This isn't part of the system, so don't prelink it.
-LOCAL_PRELINK_MODULE := false
-
 LOCAL_SRC_FILES := \
 	android_jni_cts_InstanceNonce.c \
 	android_jni_cts_JniCTest.c \
diff --git a/tests/tests/media/src/android/media/cts/AudioEffectTest.java b/tests/tests/media/src/android/media/cts/AudioEffectTest.java
index 0aaf11f..41f3055 100644
--- a/tests/tests/media/src/android/media/cts/AudioEffectTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioEffectTest.java
@@ -566,7 +566,7 @@
             byte[] param = mEffect.intToByteArray(PresetReverb.PARAM_PRESET);
             byte[] value = new byte[2];
             int status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 1 failed", AudioEffect.isError(status));
             short preset = PresetReverb.PRESET_SMALLROOM;
             if (mEffect.byteArrayToShort(value) == preset) {
                 preset = PresetReverb.PRESET_MEDIUMROOM;
@@ -575,7 +575,7 @@
             status = mEffect.setParameter(param, value);
             assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
             status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 2 failed", AudioEffect.isError(status));
             assertEquals("get/set Parameter failed", preset,
                     mEffect.byteArrayToShort(value));
 
@@ -609,7 +609,7 @@
             int param = EnvironmentalReverb.PARAM_DECAY_TIME;
             int[] value = new int[1];
             int status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 1 failed", AudioEffect.isError(status));
             int time = 500;
             if (value[0] == time) {
                 time = 1000;
@@ -617,7 +617,7 @@
             status = mEffect.setParameter(param, time);
             assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
             status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 2 failed", AudioEffect.isError(status));
             assertTrue("got incorrect decay time",
                     ((float)value[0] > (float)(time / DELAY_TOLERANCE)) &&
                     ((float)value[0] < (float)(time * DELAY_TOLERANCE)));
@@ -652,7 +652,7 @@
             int param = PresetReverb.PARAM_PRESET;
             short[] value = new short[1];
             int status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 1 failed", AudioEffect.isError(status));
             short preset = PresetReverb.PRESET_SMALLROOM;
             if (value[0] == preset) {
                 preset = PresetReverb.PRESET_MEDIUMROOM;
@@ -660,7 +660,7 @@
             status = mEffect.setParameter(param, preset);
             assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
             status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 2 failed", AudioEffect.isError(status));
             assertEquals("get/set Parameter failed", preset, value[0]);
 
         } catch (IllegalArgumentException e) {
@@ -693,7 +693,7 @@
             int param = EnvironmentalReverb.PARAM_DECAY_TIME;
             byte[] value = new byte[4];
             int status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 1 failed", AudioEffect.isError(status));
             int time = 500;
             if (mEffect.byteArrayToInt(value) == time) {
                 time = 1000;
@@ -702,7 +702,7 @@
             status = mEffect.setParameter(param, value);
             assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
             status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 2 failed", AudioEffect.isError(status));
             int time2 = mEffect.byteArrayToInt(value);
             assertTrue("got incorrect decay time",
                     ((float)time2 > (float)(time / DELAY_TOLERANCE)) &&
@@ -739,7 +739,7 @@
             int[] value = new int[1];
             param[0] = EnvironmentalReverb.PARAM_DECAY_TIME;
             int status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 1 failed", AudioEffect.isError(status));
             int[] time = new int[1];
             time[0] = 500;
             if (value[0] == time[0]) {
@@ -748,7 +748,7 @@
             status = mEffect.setParameter(param, time);
             assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
             status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 2 failed", AudioEffect.isError(status));
             assertTrue("got incorrect decay time",
                     ((float)value[0] > (float)(time[0] / DELAY_TOLERANCE)) &&
                     ((float)value[0] < (float)(time[0] * DELAY_TOLERANCE)));
@@ -785,7 +785,7 @@
             param[0] = PresetReverb.PARAM_PRESET;
             short[] value = new short[1];
             int status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 1 failed", AudioEffect.isError(status));
             short[] preset = new short[1];
             preset[0] = PresetReverb.PRESET_SMALLROOM;
             if (value[0] == preset[0]) {
@@ -794,7 +794,7 @@
             status = mEffect.setParameter(param, preset);
             assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
             status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 2 failed", AudioEffect.isError(status));
             assertEquals("get/set Parameter failed", preset[0], value[0]);
 
         } catch (IllegalArgumentException e) {
@@ -828,7 +828,7 @@
             param[0] = EnvironmentalReverb.PARAM_DECAY_TIME;
             byte[] value = new byte[4];
             int status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 1 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 1 failed", AudioEffect.isError(status));
             int time = 500;
             if (mEffect.byteArrayToInt(value) == time) {
                 time = 1000;
@@ -837,7 +837,7 @@
             status = mEffect.setParameter(param, mEffect.intToByteArray(time));
             assertEquals("setParameter failed", AudioEffect.SUCCESS, status);
             status = mEffect.getParameter(param, value);
-            assertEquals("getParameter 2 failed", AudioEffect.SUCCESS, status);
+            assertFalse("getParameter 2 failed", AudioEffect.isError(status));
             int time2 = mEffect.byteArrayToInt(value);
             assertTrue("got incorrect decay time",
                     ((float)time2 > (float)(time / DELAY_TOLERANCE)) &&
@@ -1018,8 +1018,8 @@
 
             short[] value = new short[1];
             status = effect2.getParameter(PresetReverb.PARAM_PRESET, value);
-            assertEquals("Effect2 getParameter failed",
-                    AudioEffect.SUCCESS, status);
+            assertFalse("Effect2 getParameter failed",
+                    AudioEffect.isError(status));
             assertEquals("Effect1 changed parameter", PresetReverb.PRESET_SMALLROOM
                     , value[0]);
 
@@ -1186,7 +1186,7 @@
             byte[] reply = new byte[4];
             // command 3 is ENABLE
             int status = mEffect.command(3, cmd, reply);
-            assertEquals("command failed", AudioEffect.SUCCESS, status);
+            assertFalse("command failed", AudioEffect.isError(status));
             assertTrue("effect not enabled", mEffect.getEnabled());
 
         } catch (IllegalStateException e) {
diff --git a/tests/tests/os/src/android/os/cts/MessengerTest.java b/tests/tests/os/src/android/os/cts/MessengerTest.java
index efe022d..6b2debc 100644
--- a/tests/tests/os/src/android/os/cts/MessengerTest.java
+++ b/tests/tests/os/src/android/os/cts/MessengerTest.java
@@ -90,6 +90,9 @@
         public void dump(FileDescriptor fd, String[] args) throws RemoteException {
         }
 
+        public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
+        }
+
     };
 
     // Create another messenger to send msg.
diff --git a/tests/tests/os/src/android/os/cts/ProcessTest.java b/tests/tests/os/src/android/os/cts/ProcessTest.java
index 6216f06..e810f05 100644
--- a/tests/tests/os/src/android/os/cts/ProcessTest.java
+++ b/tests/tests/os/src/android/os/cts/ProcessTest.java
@@ -26,7 +26,6 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestStatus;
 import dalvik.annotation.TestTargetNew;
 import dalvik.annotation.TestLevel;
 import dalvik.annotation.TestTargetClass;
diff --git a/tests/tests/permission/jni/Android.mk b/tests/tests/permission/jni/Android.mk
index 0891a72..44e742e 100644
--- a/tests/tests/permission/jni/Android.mk
+++ b/tests/tests/permission/jni/Android.mk
@@ -21,9 +21,6 @@
 # Don't include this package in any configuration by default.
 LOCAL_MODULE_TAGS := optional
 
-# This isn't part of the system, so don't prelink it.
-LOCAL_PRELINK_MODULE := false
-
 LOCAL_SRC_FILES := \
 		CtsPermissionsJniOnLoad.cpp \
 		android_permission_cts_FileUtils.cpp
diff --git a/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp b/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp
index 1666d50..c658af6 100644
--- a/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp
+++ b/tests/tests/permission/jni/android_permission_cts_FileUtils.cpp
@@ -21,7 +21,6 @@
 #include <grp.h>
 #include <pwd.h>
 
-static jclass gFileStatusClass;
 static jfieldID gFileStatusDevFieldID;
 static jfieldID gFileStatusInoFieldID;
 static jfieldID gFileStatusModeFieldID;
@@ -101,19 +100,19 @@
 {
     jclass clazz = env->FindClass("android/permission/cts/FileUtils");
 
-    gFileStatusClass = env->FindClass("android/permission/cts/FileUtils$FileStatus");
-    gFileStatusDevFieldID = env->GetFieldID(gFileStatusClass, "dev", "I");
-    gFileStatusInoFieldID = env->GetFieldID(gFileStatusClass, "ino", "I");
-    gFileStatusModeFieldID = env->GetFieldID(gFileStatusClass, "mode", "I");
-    gFileStatusNlinkFieldID = env->GetFieldID(gFileStatusClass, "nlink", "I");
-    gFileStatusUidFieldID = env->GetFieldID(gFileStatusClass, "uid", "I");
-    gFileStatusGidFieldID = env->GetFieldID(gFileStatusClass, "gid", "I");
-    gFileStatusSizeFieldID = env->GetFieldID(gFileStatusClass, "size", "J");
-    gFileStatusBlksizeFieldID = env->GetFieldID(gFileStatusClass, "blksize", "I");
-    gFileStatusBlocksFieldID = env->GetFieldID(gFileStatusClass, "blocks", "J");
-    gFileStatusAtimeFieldID = env->GetFieldID(gFileStatusClass, "atime", "J");
-    gFileStatusMtimeFieldID = env->GetFieldID(gFileStatusClass, "mtime", "J");
-    gFileStatusCtimeFieldID = env->GetFieldID(gFileStatusClass, "ctime", "J");
+    jclass fileStatusClass = env->FindClass("android/permission/cts/FileUtils$FileStatus");
+    gFileStatusDevFieldID = env->GetFieldID(fileStatusClass, "dev", "I");
+    gFileStatusInoFieldID = env->GetFieldID(fileStatusClass, "ino", "I");
+    gFileStatusModeFieldID = env->GetFieldID(fileStatusClass, "mode", "I");
+    gFileStatusNlinkFieldID = env->GetFieldID(fileStatusClass, "nlink", "I");
+    gFileStatusUidFieldID = env->GetFieldID(fileStatusClass, "uid", "I");
+    gFileStatusGidFieldID = env->GetFieldID(fileStatusClass, "gid", "I");
+    gFileStatusSizeFieldID = env->GetFieldID(fileStatusClass, "size", "J");
+    gFileStatusBlksizeFieldID = env->GetFieldID(fileStatusClass, "blksize", "I");
+    gFileStatusBlocksFieldID = env->GetFieldID(fileStatusClass, "blocks", "J");
+    gFileStatusAtimeFieldID = env->GetFieldID(fileStatusClass, "atime", "J");
+    gFileStatusMtimeFieldID = env->GetFieldID(fileStatusClass, "mtime", "J");
+    gFileStatusCtimeFieldID = env->GetFieldID(fileStatusClass, "ctime", "J");
 
     return env->RegisterNatives(clazz, gMethods, 
             sizeof(gMethods) / sizeof(JNINativeMethod)); 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
index 0f77369..aa981ca 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
@@ -18,11 +18,15 @@
 
 import com.android.cts.stub.R;
 
+import android.graphics.Bitmap;
 import android.renderscript.Allocation;
+import android.renderscript.AllocationAdapter;
 import android.renderscript.Allocation.MipmapControl;
 import android.renderscript.Element;
+import android.renderscript.RSIllegalArgumentException;
 import android.renderscript.Type;
 import android.renderscript.Type.Builder;
+import android.renderscript.Type.CubemapFace;
 
 public class AllocationTest extends RSBaseGraphics {
 
@@ -100,7 +104,9 @@
 
     void createSizedHelper(Element e) {
         for (int i = 1; i <= 8; i ++) {
-            Allocation.createSized(mRS, e, i);
+            Allocation A = Allocation.createSized(mRS, e, i);
+            assertEquals(A.getType().getElement(), e);
+            assertEquals(A.getType().getX(), i);
         }
     }
 
@@ -176,6 +182,236 @@
          createSizedHelper(Element.SCRIPT(mRS));
          createSizedHelper(Element.TYPE(mRS));
     }
+
+    static int bDimX = 48;
+    static int bDimY = 8;
+
+    void helperCreateFromBitmap(Bitmap B,
+                                Allocation.MipmapControl mc) {
+        for (int i = 0; i < 1; i++) {
+            for (int j = 0; j < 1; j++) {
+                for (int k = 0; k < 1; k++) {
+                    for (int l = 0; l < 1; l++) {
+                        int u = 0;
+                        u |= (i * Allocation.USAGE_SCRIPT);
+                        u |= (j * Allocation.USAGE_GRAPHICS_TEXTURE);
+                        u |= (k * Allocation.USAGE_GRAPHICS_VERTEX);
+                        u |= (l * Allocation.USAGE_GRAPHICS_CONSTANTS);
+                        assertTrue(null !=
+                            Allocation.createFromBitmap(mRS, B, mc, u));
+                        assertTrue(null !=
+                            Allocation.createCubemapFromBitmap(mRS, B, mc, u));
+                    }
+                }
+            }
+        }
+    }
+
+    public void testCreateFromBitmap() {
+        Bitmap B = Bitmap.createBitmap(bDimX, bDimY, Bitmap.Config.ARGB_8888);
+        Allocation.createFromBitmap(mRS, B);
+        Allocation.createCubemapFromBitmap(mRS, B);
+        for (Allocation.MipmapControl mc : Allocation.MipmapControl.values()) {
+            helperCreateFromBitmap(B, mc);
+        }
+
+        try {
+            int invalidUsage = 0x0020;
+            Allocation.createFromBitmap(mRS, B,
+                Allocation.MipmapControl.MIPMAP_NONE, invalidUsage);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+
+        try {
+            // width % 6 != 0
+            Bitmap badB = Bitmap.createBitmap(47, 8, Bitmap.Config.ARGB_8888);
+            Allocation.createCubemapFromBitmap(mRS, badB,
+                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+
+        try {
+            // width / 6 != height
+            Bitmap badB = Bitmap.createBitmap(48, 4, Bitmap.Config.ARGB_8888);
+            Allocation.createCubemapFromBitmap(mRS, badB,
+                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+
+        try {
+            // height not power of 2
+            Bitmap badB = Bitmap.createBitmap(36, 6, Bitmap.Config.ARGB_8888);
+            Allocation.createCubemapFromBitmap(mRS, badB,
+                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+    }
+
+    public void testAllocationMipmapControl() {
+        assertEquals(MipmapControl.MIPMAP_NONE,
+                     MipmapControl.valueOf("MIPMAP_NONE"));
+        assertEquals(MipmapControl.MIPMAP_FULL,
+                     MipmapControl.valueOf("MIPMAP_FULL"));
+        assertEquals(MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                     MipmapControl.valueOf("MIPMAP_ON_SYNC_TO_TEXTURE"));
+        // Make sure no new enums are added
+        assertEquals(3, Allocation.MipmapControl.values().length);
+
+        for (Allocation.MipmapControl mc : Allocation.MipmapControl.values()) {
+            Type.Builder b = new Type.Builder(mRS, Element.U8(mRS));
+            b.setX(8).setY(8);
+            Allocation.createTyped(mRS, b.create(), mc,
+                                   Allocation.USAGE_GRAPHICS_TEXTURE);
+        }
+    }
+
+    public void testCubemapFaces() {
+        Type.Builder b = new Type.Builder(mRS, Element.U8(mRS));
+        b.setX(8).setY(8).setFaces(true);
+        Allocation cubemap = Allocation.createTyped(mRS, b.create(),
+                                                    MipmapControl.MIPMAP_NONE,
+                                                    Allocation.USAGE_SCRIPT);
+        AllocationAdapter adapter = AllocationAdapter.create2D(mRS, cubemap);
+        for (Type.CubemapFace cf : Type.CubemapFace.values()) {
+            adapter.setFace(cf);
+        }
+    }
+
+    /*
+     * Test all copy from/to routines for byte/short/int/float
+     */
+
+    void helperFloatCopy(int nElems) {
+        Allocation A = Allocation.createSized(mRS, Element.F32(mRS), nElems);
+
+        float src[], dst[];
+        src = new float[nElems];
+        dst = new float[nElems];
+        for (int i = 0; i < nElems; i++) {
+            src[i] = (float)i;
+            dst[i] = -1.0f;
+        }
+
+        A.copyFrom(src);
+        A.copyTo(dst);
+
+        for (int i = 0; i < nElems; i++) {
+            assertEquals(dst[i], src[i]);
+        }
+    }
+
+    void helperByteCopy(int nElems) {
+        Allocation A = Allocation.createSized(mRS, Element.I8(mRS), nElems);
+
+        byte src[], dst[];
+        src = new byte[nElems];
+        dst = new byte[nElems];
+        for (int i = 0; i < nElems; i++) {
+            src[i] = (byte)i;
+            dst[i] = -1;
+        }
+
+        A.copyFrom(src);
+        A.copyTo(dst);
+
+        for (int i = 0; i < nElems; i++) {
+            assertEquals(dst[i], src[i]);
+        }
+    }
+
+    void helperShortCopy(int nElems) {
+        Allocation A = Allocation.createSized(mRS, Element.I16(mRS), nElems);
+
+        short src[], dst[];
+        src = new short[nElems];
+        dst = new short[nElems];
+        for (int i = 0; i < nElems; i++) {
+            src[i] = (short)i;
+            dst[i] = -1;
+        }
+
+        A.copyFrom(src);
+        A.copyTo(dst);
+
+        for (int i = 0; i < nElems; i++) {
+            assertEquals(dst[i], src[i]);
+        }
+    }
+
+    void helperIntCopy(int nElems) {
+        Allocation A = Allocation.createSized(mRS, Element.I32(mRS), nElems);
+
+        int src[], dst[];
+        src = new int[nElems];
+        dst = new int[nElems];
+        for (int i = 0; i < nElems; i++) {
+            src[i] = i;
+            dst[i] = -1;
+        }
+
+        A.copyFrom(src);
+        A.copyTo(dst);
+
+        for (int i = 0; i < nElems; i++) {
+            assertEquals(dst[i], src[i]);
+        }
+    }
+
+    void helperBaseObjCopy(int nElems) {
+        Allocation A =
+            Allocation.createSized(mRS, Element.ELEMENT(mRS), nElems);
+        Element E[] = new Element[nElems];
+        for (int i = 0; i < nElems; i++) {
+            E[i] = Element.BOOLEAN(mRS);
+        }
+
+        A.copyFrom(E);
+    }
+
+    void helperBitmapCopy(int x, int y) {
+        Bitmap bSrc = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
+        Bitmap bDst = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888);
+
+        for (int j = 0; j < y; j++) {
+            for (int i = 0; i < x; i++) {
+                bSrc.setPixel(i, j, 9);
+                bDst.setPixel(i, j, 0);
+            }
+        }
+
+        Type.Builder typeBuilder =
+            new Type.Builder(mRS, Element.RGBA_8888(mRS));
+        typeBuilder.setMipmaps(false);
+        typeBuilder.setFaces(false);
+        typeBuilder.setX(x).setY(y);
+        Allocation A = Allocation.createTyped(mRS, typeBuilder.create());
+
+        A.copyFrom(bSrc);
+        A.copyTo(bDst);
+
+        for (int j = 0; j < y; j++) {
+            for (int i = 0; i < x; i++) {
+                assertEquals(bSrc.getPixel(i, j), bDst.getPixel(i, j));
+            }
+        }
+    }
+
+    static int elemsToTest = 20;
+
+    public void testCopyOperations() {
+        for (int s = 8; s <= elemsToTest; s += 2) {
+            helperFloatCopy(s);
+            helperByteCopy(s);
+            helperShortCopy(s);
+            helperIntCopy(s);
+            helperBaseObjCopy(s);
+        }
+        helperBitmapCopy(bDimX, bDimY);
+    }
 }
 
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/BaseObjTest.java b/tests/tests/renderscript/src/android/renderscript/cts/BaseObjTest.java
new file mode 100644
index 0000000..a079951
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/BaseObjTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.renderscript.cts;
+
+import android.renderscript.BaseObj;
+import android.renderscript.Font;
+import android.renderscript.Font.Style;
+import android.renderscript.RSIllegalArgumentException;
+
+public class BaseObjTest extends RSBaseGraphics {
+
+    public void testBaseObj() {
+        Style S = Font.Style.NORMAL;
+        Font F = Font.create(mRS, mRes, "sans-serif", S, 8);
+        assertTrue(F != null);
+        BaseObj B = F;
+        B.setName("sans-serif");
+        try {
+            B.setName("sans-serif");
+            fail("set name twice for a BaseObj");
+        } catch (RSIllegalArgumentException e) {
+        }
+        B.destroy();
+
+        F = Font.create(mRS, mRes, "serif", S, 8);
+        assertTrue(F != null);
+        B = F;
+        try {
+            B.setName("");
+            fail("set empty name for a BaseObj");
+        } catch (RSIllegalArgumentException e) {
+        }
+        B.setName("serif");
+        B.destroy();
+
+        F = Font.create(mRS, mRes, "mono", S, 8);
+        assertTrue(F != null);
+        B = F;
+        try {
+            B.setName(null);
+            fail("set name as null string reference for a BaseObj");
+        } catch (RSIllegalArgumentException e) {
+        }
+        B.setName("mono");
+        B.destroy();
+    }
+}
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java
index a5c4f16..8d24227 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java
@@ -16,15 +16,111 @@
 
 package android.renderscript.cts;
 
-import android.content.Context;
-import android.content.res.Resources;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScript.RSMessageHandler;
-import android.test.AndroidTestCase;
+import android.renderscript.Allocation;
+
+import android.renderscript.Byte2;
+import android.renderscript.Byte3;
+import android.renderscript.Byte4;
+
+import android.renderscript.Float2;
+import android.renderscript.Float3;
+import android.renderscript.Float4;
+
+import android.renderscript.Int2;
+import android.renderscript.Int3;
+import android.renderscript.Int4;
+
+import android.renderscript.Long2;
+import android.renderscript.Long3;
+import android.renderscript.Long4;
+
+import android.renderscript.Short2;
+import android.renderscript.Short3;
+import android.renderscript.Short4;
+
 import com.android.cts.stub.R;
 
 public class ComputeTest extends RSBaseCompute {
 
+    public void testJavaVectorTypes() {
+        Byte2 b2 = new Byte2();
+        b2.x = 1;
+        b2.y = 2;
+        Byte3 b3 = new Byte3();
+        b3.x = 1;
+        b3.y = 2;
+        b3.z = 2;
+        Byte4 b4 = new Byte4();
+        b4.x = 1;
+        b4.y = 2;
+        b4.x = 3;
+        b4.w = 4;
+
+        Float2 f2 = new Float2();
+        f2.x = 1.0f;
+        f2.y = 2.0f;
+        f2 = new Float2(1.0f, 2.0f);
+        assertTrue(f2.x == 1.0f);
+        assertTrue(f2.y == 2.0f);
+        Float3 f3 = new Float3();
+        f3.x = 1.0f;
+        f3.y = 2.0f;
+        f3.z = 3.0f;
+        f3 = new Float3(1.0f, 2.0f, 3.0f);
+        assertTrue(f3.x == 1.0f);
+        assertTrue(f3.y == 2.0f);
+        assertTrue(f3.z == 3.0f);
+        Float4 f4 = new Float4();
+        f4.x = 1.0f;
+        f4.y = 2.0f;
+        f4.x = 3.0f;
+        f4.w = 4.0f;
+        f4 = new Float4(1.0f, 2.0f, 3.0f, 4.0f);
+        assertTrue(f4.x == 1.0f);
+        assertTrue(f4.y == 2.0f);
+        assertTrue(f4.z == 3.0f);
+        assertTrue(f4.w == 4.0f);
+
+        Int2 i2 = new Int2();
+        i2.x = 1;
+        i2.y = 2;
+        Int3 i3 = new Int3();
+        i3.x = 1;
+        i3.y = 2;
+        i3.z = 3;
+        Int4 i4 = new Int4();
+        i4.x = 1;
+        i4.y = 2;
+        i4.x = 3;
+        i4.w = 4;
+
+        Long2 l2 = new Long2();
+        l2.x = 1;
+        l2.y = 2;
+        Long3 l3 = new Long3();
+        l3.x = 1;
+        l3.y = 2;
+        l3.z = 3;
+        Long4 l4 = new Long4();
+        l4.x = 1;
+        l4.y = 2;
+        l4.x = 3;
+        l4.w = 4;
+
+        Short2 s2 = new Short2();
+        s2.x = 1;
+        s2.y = 2;
+        Short3 s3 = new Short3();
+        s3.x = 1;
+        s3.y = 2;
+        s3.z = 3;
+        Short4 s4 = new Short4();
+        s4.x = 1;
+        s4.y = 2;
+        s4.x = 3;
+        s4.w = 4;
+    }
+
     private boolean initializeGlobals(ScriptC_primitives s) {
         float pF = s.get_floatTest();
         if (pF != 1.99f) {
@@ -68,7 +164,6 @@
         }
         s.set_ulongTest(4611686018427387903L);
 
-
         long pLL = s.get_longlongTest();
         if (pLL != 68719476736L) {
             return false;
@@ -81,6 +176,54 @@
         }
         s.set_uint64_tTest(117179869185l);
 
+        ScriptField_AllVectorTypes avt;
+        avt = new ScriptField_AllVectorTypes(mRS, 1,
+                                             Allocation.USAGE_SCRIPT);
+        ScriptField_AllVectorTypes.Item avtItem;
+        avtItem = new ScriptField_AllVectorTypes.Item();
+        avtItem.b2.x = 1;
+        avtItem.b2.y = 2;
+        avtItem.b3.x = 1;
+        avtItem.b3.y = 2;
+        avtItem.b3.z = 3;
+        avtItem.b4.x = 1;
+        avtItem.b4.y = 2;
+        avtItem.b4.z = 3;
+        avtItem.b4.w = 4;
+
+        avtItem.s2.x = 1;
+        avtItem.s2.y = 2;
+        avtItem.s3.x = 1;
+        avtItem.s3.y = 2;
+        avtItem.s3.z = 3;
+        avtItem.s4.x = 1;
+        avtItem.s4.y = 2;
+        avtItem.s4.z = 3;
+        avtItem.s4.w = 4;
+
+        avtItem.i2.x = 1;
+        avtItem.i2.y = 2;
+        avtItem.i3.x = 1;
+        avtItem.i3.y = 2;
+        avtItem.i3.z = 3;
+        avtItem.i4.x = 1;
+        avtItem.i4.y = 2;
+        avtItem.i4.z = 3;
+        avtItem.i4.w = 4;
+
+        avtItem.f2.x = 1.0f;
+        avtItem.f2.y = 2.0f;
+        avtItem.f3.x = 1.0f;
+        avtItem.f3.y = 2.0f;
+        avtItem.f3.z = 3.0f;
+        avtItem.f4.x = 1.0f;
+        avtItem.f4.y = 2.0f;
+        avtItem.f4.z = 3.0f;
+        avtItem.f4.w = 4.0f;
+
+        avt.set(avtItem, 0, true);
+        s.bind_avt(avt);
+
         return true;
     }
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java
index 55572a3..0f58d55 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java
@@ -16,8 +16,6 @@
 
 package android.renderscript.cts;
 
-import com.android.cts.stub.R;
-
 import android.renderscript.Element;
 import android.renderscript.Element.DataType;
 import android.renderscript.Element.DataKind;
@@ -86,6 +84,7 @@
         assertTrue(Element.MATRIX_2X2(mRS) != null);
         assertTrue(Element.MATRIX_3X3(mRS) != null);
         assertTrue(Element.MATRIX_4X4(mRS) != null);
+        assertTrue(Element.MATRIX4X4(mRS) != null);
         assertTrue(Element.MESH(mRS) != null);
         assertTrue(Element.PROGRAM_FRAGMENT(mRS) != null);
         assertTrue(Element.PROGRAM_RASTER(mRS) != null);
@@ -126,6 +125,7 @@
             eb.add(Element.MATRIX_2X2(mRS), "MATRIX_2X2", arraySize);
             eb.add(Element.MATRIX_3X3(mRS), "MATRIX_3X3", arraySize);
             eb.add(Element.MATRIX_4X4(mRS), "MATRIX_4X4", arraySize);
+            eb.add(Element.MATRIX4X4(mRS), "MATRIX4X4", arraySize);
             eb.add(Element.MESH(mRS), "MESH", arraySize);
             eb.add(Element.PROGRAM_FRAGMENT(mRS), "PROGRAM_FRAGMENT", arraySize);
             eb.add(Element.PROGRAM_RASTER(mRS), "PROGRAM_RASTER", arraySize);
@@ -165,6 +165,7 @@
         assertFalse(Element.MATRIX_2X2(mRS).isComplex());
         assertFalse(Element.MATRIX_3X3(mRS).isComplex());
         assertFalse(Element.MATRIX_4X4(mRS).isComplex());
+        assertFalse(Element.MATRIX4X4(mRS).isComplex());
         assertFalse(Element.MESH(mRS).isComplex());
         assertFalse(Element.PROGRAM_FRAGMENT(mRS).isComplex());
         assertFalse(Element.PROGRAM_RASTER(mRS).isComplex());
@@ -194,6 +195,65 @@
         eb.add(e2, "e2");
         assertTrue(eb.create().isComplex());
     }
+
+    public void testDataType() {
+        assertEquals(DataType.FLOAT_32, DataType.valueOf("FLOAT_32"));
+        assertEquals(DataType.FLOAT_64, DataType.valueOf("FLOAT_64"));
+        assertEquals(DataType.SIGNED_8, DataType.valueOf("SIGNED_8"));
+        assertEquals(DataType.SIGNED_16, DataType.valueOf("SIGNED_16"));
+        assertEquals(DataType.SIGNED_32, DataType.valueOf("SIGNED_32"));
+        assertEquals(DataType.SIGNED_64, DataType.valueOf("SIGNED_64"));
+        assertEquals(DataType.UNSIGNED_8, DataType.valueOf("UNSIGNED_8"));
+        assertEquals(DataType.UNSIGNED_16, DataType.valueOf("UNSIGNED_16"));
+        assertEquals(DataType.UNSIGNED_32, DataType.valueOf("UNSIGNED_32"));
+        assertEquals(DataType.UNSIGNED_64, DataType.valueOf("UNSIGNED_64"));
+
+        assertEquals(DataType.BOOLEAN, DataType.valueOf("BOOLEAN"));
+
+        assertEquals(DataType.UNSIGNED_5_6_5, DataType.valueOf("UNSIGNED_5_6_5"));
+        assertEquals(DataType.UNSIGNED_5_5_5_1, DataType.valueOf("UNSIGNED_5_5_5_1"));
+        assertEquals(DataType.UNSIGNED_4_4_4_4, DataType.valueOf("UNSIGNED_4_4_4_4"));
+
+        assertEquals(DataType.MATRIX_4X4, DataType.valueOf("MATRIX_4X4"));
+        assertEquals(DataType.MATRIX_3X3, DataType.valueOf("MATRIX_3X3"));
+        assertEquals(DataType.MATRIX_2X2, DataType.valueOf("MATRIX_2X2"));
+
+        assertEquals(DataType.RS_ELEMENT, DataType.valueOf("RS_ELEMENT"));
+        assertEquals(DataType.RS_TYPE, DataType.valueOf("RS_TYPE"));
+        assertEquals(DataType.RS_ALLOCATION, DataType.valueOf("RS_ALLOCATION"));
+        assertEquals(DataType.RS_SAMPLER, DataType.valueOf("RS_SAMPLER"));
+        assertEquals(DataType.RS_SCRIPT, DataType.valueOf("RS_SCRIPT"));
+        assertEquals(DataType.RS_MESH, DataType.valueOf("RS_MESH"));
+        assertEquals(DataType.RS_PROGRAM_FRAGMENT, DataType.valueOf("RS_PROGRAM_FRAGMENT"));
+        assertEquals(DataType.RS_PROGRAM_VERTEX, DataType.valueOf("RS_PROGRAM_VERTEX"));
+        assertEquals(DataType.RS_PROGRAM_RASTER, DataType.valueOf("RS_PROGRAM_RASTER"));
+        assertEquals(DataType.RS_PROGRAM_STORE, DataType.valueOf("RS_PROGRAM_STORE"));
+        // Make sure no new enums are added
+        assertEquals(27, DataType.values().length);
+
+        for (DataType dt : DataType.values()) {
+            Element.createVector(mRS, dt, 2);
+        }
+    }
+
+    public void testDataKind() {
+        assertEquals(DataKind.USER, DataKind.valueOf("USER"));
+
+        assertEquals(DataKind.PIXEL_L, DataKind.valueOf("PIXEL_L"));
+        assertEquals(DataKind.PIXEL_A, DataKind.valueOf("PIXEL_A"));
+        assertEquals(DataKind.PIXEL_LA, DataKind.valueOf("PIXEL_LA"));
+        assertEquals(DataKind.PIXEL_RGB, DataKind.valueOf("PIXEL_RGB"));
+        assertEquals(DataKind.PIXEL_RGBA, DataKind.valueOf("PIXEL_RGBA"));
+        assertEquals(DataKind.PIXEL_DEPTH, DataKind.valueOf("PIXEL_DEPTH"));
+        // Make sure no new enums are added
+        assertEquals(7, DataKind.values().length);
+
+        for (DataKind dk : DataKind.values()) {
+            if (dk != DataKind.USER) {
+                Element.createPixel(mRS, DataType.UNSIGNED_8, dk);
+            }
+        }
+    }
 }
 
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ExceptionTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ExceptionTest.java
new file mode 100644
index 0000000..3a9df46
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ExceptionTest.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.renderscript.cts;
+
+import android.renderscript.RSIllegalArgumentException;
+import android.renderscript.RSInvalidStateException;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.RSDriverException;
+
+import android.test.AndroidTestCase;
+
+public class ExceptionTest extends AndroidTestCase {
+    public void testExceptions() {
+        try {
+            throw new RSIllegalArgumentException("IAE");
+        } catch (RSIllegalArgumentException e) {
+            assertEquals(e.getMessage(), "IAE");
+        }
+
+        try {
+            throw new RSInvalidStateException("ISE");
+        } catch (RSInvalidStateException e) {
+            assertEquals(e.getMessage(), "ISE");
+        }
+
+        try {
+            throw new RSRuntimeException("RE");
+        } catch (RSRuntimeException e) {
+            assertEquals(e.getMessage(), "RE");
+        }
+
+        try {
+            throw new RSDriverException("DE");
+        } catch (RSDriverException e) {
+            assertEquals(e.getMessage(), "DE");
+        }
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FieldPackerTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FieldPackerTest.java
new file mode 100644
index 0000000..f986d4b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/FieldPackerTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.renderscript.cts;
+
+import android.renderscript.Byte2;
+import android.renderscript.Byte3;
+import android.renderscript.Byte4;
+import android.renderscript.FieldPacker;
+import android.renderscript.Float2;
+import android.renderscript.Float3;
+import android.renderscript.Float4;
+import android.renderscript.Int2;
+import android.renderscript.Int3;
+import android.renderscript.Int4;
+import android.renderscript.Long2;
+import android.renderscript.Long3;
+import android.renderscript.Long4;
+import android.renderscript.Matrix2f;
+import android.renderscript.Matrix3f;
+import android.renderscript.Matrix4f;
+import android.renderscript.Short2;
+import android.renderscript.Short3;
+import android.renderscript.Short4;
+
+public class FieldPackerTest extends RSBaseCompute {
+
+    public void testAddAllTypes() {
+        FieldPacker fp = new FieldPacker(1024);
+        fp.addBoolean(true);
+        fp.addF32(0.1f);
+        fp.addF32(new Float3());
+        fp.addF32(new Float4());
+        fp.addF32(new Float2());
+        fp.addF64(0.2);
+        fp.addI16(new Short3());
+        fp.addI16(new Short2());
+        fp.addI16((short)-2);
+        fp.addI16(new Short4());
+        fp.addI32(new Int3());
+        fp.addI32(-4);
+        fp.addI32(new Int4());
+        fp.addI32(new Int2());
+        fp.addI64(-8);
+        fp.addI8((byte)-1);
+        fp.addI8(new Byte4());
+        fp.addI8(new Byte2());
+        fp.addI8(new Byte3());
+        fp.addMatrix(new Matrix4f());
+        fp.addMatrix(new Matrix3f());
+        fp.addMatrix(new Matrix2f());
+        fp.addObj(null);
+        fp.addU16(new Int2());
+        fp.addU16(new Int4());
+        fp.addU16((short)2);
+        fp.addU16(new Int3());
+        fp.addU32(new Long4());
+        fp.addU32(new Long2());
+        fp.addU32(new Long3());
+        fp.addU32(4);
+        fp.addU64(8);
+        fp.addU8(new Short2());
+        fp.addU8(new Short4());
+        fp.addU8((byte)1);
+        fp.addU8(new Short3());
+    }
+
+    public void testAlign() {
+        /*
+        fp.align(int v);
+        final byte[]     getData();
+        fp.reset(int i);
+        fp.reset();
+        fp.skip(int i);
+        */
+    }
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FileA3DTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FileA3DTest.java
new file mode 100644
index 0000000..ca2bb38
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/FileA3DTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.renderscript.cts;
+
+import java.io.File;
+
+import com.android.cts.stub.R;
+
+import android.renderscript.RSRuntimeException;
+import android.renderscript.FileA3D;
+import android.renderscript.FileA3D.EntryType;
+import android.renderscript.FileA3D.IndexEntry;
+
+public class FileA3DTest extends RSBaseGraphics {
+
+    public void testCreateFromResource() {
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.sphere);
+        assertTrue(model != null);
+    }
+
+    public void testCreateFromAsset() {
+        FileA3D model = FileA3D.createFromAsset(mRS, mRes.getAssets(), "sphere.a3d");
+        assertTrue(model != null);
+    }
+
+    public void testGetIndexEntryCount() {
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.sphere);
+        assertTrue(model != null);
+        assertTrue(model.getIndexEntryCount() == 1);
+    }
+
+    public void testGetIndexEntry() {
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.sphere);
+        assertTrue(model != null);
+        assertTrue(model.getIndexEntryCount() == 1);
+        assertTrue(model.getIndexEntry(0) != null);
+    }
+
+    public void testIndexEntryGetEntryType() {
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.sphere);
+        assertTrue(model != null);
+        assertTrue(model.getIndexEntryCount() == 1);
+        FileA3D.IndexEntry entry = model.getIndexEntry(0);
+        assertTrue(entry != null);
+        assertTrue(entry.getEntryType() == FileA3D.EntryType.MESH);
+        boolean isOneOfEntries = false;
+        for(FileA3D.EntryType et : FileA3D.EntryType.values()) {
+            if (et == entry.getEntryType()) {
+                isOneOfEntries = true;
+                break;
+            }
+        }
+        assertTrue(isOneOfEntries);
+    }
+
+    public void testIndexEntryGetMesh() {
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.sphere);
+        assertTrue(model != null);
+        assertTrue(model.getIndexEntryCount() == 1);
+        FileA3D.IndexEntry entry = model.getIndexEntry(0);
+        assertTrue(entry != null);
+        assertTrue(entry.getEntryType() == FileA3D.EntryType.MESH);
+        assertTrue(entry.getMesh() != null);
+    }
+
+    public void testIndexEntryGetName() {
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.sphere);
+        assertTrue(model != null);
+        assertTrue(model.getIndexEntryCount() == 1);
+        FileA3D.IndexEntry entry = model.getIndexEntry(0);
+        assertTrue(entry != null);
+        assertTrue(entry.getName() != null);
+    }
+
+    public void testIndexEntryGetObject() {
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.sphere);
+        assertTrue(model != null);
+        assertTrue(model.getIndexEntryCount() == 1);
+        FileA3D.IndexEntry entry = model.getIndexEntry(0);
+        assertTrue(entry != null);
+        assertTrue(entry.getObject() != null);
+    }
+
+    public void testFileA3DEntryType() {
+        assertEquals(FileA3D.EntryType.UNKNOWN, FileA3D.EntryType.valueOf("UNKNOWN"));
+        assertEquals(FileA3D.EntryType.MESH, FileA3D.EntryType.valueOf("MESH"));
+        // Make sure no new enums are added
+        assertEquals(2, FileA3D.EntryType.values().length);
+    }
+
+    public void testCreateFromFile() {
+        File fileDesc = new File("bogusFile");
+        try {
+            FileA3D model = FileA3D.createFromFile(mRS, fileDesc);
+            fail("should throw RSRuntimeException.");
+        } catch (RSRuntimeException e) {
+        }
+        try {
+            FileA3D model = FileA3D.createFromFile(mRS, "bogus");
+            fail("should throw RSRuntimeException.");
+        } catch (RSRuntimeException e) {
+        }
+    }
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/FontTest.java b/tests/tests/renderscript/src/android/renderscript/cts/FontTest.java
new file mode 100644
index 0000000..e2405e8
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/FontTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.renderscript.cts;
+
+import java.io.File;
+import com.android.cts.stub.R;
+
+import android.os.Environment;
+import android.renderscript.Font;
+import android.renderscript.Font.Style;
+import android.renderscript.RSIllegalArgumentException;
+
+public class FontTest extends RSBaseGraphics {
+
+    public void testCreate() {
+        for (int fontSize = 8; fontSize <= 12; fontSize += 2) {
+            for (Font.Style style : Font.Style.values()) {
+                Font F = null;
+                F = Font.create(mRS, mRes, "sans-serif", style, fontSize);
+                assertTrue(F != null);
+                F.setName("sans-serif");
+                try {
+                    F.setName("sans-serif");
+                    fail("set name twice for a font");
+                } catch (RSIllegalArgumentException e) {
+                }
+                F.destroy();
+
+                F = Font.create(mRS, mRes, "serif", style, fontSize);
+                assertTrue(F != null);
+                try {
+                    F.setName("");
+                    fail("set empty name for a font");
+                } catch (RSIllegalArgumentException e) {
+                }
+                F.setName("serif");
+                F.destroy();
+
+                F = Font.create(mRS, mRes, "mono", style, fontSize);
+                assertTrue(F != null);
+                try {
+                    F.setName(null);
+                    fail("set name as null string reference for a font");
+                } catch (RSIllegalArgumentException e) {
+                }
+                F.setName("mono");
+                F.destroy();
+            }
+        }
+    }
+
+    public void testCreateFromFile() {
+        String fontFile = "DroidSans.ttf";
+        String fontPath = Environment.getRootDirectory().getAbsolutePath();
+        fontPath += "/fonts/" + fontFile;
+        File fileDesc = new File(fontPath);
+        assertTrue(Font.createFromFile(mRS, mRes, fontPath, 8) != null);
+        assertTrue(Font.createFromFile(mRS, mRes, fileDesc, 8) != null);
+    }
+
+    public void testCreateFromAsset() {
+        assertTrue(Font.createFromAsset(mRS, mRes, "samplefont.ttf", 8) != null);
+    }
+
+    public void testFontStyle() {
+        assertEquals(Font.Style.NORMAL, Font.Style.valueOf("NORMAL"));
+        assertEquals(Font.Style.BOLD, Font.Style.valueOf("BOLD"));
+        assertEquals(Font.Style.ITALIC, Font.Style.valueOf("ITALIC"));
+        assertEquals(Font.Style.BOLD_ITALIC, Font.Style.valueOf("BOLD_ITALIC"));
+        // Make sure no new enums are added
+        assertEquals(4, Font.Style.values().length);
+    }
+
+    public void testCreateFromResource() {
+        assertTrue(Font.createFromResource(mRS, mRes, R.raw.samplefont, 8) != null);
+    }
+}
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Matrix2fTest.java b/tests/tests/renderscript/src/android/renderscript/cts/Matrix2fTest.java
new file mode 100755
index 0000000..fa7c5d5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Matrix2fTest.java
@@ -0,0 +1,214 @@
+/*
+ * 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.renderscript.cts;
+import android.renderscript.Matrix2f;
+
+public class Matrix2fTest extends RSBaseCompute {
+
+    final float delta = 0.00001f;
+    final float[] setData = {
+            1.0f, 2.0f,
+            3.0f, 4.0f
+        };
+
+    void checkIdentity(Matrix2f m, float delta) {
+        for (int i = 0; i < 2; i ++) {
+            for (int j = 0; j < 2; j ++) {
+                if (i == j) {
+                    assertEquals(1.0f, m.getArray()[i*2 + j], delta);
+                } else {
+                    assertEquals(0.0f, m.getArray()[i*2 + j], delta);
+                }
+            }
+        }
+    }
+
+    String getString(float[] array) {
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < 2; i ++) {
+            builder.append("[");
+            for (int j = 0; j < 2; j ++) {
+                builder.append(array[i*2 + j]);
+                builder.append(" ");
+            }
+            builder.append("]");
+        }
+        return builder.toString();
+    }
+
+    void checkData(Matrix2f m, float[] data, float delta) {
+        for (int i = 0; i < data.length; i ++) {
+            assertEquals(data[i], m.getArray()[i], delta);
+        }
+    }
+
+    void checkData(Matrix2f m, float[] data) {
+        String s1 = getString(m.getArray());
+        String s2 = getString(data);
+        assertEquals(s2, s1);
+    }
+
+    public void testCreation() {
+        Matrix2f m = new Matrix2f();
+        assertTrue(m.getArray() != null);
+        checkIdentity(m, 0.0f);
+
+        m = new Matrix2f(setData);
+        checkData(m, setData);
+    }
+
+    public void testGet() {
+
+        Matrix2f m = new Matrix2f(setData);
+
+        for (int i = 0; i < 2; i ++) {
+            for (int j = 0; j < 2; j ++) {
+                assertEquals(setData[i*2 + j], m.get(i, j), 0.0f);
+            }
+        }
+    }
+
+    public void testSet() {
+        Matrix2f m = new Matrix2f();
+        for (int i = 0; i < 2; i ++) {
+            for (int j = 0; j < 2; j ++) {
+                float valToSet = setData[i*2 + j];
+                m.set(i, j, valToSet);
+                assertEquals(valToSet, m.get(i, j), 0.0f);
+            }
+        }
+    }
+
+    public void testLoadIdentity() {
+        Matrix2f m = new Matrix2f(setData);
+        m.loadIdentity();
+        checkIdentity(m, 0.0f);
+    }
+
+    public void testLoad() {
+        Matrix2f m1 = new Matrix2f();
+        Matrix2f m2 = new Matrix2f(setData);
+
+        m1.load(m2);
+        checkData(m1, setData);
+    }
+
+    public void testLoadScale() {
+        float[] expectedData = {
+            2.0f, 0.0f,
+            0.0f, 3.0f
+        };
+
+        Matrix2f m = new Matrix2f(setData);
+        m.loadScale(2.0f, 3.0f);
+        checkData(m, expectedData);
+    }
+
+    public void testMultiply() {
+        float[] lhsData = {
+            1.0f, 1.0f,
+            1.0f, 1.0f
+        };
+
+        float[] rhsData = {
+            2.0f, 2.0f,
+            3.0f, 3.0f
+        };
+
+        float[] expected = {
+            2.0f*2.0f, 2.0f*2.0f,
+            2.0f*3.0f, 2.0f*3.0f
+        };
+
+        // Due to column major nature of OpenGL,
+        // left hand side and right hand side
+        // are reversed. Premultiplying by row major
+        // and post multiplying by column major
+        // are the same. So lhs and rhs get reversed here.
+        Matrix2f lhs = new Matrix2f(lhsData);
+        Matrix2f rhs = new Matrix2f(rhsData);
+        Matrix2f loadMul = new Matrix2f();
+
+        loadMul.loadMultiply(lhs, rhs);
+        checkData(loadMul, expected);
+
+        lhs.multiply(rhs);
+        checkData(lhs, expected);
+    }
+
+    public void testScale() {
+        float[] expectedData = new float[setData.length];
+        System.arraycopy(setData, 0, expectedData, 0, setData.length);
+        float scaleX = 2.0f;
+        float scaleY = 3.0f;
+        expectedData[0] *= scaleX;
+        expectedData[1] *= scaleX;
+        expectedData[2] *= scaleY;
+        expectedData[3] *= scaleY;
+
+        Matrix2f m = new Matrix2f(setData);
+        m.scale(scaleX, scaleY);
+        checkData(m, expectedData);
+    }
+
+    public void testTranspose() {
+        float[] expectedData = new float[setData.length];
+        System.arraycopy(setData, 0, expectedData, 0, setData.length);
+        float temp = expectedData[1];
+        expectedData[1] = expectedData[2];
+        expectedData[2] = temp;
+
+        Matrix2f m = new Matrix2f(setData);
+        m.transpose();
+
+        checkData(m, expectedData);
+    }
+
+    public void testRotateLoadRotate() {
+
+        float theta = 30.0f * (float)(java.lang.Math.PI / 180.0f);
+        float cosTheta = (float)Math.cos((float)theta);
+        float sinTheta = (float)Math.sin((float)theta);
+        float[] rotate = new float[4];
+        rotate[0] = cosTheta;
+        rotate[1] = -sinTheta;
+        rotate[2] = sinTheta;
+        rotate[3] = cosTheta;
+
+        Matrix2f m = new Matrix2f();
+        m.loadRotate(30.0f);
+        checkData(m, rotate);
+
+        m = new Matrix2f();
+        m.rotate(30.0f);
+        checkData(m, rotate);
+
+        float[] sourceData = {
+            2.0f, 3.0f,
+            4.0f, 5.0f
+        };
+        float[] rotated = new float[4];
+        rotated[0] = rotate[0] * sourceData[0] + rotate[1] * sourceData[2];
+        rotated[1] = rotate[0] * sourceData[1] + rotate[1] * sourceData[3];
+        rotated[2] = rotate[2] * sourceData[0] + rotate[3] * sourceData[2];
+        rotated[3] = rotate[2] * sourceData[1] + rotate[3] * sourceData[3];
+        m = new Matrix2f(sourceData);
+        m.rotate(30.0f);
+
+        checkData(m, rotated);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Matrix3fTest.java b/tests/tests/renderscript/src/android/renderscript/cts/Matrix3fTest.java
new file mode 100755
index 0000000..f817cab
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Matrix3fTest.java
@@ -0,0 +1,229 @@
+/*
+ * 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.renderscript.cts;
+import android.renderscript.Matrix3f;
+
+public class Matrix3fTest extends RSBaseCompute {
+
+    final float delta = 0.00001f;
+    final float[] setData = {
+            1.0f, 2.0f, 3.0f,
+            4.0f, 5.0f, 6.0f,
+            7.0f, 8.0f, 9.0f
+        };
+
+    void checkIdentity(Matrix3f m, float delta) {
+        for (int i = 0; i < 3; i ++) {
+            for (int j = 0; j < 3; j ++) {
+                if (i == j) {
+                    assertEquals(1.0f, m.getArray()[i*3 + j], delta);
+                } else {
+                    assertEquals(0.0f, m.getArray()[i*3 + j], delta);
+                }
+            }
+        }
+    }
+
+    String getString(float[] array) {
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < 3; i ++) {
+            builder.append("[");
+            for (int j = 0; j < 3; j ++) {
+                builder.append(array[i*3 + j]);
+                builder.append(" ");
+            }
+            builder.append("]");
+        }
+        return builder.toString();
+    }
+
+    void checkData(Matrix3f m, float[] data, float delta) {
+        for (int i = 0; i < data.length; i ++) {
+            assertEquals(data[i], m.getArray()[i], delta);
+        }
+    }
+
+    void checkData(Matrix3f m, float[] data) {
+        String s1 = getString(m.getArray());
+        String s2 = getString(data);
+        assertEquals(s2, s1);
+    }
+
+    public void testCreation() {
+        Matrix3f m = new Matrix3f();
+        assertTrue(m.getArray() != null);
+        checkIdentity(m, 0.0f);
+
+        m = new Matrix3f(setData);
+        checkData(m, setData);
+    }
+
+    public void testGet() {
+
+        Matrix3f m = new Matrix3f(setData);
+
+        for (int i = 0; i < 3; i ++) {
+            for (int j = 0; j < 3; j ++) {
+                assertEquals(setData[i*3 + j], m.get(i, j), 0.0f);
+            }
+        }
+    }
+
+    public void testSet() {
+        Matrix3f m = new Matrix3f();
+        for (int i = 0; i < 3; i ++) {
+            for (int j = 0; j < 3; j ++) {
+                float valToSet = setData[i*3 + j];
+                m.set(i, j, valToSet);
+                assertEquals(valToSet, m.get(i, j), 0.0f);
+            }
+        }
+    }
+
+    public void testLoadIdentity() {
+        Matrix3f m = new Matrix3f(setData);
+        m.loadIdentity();
+        checkIdentity(m, 0.0f);
+    }
+
+    public void testLoad() {
+        Matrix3f m1 = new Matrix3f();
+        Matrix3f m2 = new Matrix3f(setData);
+
+        m1.load(m2);
+        checkData(m1, setData);
+    }
+
+    public void testLoadScale() {
+        float[] expectedData = {
+            2.0f, 0.0f, 0.0f,
+            0.0f, 3.0f, 0.0f,
+            0.0f, 0.0f, 4.0f,
+        };
+        float[] expectedData2 = {
+            2.0f, 0.0f, 0.0f,
+            0.0f, 3.0f, 0.0f,
+            0.0f, 0.0f, 1.0f,
+        };
+
+        Matrix3f m = new Matrix3f(setData);
+        m.loadScale(2.0f, 3.0f, 4.0f);
+        checkData(m, expectedData);
+
+        m = new Matrix3f(setData);
+        m.loadScale(2.0f, 3.0f);
+        checkData(m, expectedData2);
+    }
+
+    public void testLoadTranslate() {
+        float[] expectedData = {
+            1.0f, 0.0f, 0.0f,
+            0.0f, 1.0f, 0.0f,
+            2.0f, 3.0f, 1.0f,
+        };
+
+        Matrix3f m = new Matrix3f(setData);
+        m.loadTranslate(2.0f, 3.0f);
+        checkData(m, expectedData);
+    }
+
+    public void testScale() {
+        float[] expectedData = new float[setData.length];
+        System.arraycopy(setData, 0, expectedData, 0, setData.length);
+        float scaleX = 2.0f;
+        float scaleY = 3.0f;
+        float scaleZ = 4.0f;
+        expectedData[0] *= scaleX;
+        expectedData[1] *= scaleX;
+        expectedData[2] *= scaleX;
+        expectedData[3] *= scaleY;
+        expectedData[4] *= scaleY;
+        expectedData[5] *= scaleY;
+        expectedData[6] *= scaleZ;
+        expectedData[7] *= scaleZ;
+        expectedData[8] *= scaleZ;
+
+        Matrix3f m = new Matrix3f(setData);
+        m.scale(scaleX, scaleY, scaleZ);
+        checkData(m, expectedData);
+
+        System.arraycopy(setData, 0, expectedData, 0, setData.length);
+        expectedData[0] *= scaleX;
+        expectedData[1] *= scaleX;
+        expectedData[2] *= scaleX;
+        expectedData[3] *= scaleY;
+        expectedData[4] *= scaleY;
+        expectedData[5] *= scaleY;
+
+        m = new Matrix3f(setData);
+        m.scale(scaleX, scaleY);
+        checkData(m, expectedData);
+    }
+
+    public void testMultiply() {
+        float[] lhsData = {
+            1.0f, 1.0f, 1.0f,
+            1.0f, 1.0f, 1.0f,
+            1.0f, 1.0f, 1.0f
+        };
+
+        float[] rhsData = {
+            2.0f, 2.0f, 2.0f,
+            3.0f, 3.0f, 3.0f,
+            4.0f, 4.0f, 4.0f
+        };
+
+        float[] expected = {
+            3.0f*2.0f, 3.0f*2.0f, 3.0f*2.0f,
+            3.0f*3.0f, 3.0f*3.0f, 3.0f*3.0f,
+            3.0f*4.0f, 3.0f*4.0f, 3.0f*4.0f
+        };
+
+        // Due to column major nature of OpenGL,
+        // left hand side and right hand side
+        // are reversed. Premultiplying by row major
+        // and post multiplying by column major
+        // are the same. So lhs and rhs get reversed here.
+        Matrix3f lhs = new Matrix3f(lhsData);
+        Matrix3f rhs = new Matrix3f(rhsData);
+        Matrix3f loadMul = new Matrix3f();
+
+        loadMul.loadMultiply(lhs, rhs);
+        checkData(loadMul, expected);
+
+        lhs.multiply(rhs);
+        checkData(lhs, expected);
+    }
+
+    public void testTranspose() {
+        float[] expectedData = new float[setData.length];
+        System.arraycopy(setData, 0, expectedData, 0, setData.length);
+
+        for(int i = 0; i < 2; i++) {
+            for(int j = i + 1; j < 3; j++) {
+                float temp = expectedData[i*3 + j];
+                expectedData[i*3 + j] = expectedData[j*3 + i];
+                expectedData[j*3 + i] = temp;
+            }
+        }
+
+        Matrix3f m = new Matrix3f(setData);
+        m.transpose();
+
+        checkData(m, expectedData);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Matrix4fTest.java b/tests/tests/renderscript/src/android/renderscript/cts/Matrix4fTest.java
new file mode 100755
index 0000000..8678578
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Matrix4fTest.java
@@ -0,0 +1,233 @@
+/*
+ * 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.renderscript.cts;
+import android.renderscript.Matrix4f;
+
+public class Matrix4fTest extends RSBaseCompute {
+
+    final float delta = 0.00001f;
+    final float[] setData = {
+            1.0f, 2.0f, 3.0f, 4.0f,
+            5.0f, 6.0f, 7.0f, 8.0f,
+            9.0f, 10.0f, 11.0f, 12.0f,
+            13.0f, 14.0f, 15.0f, 16.0f
+        };
+
+    void checkIdentity(Matrix4f m, float delta) {
+        for (int i = 0; i < 4; i ++) {
+            for (int j = 0; j < 4; j ++) {
+                if (i == j) {
+                    assertEquals(1.0f, m.getArray()[i*4 + j], delta);
+                } else {
+                    assertEquals(0.0f, m.getArray()[i*4 + j], delta);
+                }
+            }
+        }
+    }
+
+    String getString(float[] array) {
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < 4; i ++) {
+            builder.append("[");
+            for (int j = 0; j < 4; j ++) {
+                builder.append(array[i*4 + j]);
+                builder.append(" ");
+            }
+            builder.append("]");
+        }
+        return builder.toString();
+    }
+
+    void checkData(Matrix4f m, float[] data, float delta) {
+        for (int i = 0; i < data.length; i ++) {
+            assertEquals(data[i], m.getArray()[i], delta);
+        }
+    }
+
+    void checkData(Matrix4f m, float[] data) {
+        String s1 = getString(m.getArray());
+        String s2 = getString(data);
+        assertEquals(s2, s1);
+    }
+
+    public void testCreation() {
+        Matrix4f m = new Matrix4f();
+        assertTrue(m.getArray() != null);
+        checkIdentity(m, 0.0f);
+
+
+        m = new Matrix4f(setData);
+        checkData(m, setData);
+    }
+
+    public void testGet() {
+
+        Matrix4f m = new Matrix4f(setData);
+
+        for (int i = 0; i < 4; i ++) {
+            for (int j = 0; j < 4; j ++) {
+                assertEquals(setData[i*4 + j], m.get(i, j), 0.0f);
+            }
+        }
+    }
+
+    public void testSet() {
+        Matrix4f m = new Matrix4f();
+        for (int i = 0; i < 4; i ++) {
+            for (int j = 0; j < 4; j ++) {
+                float valToSet = setData[i*4 + j];
+                m.set(i, j, valToSet);
+                assertEquals(valToSet, m.get(i, j), 0.0f);
+            }
+        }
+    }
+
+    public void testLoadIdentity() {
+        Matrix4f m = new Matrix4f(setData);
+        m.loadIdentity();
+        checkIdentity(m, 0.0f);
+    }
+
+    public void testLoad() {
+        Matrix4f m1 = new Matrix4f();
+        Matrix4f m2 = new Matrix4f(setData);
+
+        m1.load(m2);
+        checkData(m1, setData);
+    }
+
+    public void testLoadScale() {
+        float[] expectedData = {
+            2.0f, 0.0f, 0.0f, 0.0f,
+            0.0f, 3.0f, 0.0f, 0.0f,
+            0.0f, 0.0f, 4.0f, 0.0f,
+            0.0f, 0.0f, 0.0f, 1.0f
+        };
+
+        Matrix4f m = new Matrix4f(setData);
+        m.loadScale(2.0f, 3.0f, 4.0f);
+        checkData(m, expectedData);
+    }
+
+    public void testLoadTranslate() {
+        float[] expectedData = {
+            1.0f, 0.0f, 0.0f, 0.0f,
+            0.0f, 1.0f, 0.0f, 0.0f,
+            0.0f, 0.0f, 1.0f, 0.0f,
+            2.0f, 3.0f, 4.0f, 1.0f
+        };
+
+        Matrix4f m = new Matrix4f(setData);
+        m.loadTranslate(2.0f, 3.0f, 4.0f);
+        checkData(m, expectedData);
+    }
+
+    public void testScale() {
+        float[] expectedData = new float[setData.length];
+        System.arraycopy(setData, 0, expectedData, 0, setData.length);
+        float scaleX = 2.0f;
+        float scaleY = 3.0f;
+        float scaleZ = 4.0f;
+        expectedData[0] *= scaleX;
+        expectedData[1] *= scaleX;
+        expectedData[2] *= scaleX;
+        expectedData[3] *= scaleX;
+        expectedData[4] *= scaleY;
+        expectedData[5] *= scaleY;
+        expectedData[6] *= scaleY;
+        expectedData[7] *= scaleY;
+        expectedData[8] *= scaleZ;
+        expectedData[9] *= scaleZ;
+        expectedData[10] *= scaleZ;
+        expectedData[11] *= scaleZ;
+
+        Matrix4f m = new Matrix4f(setData);
+        m.scale(scaleX, scaleY, scaleZ);
+        checkData(m, expectedData);
+    }
+
+    public void testTranspose() {
+        float[] expectedData = new float[setData.length];
+        System.arraycopy(setData, 0, expectedData, 0, setData.length);
+
+        for(int i = 0; i < 3; i++) {
+            for(int j = i + 1; j < 4; j++) {
+                float temp = expectedData[i*4 + j];
+                expectedData[i*4 + j] = expectedData[j*4 + i];
+                expectedData[j*4 + i] = temp;
+            }
+        }
+
+        Matrix4f m = new Matrix4f(setData);
+        m.transpose();
+
+        checkData(m, expectedData);
+    }
+
+    public void testMultiply() {
+        float[] lhsData = {
+            1.0f, 1.0f, 1.0f, 1.0f,
+            1.0f, 1.0f, 1.0f, 1.0f,
+            1.0f, 1.0f, 1.0f, 1.0f,
+            1.0f, 1.0f, 1.0f, 1.0f
+        };
+
+        float[] rhsData = {
+            2.0f, 2.0f, 2.0f, 2.0f,
+            3.0f, 3.0f, 3.0f, 3.0f,
+            4.0f, 4.0f, 4.0f, 4.0f,
+            5.0f, 5.0f, 5.0f, 5.0f
+        };
+
+        float[] expected = {
+            4.0f*2.0f, 4.0f*2.0f, 4.0f*2.0f, 4.0f*2.0f,
+            4.0f*3.0f, 4.0f*3.0f, 4.0f*3.0f, 4.0f*3.0f,
+            4.0f*4.0f, 4.0f*4.0f, 4.0f*4.0f, 4.0f*4.0f,
+            4.0f*5.0f, 4.0f*5.0f, 4.0f*5.0f, 4.0f*5.0f
+        };
+
+        // Due to column major nature of OpenGL,
+        // left hand side and right hand side
+        // are reversed. Premultiplying by row major
+        // and post multiplying by column major
+        // are the same. So lhs and rhs get reversed here.
+        Matrix4f lhs = new Matrix4f(lhsData);
+        Matrix4f rhs = new Matrix4f(rhsData);
+        Matrix4f loadMul = new Matrix4f();
+
+        loadMul.loadMultiply(lhs, rhs);
+        checkData(loadMul, expected);
+
+        lhs.multiply(rhs);
+        checkData(lhs, expected);
+    }
+
+    public void testInverse() {
+        Matrix4f m = new Matrix4f();
+        assertTrue(m.inverse());
+        checkIdentity(m, delta);
+
+        m = new Matrix4f();
+        m.scale(2.0f, 2.0f, 2.0f);
+        m.translate(5.0f, 6.0f, 7.0f);
+
+        Matrix4f m2 = new Matrix4f(m.getArray());
+        assertTrue(m2.inverse());
+        m.multiply(m2);
+        checkIdentity(m, delta);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/MeshTest.java b/tests/tests/renderscript/src/android/renderscript/cts/MeshTest.java
new file mode 100644
index 0000000..ffa733a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/MeshTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Type;
+import android.renderscript.Mesh;
+import android.renderscript.Mesh.Primitive;
+import android.renderscript.Mesh.AllocationBuilder;
+import android.renderscript.Mesh.Builder;
+import android.renderscript.Mesh.TriangleMeshBuilder;
+
+public class MeshTest extends RSBaseGraphics {
+
+    Allocation mAttrAlloc;
+    Allocation mIndexAlloc;
+    Element mPosElem;
+    Type mPosType;
+    Type mIndexType;
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Element.Builder eb = new Element.Builder(mRS);
+        eb.add(Element.F32_4(mRS), "position");
+        mPosElem = eb.create();
+        Type.Builder typeB = new Type.Builder(mRS, mPosElem);
+        mPosType = typeB.setX(3).create();
+        typeB = new Type.Builder(mRS, Element.U16(mRS));
+        mIndexType = typeB.setX(3).create();
+
+        mAttrAlloc = Allocation.createSized(mRS, mPosElem, 3);
+        mIndexAlloc = Allocation.createSized(mRS, Element.U16(mRS), 3);
+    }
+
+    public void testMeshAllocationBuilder() {
+        Mesh.AllocationBuilder mab;
+        for(Primitive prim : Primitive.values()) {
+            mab = new Mesh.AllocationBuilder(mRS);
+            mab.addVertexAllocation(mAttrAlloc);
+            mab.getCurrentVertexTypeIndex();
+            mab.addIndexSetType(prim);
+            assertTrue(mab.create() != null);
+
+            mab = new Mesh.AllocationBuilder(mRS);
+            mab.addVertexAllocation(mAttrAlloc);
+            mab.getCurrentVertexTypeIndex();
+            mab.addIndexSetAllocation(mIndexAlloc, prim);
+            mab.getCurrentIndexSetIndex();
+            mab.addIndexSetType(prim);
+
+            Mesh mesh = mab.create();
+            assertTrue(mesh != null);
+            assertTrue(mesh.getVertexAllocationCount() == 1);
+            assertTrue(mesh.getVertexAllocation(0) == mAttrAlloc);
+            assertTrue(mesh.getPrimitiveCount() == 2);
+            assertTrue(mesh.getPrimitive(0) == prim);
+            assertTrue(mesh.getPrimitive(1) == prim);
+            assertTrue(mesh.getIndexSetAllocation(0) == mIndexAlloc);
+        }
+    }
+
+    public void testMeshBuilder() {
+        Mesh.Builder mb;
+        for(Primitive prim : Primitive.values()) {
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosElem, 3);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(prim);
+            Mesh mesh = mb.create();
+            assertTrue(mesh != null);
+            assertTrue(mesh.getVertexAllocationCount() != 0);
+
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosElem, 3);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(Element.U16(mRS), 3, prim);
+            mb.getCurrentIndexSetIndex();
+            mesh = mb.create();
+            assertTrue(mesh != null);
+            assertTrue(mesh.getVertexAllocationCount() != 0);
+            assertTrue(mesh.getPrimitiveCount() != 0);
+
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosElem, 3);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(mIndexType, prim);
+            mb.getCurrentIndexSetIndex();
+            assertTrue(mb.create() != null);
+
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosType);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(prim);
+            assertTrue(mb.create() != null);
+
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosType);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(Element.U16(mRS), 3, prim);
+            mb.getCurrentIndexSetIndex();
+            assertTrue(mb.create() != null);
+
+            mb = new Mesh.Builder(mRS,
+                                  Allocation.USAGE_SCRIPT |
+                                  Allocation.USAGE_GRAPHICS_VERTEX);
+            mb.addVertexType(mPosType);
+            mb.getCurrentVertexTypeIndex();
+            mb.addIndexSetType(mIndexType, prim);
+            mb.getCurrentIndexSetIndex();
+            assertTrue(mb.create() != null);
+        }
+    }
+
+    void triangleMeshBuilderHelper(int size, int flags) {
+        // Test various num vertices and triangles
+        for (int numVerts = 3; numVerts < 100; numVerts += 15) {
+            for (int numTries = 1; numTries < 100; numTries += 15) {
+                Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, size, flags);
+                // Append all the vertices
+                for (int numVertsI = 0; numVertsI < numVerts; numVertsI++) {
+                    if (size == 2) {
+                        tmb.addVertex(1.0f, 1.0f);
+                    } else {
+                        tmb.addVertex(1.0f, 1.0f, 1.0f);
+                    }
+                    if ((flags & TriangleMeshBuilder.COLOR) != 0) {
+                        tmb.setColor(1.0f, 1.0f, 1.0f, 1.0f);
+                    }
+                    if ((flags & TriangleMeshBuilder.NORMAL) != 0) {
+                        tmb.setNormal(1.0f, 1.0f, 1.0f);
+                    }
+                    if ((flags & TriangleMeshBuilder.TEXTURE_0) != 0) {
+                        tmb.setTexture(1.0f, 1.0f);
+                    }
+                }
+                // Add triangles to index them
+                for (int numTriesI = 0; numTriesI < numTries; numTriesI ++) {
+                    tmb.addTriangle(0, 1, 2);
+                }
+                assertTrue(tmb.create(false) != null);
+                assertTrue(tmb.create(true) != null);
+            }
+        }
+    }
+
+    public void testMeshTriangleMeshBuilder() {
+        for (int size = 2; size <= 3; size ++) {
+            triangleMeshBuilderHelper(size, 0);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.COLOR);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.COLOR |
+                                            TriangleMeshBuilder.NORMAL);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.COLOR |
+                                            TriangleMeshBuilder.TEXTURE_0);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.COLOR |
+                                            TriangleMeshBuilder.NORMAL |
+                                            TriangleMeshBuilder.TEXTURE_0);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.NORMAL);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.NORMAL|
+                                            TriangleMeshBuilder.TEXTURE_0);
+            triangleMeshBuilderHelper(size, TriangleMeshBuilder.TEXTURE_0);
+        }
+    }
+
+    public void testMeshPrimitive() {
+        assertEquals(Mesh.Primitive.POINT, Mesh.Primitive.valueOf("POINT"));
+        assertEquals(Mesh.Primitive.LINE, Mesh.Primitive.valueOf("LINE"));
+        assertEquals(Mesh.Primitive.LINE_STRIP, Mesh.Primitive.valueOf("LINE_STRIP"));
+        assertEquals(Mesh.Primitive.TRIANGLE, Mesh.Primitive.valueOf("TRIANGLE"));
+        assertEquals(Mesh.Primitive.TRIANGLE_STRIP, Mesh.Primitive.valueOf("TRIANGLE_STRIP"));
+        assertEquals(Mesh.Primitive.TRIANGLE_FAN, Mesh.Primitive.valueOf("TRIANGLE_FAN"));
+        // Make sure no new enums are added
+        assertEquals(6, Mesh.Primitive.values().length);
+    }
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ProgramFragmentFixedFunctionTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ProgramFragmentFixedFunctionTest.java
new file mode 100644
index 0000000..ac54b74
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ProgramFragmentFixedFunctionTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.renderscript.cts;
+
+import com.android.cts.stub.R;
+import android.renderscript.Element;
+import android.renderscript.Type;
+import android.renderscript.Allocation;
+import android.renderscript.Sampler;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramFragmentFixedFunction;
+import android.renderscript.ProgramFragmentFixedFunction.Builder;
+
+public class ProgramFragmentFixedFunctionTest extends RSBaseGraphics {
+
+    ScriptC_graphics_runner mScript;
+
+    Allocation mTex2D;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Type.Builder typeB = new Type.Builder(mRS, Element.RGB_888(mRS));
+        typeB.setX(8).setY(8);
+        mTex2D = Allocation.createTyped(mRS, typeB.create(),
+                                        Allocation.USAGE_SCRIPT |
+                                        Allocation.USAGE_GRAPHICS_TEXTURE);
+
+        mScript = new ScriptC_graphics_runner(mRS, mRes, R.raw.graphics_runner);
+        mRS.bindRootScript(mScript);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mRS.bindRootScript(null);
+        super.tearDown();
+    }
+
+    void testProgramFragmentFixedFunctionBuilder(boolean testBind) {
+        ProgramFragmentFixedFunction.Builder b;
+        for (int tCount = 0; tCount <= Builder.MAX_TEXTURE; tCount ++) {
+            for (int varC = 0; varC <= 1; varC++) {
+                for (int pSprite = 0; pSprite <= 1; pSprite++) {
+                    for (Builder.EnvMode env : Builder.EnvMode.values()) {
+                        for (Builder.Format format : Builder.Format.values()) {
+                            b = new ProgramFragmentFixedFunction.Builder(mRS);
+                            b.setVaryingColor(varC == 1);
+                            b.setPointSpriteTexCoordinateReplacement(pSprite == 1);
+                            for (int t = 0; t < tCount; t++) {
+                                b.setTexture(env, format, t);
+                            }
+
+                            ProgramFragment pf = b.create();
+                            assertTrue(pf != null);
+                            for (int t = 0; t < tCount; t++) {
+                                pf.bindTexture(mTex2D, t);
+                                pf.bindSampler(Sampler.CLAMP_NEAREST(mRS), t);
+                            }
+                            if (testBind) {
+                                mScript.invoke_testProgramFragment(pf);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void testProgramFragmentFixedFunctionBuilder() {
+        testProgramFragmentFixedFunctionBuilder(false);
+        testProgramFragmentFixedFunctionBuilder(true);
+    }
+
+    public void testBuilderEnvMode() {
+        assertEquals(Builder.EnvMode.DECAL, Builder.EnvMode.valueOf("DECAL"));
+        assertEquals(Builder.EnvMode.MODULATE, Builder.EnvMode.valueOf("MODULATE"));
+        assertEquals(Builder.EnvMode.REPLACE, Builder.EnvMode.valueOf("REPLACE"));
+
+        // Make sure no new enums are added
+        assertEquals(3, Builder.EnvMode.values().length);
+    }
+
+    public void testBuilderFormat() {
+        assertEquals(Builder.Format.ALPHA, Builder.Format.valueOf("ALPHA"));
+        assertEquals(Builder.Format.LUMINANCE_ALPHA, Builder.Format.valueOf("LUMINANCE_ALPHA"));
+        assertEquals(Builder.Format.RGB, Builder.Format.valueOf("RGB"));
+        assertEquals(Builder.Format.RGBA, Builder.Format.valueOf("RGBA"));
+
+        // Make sure no new enums are added
+        assertEquals(4, Builder.Format.values().length);
+    }
+
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ProgramFragmentTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ProgramFragmentTest.java
new file mode 100644
index 0000000..d6a7f0d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ProgramFragmentTest.java
@@ -0,0 +1,221 @@
+/*
+ * 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.renderscript.cts;
+
+import com.android.cts.stub.R;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Program;
+import android.renderscript.ProgramFragment;
+import android.renderscript.Sampler;
+import android.renderscript.Type;
+
+public class ProgramFragmentTest extends RSBaseGraphics {
+
+    ScriptC_graphics_runner mScript;
+
+    Allocation mConstMatrix;
+    Allocation mConstComplex;
+    Allocation mConstExtra;
+
+    Allocation mTex2D;
+    Allocation mTexCube;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        Type.Builder typeB = new Type.Builder(mRS, Element.RGB_888(mRS));
+        typeB.setX(8).setY(8);
+        mTex2D = Allocation.createTyped(mRS, typeB.create(),
+                                        Allocation.USAGE_SCRIPT |
+                                        Allocation.USAGE_GRAPHICS_TEXTURE);
+        typeB.setFaces(true);
+        mTexCube = Allocation.createTyped(mRS, typeB.create(),
+                                          Allocation.USAGE_SCRIPT |
+                                          Allocation.USAGE_GRAPHICS_TEXTURE);
+
+        ScriptField_ConstMatrix c1 = new ScriptField_ConstMatrix(mRS, 1,
+                                                                 Allocation.USAGE_SCRIPT |
+                                                                 Allocation.USAGE_GRAPHICS_CONSTANTS);
+        c1.set(new ScriptField_ConstMatrix.Item(), 0, true);
+        mConstMatrix = c1.getAllocation();
+
+        ScriptField_ConstComplex c2 = new ScriptField_ConstComplex(mRS, 1,
+                                                                   Allocation.USAGE_SCRIPT |
+                                                                   Allocation.USAGE_GRAPHICS_CONSTANTS);
+        c2.set(new ScriptField_ConstComplex.Item(), 0, true);
+        mConstComplex = c2.getAllocation();
+
+        ScriptField_ConstExtra c3 = new ScriptField_ConstExtra(mRS, 1,
+                                                               Allocation.USAGE_SCRIPT |
+                                                               Allocation.USAGE_GRAPHICS_CONSTANTS);
+        c3.set(new ScriptField_ConstExtra.Item(), 0, true);
+        mConstExtra = c3.getAllocation();
+
+        mScript = new ScriptC_graphics_runner(mRS, mRes, R.raw.graphics_runner);
+        mRS.bindRootScript(mScript);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mRS.bindRootScript(null);
+        super.tearDown();
+    }
+
+    ProgramFragment buildShader(Allocation[] textures, Allocation[] constInput, String shader) {
+        ProgramFragment.Builder pfb = new ProgramFragment.Builder(mRS);
+        Program.BaseProgramBuilder bpb = pfb;
+        if (textures != null) {
+            for (int i = 0; i < textures.length; i++) {
+                Program.TextureType tType = Program.TextureType.TEXTURE_2D;
+                if (textures[i].getType().hasFaces()) {
+                    tType = Program.TextureType.TEXTURE_CUBE;
+                }
+                // Add textures through the base program builder
+                bpb.addTexture(tType);
+                bpb.getCurrentTextureIndex();
+            }
+        }
+
+        if (constInput != null) {
+            for (int i = 0; i < constInput.length; i++) {
+                bpb.addConstant(constInput[i].getType());
+                bpb.getCurrentConstantIndex();
+            }
+        }
+
+        bpb.setShader(shader);
+        ProgramFragment pf = pfb.create();
+        if (constInput != null) {
+            for (int i = 0; i < constInput.length; i++) {
+                pf.bindConstants(constInput[i], i);
+                // Test the base class path too
+                Program p = pf;
+                p.bindConstants(constInput[i], i);
+            }
+        }
+        if (textures != null) {
+            for (int i = 0; i < textures.length; i++) {
+                pf.bindTexture(textures[i], i);
+                pf.bindSampler(Sampler.CLAMP_NEAREST(mRS), i);
+                // Test the base class path too
+                Program p = pf;
+                p.bindTexture(textures[i], i);
+                p.bindSampler(Sampler.CLAMP_NEAREST(mRS), i);
+            }
+        }
+        return pf;
+    }
+
+    void testProgramFragmentBuilderHelper(boolean testBind) {
+        String simpleFrag = "void main() {\n"+
+                            "  vec4 col = vec4(0.1, 0.2, 0.3, 0.4);"+
+                            "  gl_FragColor = col;\n"+
+                            "}";
+
+        String simpleUni = "void main() {\n"+
+                           "  vec4 col = vec4(0.1, 0.2, 0.3, 0.4);\n"+
+                           "  col = UNI_MVP * col;\n"+
+                           "  gl_FragColor = col;\n"+
+                           "}";
+
+        String simpleUniTex = "void main() {\n"+
+                              "  vec4 col = vec4(0.1, 0.2, 0.3, 0.4);"+
+                              "  col += texture2D(UNI_Tex0, vec2(0.1, 0.1));\n"+
+                              "  col += textureCube(UNI_Tex1, vec3(0.1, 0.2, 0.3));\n"+
+                              "  col = UNI_MVP * col;\n"+
+                              "  gl_FragColor = col;\n"+
+                              "}";
+
+        String multiUni = "void main() {\n"+
+                          "  vec4 col = vec4(0.1, 0.2, 0.3, 0.4);"+
+                          "  col = UNI_MVP * col;\n"+
+                          "  col = UNI_EXTRA * col;\n"+
+                          "  col += UNI_extra4;\n"+
+                          "  col.xyz += UNI_extra3;\n "+
+                          "  col.xy += UNI_extra2;\n"+
+                          "  col.x += UNI_extra1;\n"+
+                          "  gl_FragColor = col;\n"+
+                          "}";
+
+        // Create a series of shaders that do nothing useful
+        // but exercise creation pipeline
+        ProgramFragment pf = buildShader(null, null, simpleFrag);
+        if (testBind) {
+            mScript.invoke_testProgramFragment(pf);
+        }
+
+        Allocation[] constInput = new Allocation[1];
+        constInput[0] = mConstMatrix;
+        pf = buildShader(null, constInput, simpleUni);
+        if (testBind) {
+            mScript.invoke_testProgramFragment(pf);
+            mRS.bindProgramFragment(pf);
+        }
+
+        constInput[0] = mConstComplex;
+        pf = buildShader(null, constInput, multiUni);
+        if (testBind) {
+            mScript.invoke_testProgramFragment(pf);
+            mRS.bindProgramFragment(pf);
+        }
+
+        Allocation[] textures = new Allocation[2];
+        textures[0] = mTex2D;
+        textures[1] = mTexCube;
+        pf = buildShader(textures, constInput, simpleUniTex);
+        if (testBind) {
+            mScript.invoke_testProgramFragment(pf);
+            mRS.bindProgramFragment(pf);
+        }
+
+        constInput = new Allocation[2];
+        constInput[0] = mConstMatrix;
+        constInput[1] = mConstExtra;
+        pf = buildShader(null, constInput, multiUni);
+        if (testBind) {
+            mScript.invoke_testProgramFragment(pf);
+            mRS.bindProgramFragment(pf);
+        }
+    }
+
+    public void testProgramFragmentBuilder() {
+        testProgramFragmentBuilderHelper(false);
+    }
+
+    public void testProgramFragmentCreation() {
+        testProgramFragmentBuilderHelper(true);
+    }
+
+    public void testProgramTextureType() {
+        assertEquals(Program.TextureType.TEXTURE_2D,
+                     Program.TextureType.valueOf("TEXTURE_2D"));
+        assertEquals(Program.TextureType.TEXTURE_CUBE,
+                     Program.TextureType.valueOf("TEXTURE_CUBE"));
+        // Make sure no new enums are added
+        assertEquals(2, Program.TextureType.values().length);
+
+        ProgramFragment.Builder pfb = new ProgramFragment.Builder(mRS);
+        for (Program.TextureType tt : Program.TextureType.values()) {
+            pfb.addTexture(tt);
+        }
+    }
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ProgramRasterTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ProgramRasterTest.java
index bebb8b0..befa926 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ProgramRasterTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ProgramRasterTest.java
@@ -16,8 +16,6 @@
 
 package android.renderscript.cts;
 
-import com.android.cts.stub.R;
-
 import android.renderscript.ProgramRaster;
 import android.renderscript.ProgramRaster.Builder;
 import android.renderscript.ProgramRaster.CullMode;
@@ -31,7 +29,9 @@
             b.setPointSpriteEnabled(pSprite);
             for (CullMode cull : CullMode.values()) {
                 b.setCullMode(cull);
-                b.create();
+                ProgramRaster pr = b.create();
+                assertTrue(pr != null);
+                mRS.bindProgramRaster(pr);
             }
         }
     }
@@ -39,7 +39,14 @@
     public void testPrebuiltProgramRaster() {
         assertTrue(ProgramRaster.CULL_BACK(mRS) != null);
         assertTrue(ProgramRaster.CULL_FRONT(mRS) != null);
+        assertTrue(ProgramRaster.CULL_NONE(mRS) != null);
+    }
+
+    public void testProgramRasterCullMode() {
+        assertEquals(CullMode.BACK, CullMode.valueOf("BACK"));
+        assertEquals(CullMode.FRONT, CullMode.valueOf("FRONT"));
+        assertEquals(CullMode.NONE, CullMode.valueOf("NONE"));
+        // Make sure no new enums are added
+        assertEquals(3, CullMode.values().length);
     }
 }
-
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ProgramStoreTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ProgramStoreTest.java
index 54c5672..b7f5eff 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ProgramStoreTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ProgramStoreTest.java
@@ -16,10 +16,7 @@
 
 package android.renderscript.cts;
 
-import com.android.cts.stub.R;
-
 import android.renderscript.ProgramStore;
-import android.renderscript.ProgramStore.Builder;
 import android.renderscript.ProgramStore.DepthFunc;
 import android.renderscript.ProgramStore.BlendSrcFunc;
 import android.renderscript.ProgramStore.BlendDstFunc;
@@ -37,9 +34,11 @@
                         boolean isA = (a == 1);
                         for (int dither = 0; dither <= 1; dither++) {
                             boolean isDither = (dither == 1);
-                            pb.setDepthMaskEnabled(isDither);
+                            pb.setDitherEnabled(isDither);
                             pb.setColorMaskEnabled(isR, isG, isB, isA);
-                            pb.create();
+                            ProgramStore ps = pb.create();
+                            assertTrue(ps != null);
+                            mRS.bindProgramStore(ps);
                         }
                     }
                 }
@@ -70,6 +69,68 @@
         assertTrue(ProgramStore.BLEND_NONE_DEPTH_NONE(mRS) != null);
         assertTrue(ProgramStore.BLEND_NONE_DEPTH_TEST(mRS) != null);
     }
+
+    public void testProgramStoreBlendDstFunc() {
+        assertEquals(BlendDstFunc.ZERO,
+                     BlendDstFunc.valueOf("ZERO"));
+        assertEquals(BlendDstFunc.ONE,
+                     BlendDstFunc.valueOf("ONE"));
+        assertEquals(BlendDstFunc.SRC_COLOR,
+                     BlendDstFunc.valueOf("SRC_COLOR"));
+        assertEquals(BlendDstFunc.ONE_MINUS_SRC_COLOR,
+                     BlendDstFunc.valueOf("ONE_MINUS_SRC_COLOR"));
+        assertEquals(BlendDstFunc.SRC_ALPHA,
+                     BlendDstFunc.valueOf("SRC_ALPHA"));
+        assertEquals(BlendDstFunc.ONE_MINUS_SRC_ALPHA,
+                     BlendDstFunc.valueOf("ONE_MINUS_SRC_ALPHA"));
+        assertEquals(BlendDstFunc.DST_ALPHA,
+                     BlendDstFunc.valueOf("DST_ALPHA"));
+        assertEquals(BlendDstFunc.ONE_MINUS_DST_ALPHA,
+                     BlendDstFunc.valueOf("ONE_MINUS_DST_ALPHA"));
+        // Make sure no new enums are added
+        assertEquals(8, BlendDstFunc.values().length);
+    }
+
+    public void testProgramStoreBlendSrcFunc() {
+        assertEquals(BlendSrcFunc.ZERO,
+                     BlendSrcFunc.valueOf("ZERO"));
+        assertEquals(BlendSrcFunc.ONE,
+                     BlendSrcFunc.valueOf("ONE"));
+        assertEquals(BlendSrcFunc.DST_COLOR,
+                     BlendSrcFunc.valueOf("DST_COLOR"));
+        assertEquals(BlendSrcFunc.ONE_MINUS_DST_COLOR,
+                     BlendSrcFunc.valueOf("ONE_MINUS_DST_COLOR"));
+        assertEquals(BlendSrcFunc.SRC_ALPHA,
+                     BlendSrcFunc.valueOf("SRC_ALPHA"));
+        assertEquals(BlendSrcFunc.ONE_MINUS_SRC_ALPHA,
+                     BlendSrcFunc.valueOf("ONE_MINUS_SRC_ALPHA"));
+        assertEquals(BlendSrcFunc.DST_ALPHA,
+                     BlendSrcFunc.valueOf("DST_ALPHA"));
+        assertEquals(BlendSrcFunc.ONE_MINUS_DST_ALPHA,
+                     BlendSrcFunc.valueOf("ONE_MINUS_DST_ALPHA"));
+        assertEquals(BlendSrcFunc.SRC_ALPHA_SATURATE,
+                     BlendSrcFunc.valueOf("SRC_ALPHA_SATURATE"));
+        // Make sure no new enums are added
+        assertEquals(9, BlendSrcFunc.values().length);
+    }
+    public void testProgramStoreDepthFunc() {
+        assertEquals(DepthFunc.ALWAYS,
+                     DepthFunc.valueOf("ALWAYS"));
+        assertEquals(DepthFunc.LESS,
+                     DepthFunc.valueOf("LESS"));
+        assertEquals(DepthFunc.LESS_OR_EQUAL,
+                     DepthFunc.valueOf("LESS_OR_EQUAL"));
+        assertEquals(DepthFunc.GREATER,
+                     DepthFunc.valueOf("GREATER"));
+        assertEquals(DepthFunc.GREATER_OR_EQUAL,
+                     DepthFunc.valueOf("GREATER_OR_EQUAL"));
+        assertEquals(DepthFunc.EQUAL,
+                     DepthFunc.valueOf("EQUAL"));
+        assertEquals(DepthFunc.NOT_EQUAL,
+                     DepthFunc.valueOf("NOT_EQUAL"));
+        // Make sure no new enums are added
+        assertEquals(7, DepthFunc.values().length);
+    }
 }
 
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ProgramVertexFixedFunctionTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ProgramVertexFixedFunctionTest.java
new file mode 100644
index 0000000..0adab9a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ProgramVertexFixedFunctionTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.renderscript.cts;
+
+import com.android.cts.stub.R;
+
+import android.renderscript.ProgramVertexFixedFunction;
+import android.renderscript.ProgramVertexFixedFunction.Builder;
+import android.renderscript.ScriptC;
+import android.renderscript.Matrix4f;
+
+public class ProgramVertexFixedFunctionTest extends RSBaseGraphics {
+
+    ScriptC_graphics_runner mScript;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mScript = new ScriptC_graphics_runner(mRS, mRes, R.raw.graphics_runner);
+        mRS.bindRootScript(mScript);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mRS.bindRootScript(null);
+        super.tearDown();
+    }
+
+    public void testConstants() {
+        ProgramVertexFixedFunction.Constants pva;
+        for (int isM = 0; isM <= 1; isM++) {
+            for (int isP = 0; isP <= 1; isP++) {
+                for (int isT = 0; isT <= 1; isT++) {
+                    pva = new ProgramVertexFixedFunction.Constants(mRS);
+                    if (isM == 1) {
+                        pva.setModelview(new Matrix4f());
+                    }
+                    if (isP == 1) {
+                        pva.setProjection(new Matrix4f());
+                    }
+                    if (isT == 1) {
+                        pva.setTexture(new Matrix4f());
+                    }
+                    pva.destroy();
+                }
+            }
+        }
+    }
+
+    void testProgramVertexFixedFunctionBuilder(boolean testBind) {
+        ProgramVertexFixedFunction.Constants pva;
+        pva = new ProgramVertexFixedFunction.Constants(mRS);
+
+        ProgramVertexFixedFunction.Builder b;
+        b = new ProgramVertexFixedFunction.Builder(mRS);
+        b.setTextureMatrixEnable(false);
+        ProgramVertexFixedFunction pv = b.create();
+        assertTrue(pv != null);
+        pv.bindConstants(pva);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+        }
+        pv.destroy();
+        b.setTextureMatrixEnable(true);
+        pv = b.create();
+        assertTrue(pv != null);
+        pv.bindConstants(pva);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+        }
+        pv.destroy();
+    }
+
+    public void testProgramVertexFixedFunctionBuilder() {
+        testProgramVertexFixedFunctionBuilder(false);
+        testProgramVertexFixedFunctionBuilder(true);
+    }
+
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ProgramVertexTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ProgramVertexTest.java
new file mode 100644
index 0000000..0a5c60e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ProgramVertexTest.java
@@ -0,0 +1,243 @@
+/*
+ * 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.renderscript.cts;
+
+import com.android.cts.stub.R;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Program;
+import android.renderscript.ProgramVertex;
+
+public class ProgramVertexTest extends RSBaseGraphics {
+
+    ScriptC_graphics_runner mScript;
+    Element mAttrPosElem;
+    Element mAttrNormTexElem;
+    Element mAttrPosNormTexElem;
+    Element mAttrExtra;
+
+    Allocation mConstMatrix;
+    Allocation mConstComplex;
+    Allocation mConstExtra;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // Build elements for shader inputs
+        Element.Builder eb = new Element.Builder(mRS);
+        eb.add(Element.F32_4(mRS), "position");
+        mAttrPosElem = eb.create();
+
+        eb = new Element.Builder(mRS);
+        eb.add(Element.F32_3(mRS), "normal");
+        eb.add(Element.F32_2(mRS), "texture0");
+        mAttrNormTexElem = eb.create();
+
+        eb = new Element.Builder(mRS);
+        eb.add(Element.F32_4(mRS), "position");
+        eb.add(Element.F32_3(mRS), "normal");
+        eb.add(Element.F32_2(mRS), "texture0");
+        mAttrPosNormTexElem = eb.create();
+
+        eb.add(Element.F32(mRS), "extra1");
+        eb.add(Element.F32_2(mRS), "extra2");
+        eb.add(Element.F32_3(mRS), "extra3");
+        eb.add(Element.F32_4(mRS), "extra4");
+        mAttrExtra = eb.create();
+
+        ScriptField_ConstMatrix c1 = new ScriptField_ConstMatrix(mRS, 1,
+                                                                 Allocation.USAGE_SCRIPT |
+                                                                 Allocation.USAGE_GRAPHICS_CONSTANTS);
+        c1.set(new ScriptField_ConstMatrix.Item(), 0, true);
+        mConstMatrix = c1.getAllocation();
+
+        ScriptField_ConstComplex c2 = new ScriptField_ConstComplex(mRS, 1,
+                                                                   Allocation.USAGE_SCRIPT |
+                                                                   Allocation.USAGE_GRAPHICS_CONSTANTS);
+        c2.set(new ScriptField_ConstComplex.Item(), 0, true);
+        mConstComplex = c2.getAllocation();
+
+        ScriptField_ConstExtra c3 = new ScriptField_ConstExtra(mRS, 1,
+                                                               Allocation.USAGE_SCRIPT |
+                                                               Allocation.USAGE_GRAPHICS_CONSTANTS);
+        c3.set(new ScriptField_ConstExtra.Item(), 0, true);
+        mConstExtra = c3.getAllocation();
+
+        mScript = new ScriptC_graphics_runner(mRS, mRes, R.raw.graphics_runner);
+        mRS.bindRootScript(mScript);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mRS.bindRootScript(null);
+        super.tearDown();
+    }
+
+    ProgramVertex buildShader(Element[] input, Allocation[] constInput, String shader) {
+        ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS);
+        Program.BaseProgramBuilder bpb = pvb;
+        if (input != null) {
+            for (int i = 0; i < input.length; i++) {
+                pvb.addInput(input[i]);
+            }
+        }
+        if (constInput != null) {
+            for (int i = 0; i < constInput.length; i++) {
+                // Add constants through the base builder class to
+                // tick cts test coverage (doesn't register through subclass)
+                bpb.addConstant(constInput[i].getType());
+                bpb.getCurrentConstantIndex();
+            }
+        }
+
+        bpb.setShader(shader);
+        ProgramVertex pv = pvb.create();
+        if (constInput != null) {
+            for (int i = 0; i < constInput.length; i++) {
+                pv.bindConstants(constInput[i], i);
+                // Go through the base class code as well
+                Program p = pv;
+                p.bindConstants(constInput[i], i);
+            }
+        }
+        return pv;
+    }
+
+    void testProgramVertexBuilderHelper(boolean testBind) {
+        String simpleAttr = "void main() {\n"+
+                            "  gl_Position = ATTRIB_position;\n"+
+                            "}";
+
+        String multiAttr = "void main() {\n"+
+                           "  vec4 temp = ATTRIB_position;\n"+
+                           "  temp.xyz += ATTRIB_normal;\n"+
+                           "  temp.xy += ATTRIB_texture0;\n"+
+                           "  gl_Position = temp;\n"+
+                           "}";
+
+        String multiAttr2 = "void main() {\n"+
+                            "  vec4 temp = ATTRIB_position;\n"+
+                            "  temp.xyz += ATTRIB_normal;\n"+
+                            "  temp.xy += ATTRIB_texture0;\n"+
+                            "  temp += ATTRIB_extra4;\n"+
+                            "  temp.xyz += ATTRIB_extra3;\n "+
+                            "  temp.xy += ATTRIB_extra2;\n"+
+                            "  temp.x += ATTRIB_extra1;\n"+
+                            "  gl_Position = temp;\n"+
+                            "}";
+
+        String simpleAttrSimpleUni = "void main() {\n"+
+                                     "  gl_Position = UNI_MVP * ATTRIB_position;\n"+
+                                     "}";
+
+        String multiAttrMultiUni = "void main() {\n"+
+                                   "  vec4 temp = UNI_MVP * ATTRIB_position;\n"+
+                                   "  temp = UNI_EXTRA * temp;\n"+
+                                   "  temp.xyz += ATTRIB_normal;\n"+
+                                   "  temp.xy += ATTRIB_texture0;\n"+
+                                   "  temp += UNI_extra4;\n"+
+                                   "  temp.xyz += UNI_extra3;\n "+
+                                   "  temp.xy += UNI_extra2;\n"+
+                                   "  temp.x += UNI_extra1;\n"+
+                                   "  gl_Position = temp;\n"+
+                                   "}";
+
+        // Create a series of shaders that do nothing useful
+        // but exercise creation pipeline
+        Element[] inputs = new Element[1];
+        inputs[0] = mAttrPosElem;
+        ProgramVertex pv = buildShader(inputs, null, simpleAttr);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+            mRS.bindProgramVertex(pv);
+        }
+
+        inputs[0] = mAttrPosNormTexElem;
+        pv = buildShader(inputs, null, multiAttr);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+            mRS.bindProgramVertex(pv);
+        }
+
+        inputs[0] = mAttrExtra;
+        pv = buildShader(inputs, null, multiAttr2);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+            mRS.bindProgramVertex(pv);
+        }
+
+        // Now with constant inputs
+        Allocation[] constInput = new Allocation[1];
+        inputs[0] = mAttrPosElem;
+        constInput[0] = mConstMatrix;
+        pv = buildShader(inputs, constInput, simpleAttrSimpleUni);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+            mRS.bindProgramVertex(pv);
+        }
+
+        inputs[0] = mAttrPosNormTexElem;
+        constInput[0] = mConstComplex;
+        pv = buildShader(inputs, constInput, multiAttrMultiUni);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+            mRS.bindProgramVertex(pv);
+        }
+
+        // Now with multiple input and const structs
+        constInput = new Allocation[2];
+        constInput[0] = mConstMatrix;
+        constInput[1] = mConstExtra;
+        inputs[0] = mAttrPosNormTexElem;
+        pv = buildShader(inputs, constInput, multiAttrMultiUni);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+            mRS.bindProgramVertex(pv);
+        }
+
+        inputs = new Element[2];
+        inputs[0] = mAttrPosElem;
+        inputs[1] = mAttrNormTexElem;
+        pv = buildShader(inputs, null, multiAttr);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+            mRS.bindProgramVertex(pv);
+        }
+
+        constInput[0] = mConstMatrix;
+        constInput[1] = mConstExtra;
+        inputs[0] = mAttrPosElem;
+        inputs[1] = mAttrNormTexElem;
+        pv = buildShader(inputs, constInput, multiAttrMultiUni);
+        if (testBind) {
+            mScript.invoke_testProgramVertex(pv);
+            mRS.bindProgramVertex(pv);
+        }
+    }
+
+    public void testProgramVertexBuilder() {
+        testProgramVertexBuilderHelper(false);
+    }
+
+    public void testProgramVertexCreation() {
+        testProgramVertexBuilderHelper(true);
+    }
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java
index 10aa8e6..56838e1 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java
@@ -20,7 +20,6 @@
 import android.content.res.Resources;
 import android.renderscript.RenderScript.RSMessageHandler;
 import android.test.AndroidTestCase;
-import com.android.cts.stub.R;
 
 /**
  * Base RenderScript test class. This class provides a message handler and a
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
index 84616ca..3278113 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
@@ -16,12 +16,7 @@
 
 package android.renderscript.cts;
 
-import android.content.Context;
-import android.content.res.Resources;
 import android.renderscript.RenderScript;
-import android.renderscript.RenderScript.RSMessageHandler;
-import android.test.AndroidTestCase;
-import com.android.cts.stub.R;
 
 /**
  * Base RenderScript test class. This class provides a message handler and a
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseGraphics.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseGraphics.java
index 83a2744..986a50d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseGraphics.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseGraphics.java
@@ -16,14 +16,8 @@
 
 package android.renderscript.cts;
 
-import android.content.Context;
-import android.content.res.Resources;
-import android.renderscript.RenderScript;
-import android.renderscript.RenderScript.RSMessageHandler;
 import android.renderscript.RenderScriptGL;
 import android.renderscript.RenderScriptGL.SurfaceConfig;
-import android.test.AndroidTestCase;
-import com.android.cts.stub.R;
 
 /**
  * Base RenderScript test class. This class provides a message handler and a
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSSurfaceViewTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RSSurfaceViewTest.java
new file mode 100644
index 0000000..9cf8f65
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSSurfaceViewTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.renderscript.cts;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScriptGL;
+import android.renderscript.RenderScriptGL.SurfaceConfig;
+import android.util.AttributeSet;
+
+public class RSSurfaceViewTest extends RSBaseGraphics {
+
+    public void testCreation() {
+        RSSurfaceView view = new RSSurfaceView(mCtx);
+        view = new RSSurfaceView(mCtx, null);
+    }
+
+    public void testCreateRenderScriptGL() {
+        RSSurfaceView view = new RSSurfaceView(mCtx);
+        RenderScriptGL rs = view.createRenderScriptGL(new SurfaceConfig());
+        assertTrue(rs != null);
+    }
+
+    public void testGetSetRenderScriptGL() {
+        RSSurfaceView view = new RSSurfaceView(mCtx);
+        RenderScriptGL rs = view.createRenderScriptGL(new SurfaceConfig());
+        assertTrue(rs != null);
+        assertEquals(view.getRenderScriptGL(), rs);
+
+        view = new RSSurfaceView(mCtx);
+        view.setRenderScriptGL(mRS);
+        assertEquals(view.getRenderScriptGL(), mRS);
+    }
+
+    public void testDestroyRenderScriptGL() {
+        RSSurfaceView view = new RSSurfaceView(mCtx);
+        RenderScriptGL rs = view.createRenderScriptGL(new SurfaceConfig());
+        assertTrue(rs != null);
+        view.destroyRenderScriptGL();
+        assertTrue(view.getRenderScriptGL() == null);
+    }
+
+    public void testPauseResume() {
+        RSSurfaceView view = new RSSurfaceView(mCtx);
+        view.pause();
+        view.resume();
+
+        view.setRenderScriptGL(mRS);
+        view.pause();
+        view.resume();
+    }
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RenderScriptTest.java b/tests/tests/renderscript/src/android/renderscript/cts/RenderScriptTest.java
index e2d7968..9e61526 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RenderScriptTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RenderScriptTest.java
@@ -59,4 +59,34 @@
         mRS.destroy();
     }
 
+    /**
+     * Verify Priority enum properties.
+     */
+    public void testPriority() {
+        assertEquals(RenderScript.Priority.LOW,
+            RenderScript.Priority.valueOf("LOW"));
+        assertEquals(RenderScript.Priority.NORMAL,
+            RenderScript.Priority.valueOf("NORMAL"));
+        assertEquals(2, RenderScript.Priority.values().length);
+    }
+
+    /**
+     * Create a base RSMessageHandler object and run() it.
+     * Note that most developers will subclass RSMessageHandler and use
+     * their own non-empty implementation.
+     */
+    public void testRSMessageHandler() {
+        RenderScript.RSMessageHandler mMH = new RenderScript.RSMessageHandler();
+        mMH.run();
+    }
+
+    /**
+     * Create a base RSErrorHandler object and run() it.
+     * Note that most developers will subclass RSErrorHandler and use
+     * their own non-empty implementation.
+     */
+    public void testRSErrorHandler() {
+        RenderScript.RSErrorHandler mEH = new RenderScript.RSErrorHandler();
+        mEH.run();
+    }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SamplerTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SamplerTest.java
index 7f2b052..35e813e 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/SamplerTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/SamplerTest.java
@@ -16,10 +16,7 @@
 
 package android.renderscript.cts;
 
-import com.android.cts.stub.R;
-
 import android.renderscript.Sampler;
-import android.renderscript.Sampler.Builder;
 import android.renderscript.Sampler.Value;
 
 public class SamplerTest extends RSBaseGraphics {
@@ -119,6 +116,18 @@
         assertTrue(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS) != null);
         assertTrue(Sampler.WRAP_NEAREST(mRS) != null);
     }
+
+    public void testSamplerValue() {
+        assertEquals(Value.NEAREST, Value.valueOf("NEAREST"));
+        assertEquals(Value.LINEAR, Value.valueOf("LINEAR"));
+        assertEquals(Value.LINEAR_MIP_LINEAR, Value.valueOf("LINEAR_MIP_LINEAR"));
+        assertEquals(Value.LINEAR_MIP_NEAREST, Value.valueOf("LINEAR_MIP_NEAREST"));
+        assertEquals(Value.WRAP, Value.valueOf("WRAP"));
+        assertEquals(Value.CLAMP, Value.valueOf("CLAMP"));
+
+        // Make sure no new enums are added
+        assertEquals(6, Value.values().length);
+    }
 }
 
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SurfaceConfigTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SurfaceConfigTest.java
new file mode 100644
index 0000000..94d784e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/SurfaceConfigTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.renderscript.cts;
+import android.test.AndroidTestCase;
+
+import android.renderscript.RSIllegalArgumentException;
+import android.renderscript.RenderScriptGL.SurfaceConfig;
+
+public class SurfaceConfigTest extends AndroidTestCase {
+
+    public void testSimpleCreate() {
+        SurfaceConfig sc = new SurfaceConfig();
+    }
+
+    public void testSetColor() {
+        SurfaceConfig sc = new SurfaceConfig();
+        try {
+            sc.setColor(-1, 8);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        try {
+            sc.setColor(9, 8);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        try {
+            sc.setColor(5, -1);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        sc.setColor(5, 8);
+        sc = new SurfaceConfig();
+        sc.setColor(8, 8);
+    }
+
+    public void testSetAlpha() {
+        SurfaceConfig sc = new SurfaceConfig();
+        try {
+            sc.setAlpha(-1, 8);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        try {
+            sc.setAlpha(9, 8);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        try {
+            sc.setAlpha(0, -1);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        sc.setAlpha(0, 8);
+        sc = new SurfaceConfig();
+        sc.setAlpha(8, 8);
+    }
+
+    public void testSetDepth() {
+        SurfaceConfig sc = new SurfaceConfig();
+        try {
+            sc.setDepth(-1, 8);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        try {
+            sc.setDepth(45, 8);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        try {
+            sc.setDepth(0, -1);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        sc.setDepth(0, 16);
+        sc = new SurfaceConfig();
+        sc.setDepth(16, 24);
+        sc = new SurfaceConfig();
+        sc.setDepth(24, 24);
+    }
+
+    public void testSetSamples() {
+        SurfaceConfig sc = new SurfaceConfig();
+        try {
+            sc.setSamples(-1, 8, 1.0f);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        try {
+            sc.setSamples(45, 8, 1.0f);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        try {
+            sc.setSamples(1, -1, 1.0f);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        try {
+            sc.setSamples(1, 1, -1.0f);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        try {
+            sc.setSamples(1, 1, 10.0f);
+            fail("should throw RSIllegalArgumentException.");
+        } catch (RSIllegalArgumentException e) {
+        }
+        sc = new SurfaceConfig();
+        sc.setSamples(1, 4, 1.0f);
+        sc = new SurfaceConfig();
+        sc.setSamples(4, 32, 1.0f);
+        sc = new SurfaceConfig();
+        sc.setSamples(4, 64, 0.5f);
+    }
+
+    public void testCopyConstructor() {
+        SurfaceConfig sc = new SurfaceConfig();
+        sc.setAlpha(1, 7);
+        sc.setColor(5, 8);
+        sc.setDepth(0, 16);
+        sc.setSamples(1, 4, 0.71f);
+        SurfaceConfig sc2 = new SurfaceConfig(sc);
+    }
+
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TypeTest.java b/tests/tests/renderscript/src/android/renderscript/cts/TypeTest.java
index 82c7a79..928abaf 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/TypeTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TypeTest.java
@@ -16,13 +16,8 @@
 
 package android.renderscript.cts;
 
-import com.android.cts.stub.R;
-
 import android.renderscript.Element;
-import android.renderscript.Element.DataType;
-import android.renderscript.Element.DataKind;
 import android.renderscript.Type;
-import android.renderscript.Type.Builder;
 
 public class TypeTest extends RSBaseCompute {
 
@@ -127,6 +122,59 @@
         expectedCount = 7*3 + 3*1 + 1;
         assertTrue(t.getCount() == expectedCount);
     }
+
+    public void testGetElement() {
+        Type.Builder b = new Type.Builder(mRS, Element.F32(mRS));
+        b.setX(1);
+        assertTrue(b.create().getElement() == Element.F32(mRS));
+    }
+
+    public void testGetX() {
+        Type.Builder b = new Type.Builder(mRS, Element.F32(mRS));
+        b.setX(3);
+        assertTrue(b.create().getX() == 3);
+    }
+
+    public void testGetY() {
+        Type.Builder b = new Type.Builder(mRS, Element.F32(mRS));
+        b.setX(3).setY(4);
+        Type t = b.create();
+        assertTrue(t.getX() == 3);
+        assertTrue(t.getY() == 4);
+    }
+
+    public void testGetZ() {
+        Type.Builder b = new Type.Builder(mRS, Element.F32(mRS));
+        b.setX(3).setY(4);
+        assertTrue(b.create().getZ() == 0);
+    }
+
+    public void testHasFaces() {
+        Type.Builder b = new Type.Builder(mRS, Element.F32(mRS));
+        b.setX(4).setY(4).setFaces(true);
+        assertTrue(b.create().hasFaces());
+        b.setFaces(false);
+        assertFalse(b.create().hasFaces());
+    }
+
+    public void testGetMipmaps() {
+        Type.Builder b = new Type.Builder(mRS, Element.F32(mRS));
+        b.setX(4).setY(4).setMipmaps(true);
+        assertTrue(b.create().hasMipmaps());
+        b.setMipmaps(false);
+        assertFalse(b.create().hasMipmaps());
+    }
+
+    public void testTypeCubemapFace() {
+        assertEquals(Type.CubemapFace.NEGATIVE_X, Type.CubemapFace.valueOf("NEGATIVE_X"));
+        assertEquals(Type.CubemapFace.NEGATIVE_Y, Type.CubemapFace.valueOf("NEGATIVE_Y"));
+        assertEquals(Type.CubemapFace.NEGATIVE_Z, Type.CubemapFace.valueOf("NEGATIVE_Z"));
+        assertEquals(Type.CubemapFace.POSITVE_X, Type.CubemapFace.valueOf("POSITVE_X"));
+        assertEquals(Type.CubemapFace.POSITVE_Y, Type.CubemapFace.valueOf("POSITVE_Y"));
+        assertEquals(Type.CubemapFace.POSITVE_Z, Type.CubemapFace.valueOf("POSITVE_Z"));
+        // Make sure no new enums are added
+        assertEquals(6, Type.CubemapFace.values().length);
+    }
 }
 
 
diff --git a/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
index a92f323..76f28cc 100644
--- a/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
@@ -70,7 +70,6 @@
         mArrowKeyMovementMethod = new ArrowKeyMovementMethod();
 
         initTextViewWithNullLayout();
-        mEditable = (Editable) mTextView.getText();
 
         getInstrumentation().runOnMainSync(new Runnable() {
             public void run() {
@@ -197,8 +196,6 @@
             + "document about the behaviour of this method.")
     public void testOnTakeFoucusWithNullLayout() {
         initTextViewWithNullLayout();
-        mEditable = (Editable) mTextView.getText();
-
         assertSelectEndOfContent();
     }
 
@@ -214,7 +211,6 @@
             + "Spannable, int)} when the params view or text is null")
     public void testOnTakeFocusWithNullParameters() {
         initTextViewWithNullLayout();
-        mEditable = (Editable) mTextView.getText();
         try {
             mArrowKeyMovementMethod.onTakeFocus(null, mEditable, View.FOCUS_DOWN);
             fail("The method did not throw NullPointerException when param textView is null.");
@@ -580,8 +576,6 @@
             + "Spannable, int, KeyEvent)} when the view does not get layout")
     public void testOnKeyDownWithNullLayout() {
         initTextViewWithNullLayout();
-        mEditable = (Editable) mTextView.getText();
-
         try {
             mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable, KeyEvent.KEYCODE_DPAD_RIGHT,
                     null);
@@ -698,7 +692,6 @@
             + "Spannable, MotionEvent)} when the view does not get layout")
     public void testOnTouchEventWithNullLayout() {
         initTextViewWithNullLayout();
-        mEditable = (Editable) mTextView.getText();
         mTextView.setFocusable(true);
         mTextView.requestFocus();
         assertTrue(mTextView.isFocused());
@@ -738,7 +731,6 @@
             + "Spannable, MotionEvent)} when the params view, buffer or event is null")
     public void testOnTouchEventWithNullParameters() {
         initTextViewWithNullLayout();
-        mEditable = (Editable) mTextView.getText();
         try {
             mArrowKeyMovementMethod.onTouchEvent(null, mEditable,
                     MotionEvent.obtain(0, 0, 0, 1, 1, 0));
@@ -812,7 +804,6 @@
                 MotionEvent.obtain(0, 0, 0, 1, 1, 0)));
 
         initTextViewWithNullLayout();
-        mEditable = (Editable) mTextView.getText();
 
         assertFalse(mArrowKeyMovementMethod.onTrackballEvent(mTextView, mEditable,
                 MotionEvent.obtain(0, 0, 0, 1, 1, 0)));
@@ -846,10 +837,387 @@
         assertFalse(method.onKeyUp(view, spannable, KeyEvent.KEYCODE_0, null));
     }
 
+    private static final String TEXT_WORDS =
+            "Lorem ipsum; dolor sit \u00e4met, conse\u0ca0_\u0ca0ctetur?       Adipiscing"
+            + ".elit.integ\u00e9r. Etiam    tristique\ntortor nec   ?:?    \n\n"
+            + "lectus porta consequ\u00e4t...  LOReM iPSuM";
+
+    @UiThreadTest
+    public void testFollowingWordStartToEnd() {
+
+        // NOTE: there seems to be much variation in how word boundaries are
+        // navigated; the behaviors asserted here were derived from Google
+        // Chrome 10.0.648.133 beta.
+
+        initTextViewWithNullLayout(TEXT_WORDS);
+
+        // |Lorem ipsum; dolor sit $met,
+        Selection.setSelection(mEditable, 0);
+        assertSelection(0);
+
+        // Lorem| ipsum; dolor sit $met,
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(5);
+
+        // Lorem ipsum|; dolor sit $met,
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(11);
+
+        // Lorem ipsum; dolor| sit $met,
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(18);
+
+        // Lorem ipsum; dolor sit| $met,
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(22);
+
+        // $met|, conse$_$ctetur$       Adipiscing.elit.integ$r.
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(27);
+
+        // $met, conse$_$ctetur|$       Adipiscing.elit.integ$r.
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(43);
+
+        // TODO: enable these two additional word breaks when implemented
+//        // $met, conse$_$ctetur$       Adipiscing|.elit.integ$r.
+//        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+//        assertSelection(61);
+//
+//        // $met, conse$_$ctetur$       Adipiscing.elit|.integ$r.
+//        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+//        assertSelection(66);
+
+        // $met, conse$_$ctetur$       Adipiscing.elit.integ$r|.
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(74);
+
+        // integ$r. Etiam|    tristique$tortor nec   ?:?    $$lectus porta
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(81);
+
+        // integ$r. Etiam    tristique|$tortor nec   ?:?    $$lectus porta
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(94);
+
+        // integ$r. Etiam    tristique$tortor| nec   ?:?    $$lectus porta
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(101);
+
+        // integ$r. Etiam    tristique$tortor nec|   ?:?    $$lectus porta
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(105);
+
+        // integ$r. Etiam    tristique$tortor nec   ?:?    $$lectus| porta
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(123);
+
+        // $$lectus porta| consequ$t...  LOReM iPSuM
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(129);
+
+        // $$lectus porta consequ$t|...  LOReM iPSuM
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(139);
+
+        // $$lectus porta consequ$t...  LOReM| iPSuM
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(149);
+
+        // $$lectus porta consequ$t...  LOReM iPSuM|
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(155);
+
+        // keep trying to push beyond end, which should fail
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(155);
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(155);
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(155);
+
+    }
+
+    @UiThreadTest
+    public void testPrecedingWordEndToStart() {
+
+        // NOTE: there seems to be much variation in how word boundaries are
+        // navigated; the behaviors asserted here were derived from Google
+        // Chrome 10.0.648.133 beta.
+
+        initTextViewWithNullLayout(TEXT_WORDS);
+
+        // $$lectus porta consequ$t...  LOReM iPSuM|
+        Selection.setSelection(mEditable, mEditable.length());
+        assertSelection(155);
+
+        // $$lectus porta consequ$t...  LOReM |iPSuM
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(150);
+
+        // $$lectus porta consequ$t...  |LOReM iPSuM
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(144);
+
+        // $$lectus porta |consequ$t...  LOReM iPSuM
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(130);
+
+        // $$lectus |porta consequ$t...  LOReM iPSuM
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(124);
+
+        // integ$r. Etiam    tristique$tortor nec   ?:?    $$|lectus
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(117);
+
+        // integ$r. Etiam    tristique$tortor |nec   ?:?    $$lectus
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(102);
+
+        // integ$r. Etiam    tristique$|tortor nec   ?:?    $$lectus
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(95);
+
+        // integ$r. Etiam    |tristique$tortor nec   ?:?    $$lectus
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(85);
+
+        // integ$r. |Etiam    tristique$tortor nec   ?:?    $$lectus
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(76);
+
+        // TODO: enable these two additional word breaks when implemented
+//        // dolor sit $met, conse$_$ctetur$       Adipiscing.elit.|integ$r.
+//        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+//        assertSelection(67);
+//
+//        // dolor sit $met, conse$_$ctetur$       Adipiscing.|elit.integ$r.
+//        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+//        assertSelection(62);
+
+        // dolor sit $met, conse$_$ctetur$       |Adipiscing.elit.integ$r.
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(51);
+
+        // dolor sit $met, |conse$_$ctetur$       Adipiscing.elit.integ$r.
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(29);
+
+        // dolor sit |$met, conse$_$ctetur$       Adipiscing.elit.integ$r.
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(23);
+
+        // Lorem ipsum; dolor |sit $met
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(19);
+
+        // Lorem ipsum; |dolor sit $met
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(13);
+
+        // Lorem |ipsum; dolor sit $met
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(6);
+
+        // |Lorem ipsum; dolor sit $met
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(0);
+
+        // keep trying to push before beginning, which should fail
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(0);
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(0);
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(0);
+
+    }
+
+    private static final String TEXT_WORDS_WITH_NUMBERS =
+            "Lorem ipsum123,456.90   dolor sit.. 4-0.0=2 ADipiscing4";
+
+    @UiThreadTest
+    public void testFollowingWordStartToEndWithNumbers() {
+
+        initTextViewWithNullLayout(TEXT_WORDS_WITH_NUMBERS);
+
+        // |Lorem ipsum123,456.90   dolor sit.. 4-0.0=2 ADipiscing4
+        Selection.setSelection(mEditable, 0);
+        assertSelection(0);
+
+        // Lorem| ipsum123,456.90   dolor sit.. 4-0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(5);
+
+        // Lorem ipsum123,456.90|   dolor sit.. 4-0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(21);
+
+        // Lorem ipsum123,456.90   dolor| sit.. 4-0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(29);
+
+        // Lorem ipsum123,456.90   dolor sit|.. 4-0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(33);
+
+        // Lorem ipsum123,456.90   dolor sit.. 4|-0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(37);
+
+        // Lorem ipsum123,456.90   dolor sit.. 4-0.0|=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(41);
+
+        // Lorem ipsum123,456.90   dolor sit.. 4-0.0=2| ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(43);
+
+        // Lorem ipsum123,456.90   dolor sit.. 4-0.0=2 ADipiscing4|
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(55);
+
+        // keep trying to push beyond end, which should fail
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(55);
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(55);
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(55);
+
+    }
+
+    @UiThreadTest
+    public void testFollowingWordEndToStartWithNumbers() {
+
+        initTextViewWithNullLayout(TEXT_WORDS_WITH_NUMBERS);
+
+        // Lorem ipsum123,456.90   dolor sit.. 4-0.0=2 ADipiscing4|
+        Selection.setSelection(mEditable, mEditable.length());
+        assertSelection(55);
+
+        // Lorem ipsum123,456.90   dolor sit.. 4-0.0=2 |ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(44);
+
+        // Lorem ipsum123,456.90   dolor sit.. 4-0.0=|2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(42);
+
+        // Lorem ipsum123,456.90   dolor sit.. 4-|0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(38);
+
+        // Lorem ipsum123,456.90   dolor sit.. |4-0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(36);
+
+        // Lorem ipsum123,456.90   dolor |sit.. 4-0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(30);
+
+        // Lorem ipsum123,456.90   |dolor sit.. 4-0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(24);
+
+        // Lorem |ipsum123,456.90   dolor sit.. 4-0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(6);
+
+        // |Lorem ipsum123,456.90   dolor sit.. 4-0.0=2 ADipiscing4
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(0);
+
+        // keep trying to push before beginning, which should fail
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(0);
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(0);
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(0);
+
+    }
+
+    private static final String TEXT_WORDS_WITH_1CHAR_FINAL_WORD = "abc d";
+
+    @UiThreadTest
+    public void testFollowingWordStartToEndWithOneCharFinalWord() {
+
+        initTextViewWithNullLayout(TEXT_WORDS_WITH_1CHAR_FINAL_WORD);
+
+        // |abc d
+        Selection.setSelection(mEditable, 0);
+        assertSelection(0);
+
+        // abc| d
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(3);
+
+        // abc d|
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+        assertSelection(mEditable.length());
+
+    }
+
+    @UiThreadTest
+    public void testFollowingWordEndToStartWithOneCharFinalWord() {
+
+        initTextViewWithNullLayout(TEXT_WORDS_WITH_1CHAR_FINAL_WORD);
+
+        // abc d|
+        Selection.setSelection(mEditable, mEditable.length());
+        assertSelection(5);
+
+        // abc |d
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(4);
+
+        // |abc d
+        assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+        assertSelection(0);
+
+    }
+
+    @UiThreadTest
+    public void testMovementFromMiddleOfWord() {
+
+        initTextViewWithNullLayout("before word after");
+        checkMoveFromInsideWord(7, 10);
+
+        // Surrogate characters are not (yet) correctly supported. TODO
+        //final String ANGRY_FACE_EMOJI = "\uDBB8\uDF20";
+        //initTextViewWithNullLayout("before " + ANGRY_FACE_EMOJI + " after");
+        //checkMoveFromInsideWord(7, 9);
+
+    }
+
+    private void checkMoveFromInsideWord(int wordStart, int wordEnd) {
+
+        // Check following always goes at the end of the word
+        for (int offset = wordStart; offset != wordEnd + 1; offset++) {
+            Selection.setSelection(mEditable, offset);
+            assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_RIGHT));
+            assertSelection(wordEnd + 1);
+        }
+
+        // Check preceding always goes at the beginning of the word
+        for (int offset = wordEnd + 1; offset != wordStart; offset--) {
+            Selection.setSelection(mEditable, offset);
+            assertTrue(pressCtrlChord(KeyEvent.KEYCODE_DPAD_LEFT));
+            assertSelection(wordStart);
+        }
+    }
+
     private void initTextViewWithNullLayout() {
+        initTextViewWithNullLayout(THREE_LINES_TEXT);
+    }
+
+    private void initTextViewWithNullLayout(CharSequence text) {
         mTextView = new TextView(getActivity());
-        mTextView.setText(THREE_LINES_TEXT, BufferType.EDITABLE);
+        mTextView.setText(text, BufferType.EDITABLE);
         assertNull(mTextView.getLayout());
+        mEditable = (Editable) mTextView.getText();
     }
 
     private void pressMetaKey(int metakey, int expectedState) {
@@ -873,13 +1241,38 @@
         pressMetaKey(KeyEvent.KEYCODE_ALT_LEFT, MetaKeyKeyListener.META_ALT_ON);
     }
 
-    private void assertSelection(int position) {
-        assertSelection(position, position);
+    private boolean pressCtrlChord(int keyCode) {
+        final long now = System.currentTimeMillis();
+        final KeyEvent keyEvent = new KeyEvent(
+                now, now, KeyEvent.ACTION_DOWN, keyCode, 0, KeyEvent.META_CTRL_LEFT_ON);
+        return mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable, keyCode, keyEvent);
     }
 
-    private void assertSelection(int start, int end) {
-        assertEquals(start, Selection.getSelectionStart(mEditable));
-        assertEquals(end, Selection.getSelectionEnd(mEditable));
+    private void assertSelection(int expectedPosition) {
+        assertSelection(expectedPosition, expectedPosition);
+    }
+
+    private void assertSelection(int expectedStart, int expectedEnd) {
+        final int actualStart = Selection.getSelectionStart(mEditable);
+        final int actualEnd = Selection.getSelectionEnd(mEditable);
+
+        assertCharSequenceIndexEquals(mEditable, expectedStart, actualStart);
+        assertCharSequenceIndexEquals(mEditable, expectedEnd, actualEnd);
+    }
+
+    private static void assertCharSequenceIndexEquals(CharSequence text, int expected, int actual) {
+        final String message = "expected <" + getCursorSnippet(text, expected) + "> but was <"
+                + getCursorSnippet(text, actual) + ">";
+        assertEquals(message, expected, actual);
+    }
+
+    private static String getCursorSnippet(CharSequence text, int index) {
+        if (index >= 0 && index < text.length()) {
+            return text.subSequence(Math.max(0, index - 5), index) + "|"
+                    + text.subSequence(index, Math.min(text.length() - 1, index + 5));
+        } else {
+            return null;
+        }
     }
 
     private void assertSelectEndOfContent() {
diff --git a/tests/tests/view/src/android/view/cts/MotionEventTest.java b/tests/tests/view/src/android/view/cts/MotionEventTest.java
index f8a14e6..909ec92 100644
--- a/tests/tests/view/src/android/view/cts/MotionEventTest.java
+++ b/tests/tests/view/src/android/view/cts/MotionEventTest.java
@@ -599,4 +599,71 @@
             android.util.Log.i("TEST", msg.toString());
         }
     }
+
+    public void testPointerCoordsDefaultConstructor() {
+        PointerCoords coords = new PointerCoords();
+
+        assertEquals(0f, coords.x);
+        assertEquals(0f, coords.y);
+        assertEquals(0f, coords.pressure);
+        assertEquals(0f, coords.size);
+        assertEquals(0f, coords.touchMajor);
+        assertEquals(0f, coords.touchMinor);
+        assertEquals(0f, coords.toolMajor);
+        assertEquals(0f, coords.toolMinor);
+        assertEquals(0f, coords.orientation);
+    }
+
+    public void testPointerCoordsCopyConstructor() {
+        PointerCoords coords = new PointerCoords();
+        coords.x = 1;
+        coords.y = 2;
+        coords.pressure = 3;
+        coords.size = 4;
+        coords.touchMajor = 5;
+        coords.touchMinor = 6;
+        coords.toolMajor = 7;
+        coords.toolMinor = 8;
+        coords.orientation = 9;
+        coords.setAxisValue(MotionEvent.AXIS_GENERIC_1, 10);
+
+        PointerCoords copy = new PointerCoords(coords);
+        assertEquals(1f, copy.x);
+        assertEquals(2f, copy.y);
+        assertEquals(3f, copy.pressure);
+        assertEquals(4f, copy.size);
+        assertEquals(5f, copy.touchMajor);
+        assertEquals(6f, copy.touchMinor);
+        assertEquals(7f, copy.toolMajor);
+        assertEquals(8f, copy.toolMinor);
+        assertEquals(9f, copy.orientation);
+        assertEquals(10f, coords.getAxisValue(MotionEvent.AXIS_GENERIC_1));
+    }
+
+    public void testPointerCoordsCopyFrom() {
+        PointerCoords coords = new PointerCoords();
+        coords.x = 1;
+        coords.y = 2;
+        coords.pressure = 3;
+        coords.size = 4;
+        coords.touchMajor = 5;
+        coords.touchMinor = 6;
+        coords.toolMajor = 7;
+        coords.toolMinor = 8;
+        coords.orientation = 9;
+        coords.setAxisValue(MotionEvent.AXIS_GENERIC_1, 10);
+
+        PointerCoords copy = new PointerCoords();
+        copy.copyFrom(coords);
+        assertEquals(1f, copy.x);
+        assertEquals(2f, copy.y);
+        assertEquals(3f, copy.pressure);
+        assertEquals(4f, copy.size);
+        assertEquals(5f, copy.touchMajor);
+        assertEquals(6f, copy.touchMinor);
+        assertEquals(7f, copy.toolMajor);
+        assertEquals(8f, copy.toolMinor);
+        assertEquals(9f, copy.orientation);
+        assertEquals(10f, coords.getAxisValue(MotionEvent.AXIS_GENERIC_1));
+    }
 }
diff --git a/tests/tests/view/src/android/view/cts/VelocityTrackerTest.java b/tests/tests/view/src/android/view/cts/VelocityTrackerTest.java
index 35254b6..25b94d9 100644
--- a/tests/tests/view/src/android/view/cts/VelocityTrackerTest.java
+++ b/tests/tests/view/src/android/view/cts/VelocityTrackerTest.java
@@ -96,7 +96,7 @@
         VelocityTracker vt = VelocityTracker.obtain();
         assertNotNull(vt);
 
-        MotionEvent me = MotionEvent.obtain(0L, 10, 1, .0f, .0f, 0);
+        MotionEvent me = MotionEvent.obtain(0L, 10L, MotionEvent.ACTION_MOVE, .0f, .0f, 0);
 
         vt.clear();
         me.addBatch(20L, 20, 20, .0f, .0f, 0);
@@ -112,14 +112,14 @@
         assertEquals(XVelocity, vt.getXVelocity(), ERROR_TOLERANCE);
         assertEquals(YVelocity, vt.getYVelocity(), ERROR_TOLERANCE);
 
-        for (int i = 30; i < 100; i += 10) {
-            me.addBatch((long)i, (float)i, (float)i, .0f, .0f, 0);
+        for (int i = 3; i < 10; i++) {
+            me.addBatch((long)i * 10, (float)i * 10, (float)i * 10, .0f, .0f, 0);
         }
         vt.clear();
         vt.addMovement(me);
         vt.computeCurrentVelocity(1);
-        XVelocity = 1.1875744f;
-        YVelocity = 1.1875744f;
+        XVelocity = 1.1479408f;
+        YVelocity = 1.1479408f;
         assertEquals(XVelocity, vt.getXVelocity(), ERROR_TOLERANCE);
         assertEquals(YVelocity, vt.getYVelocity(), ERROR_TOLERANCE);
 
@@ -127,11 +127,21 @@
         me.addBatch(100L, 100, 100, .0f, .0f, 0);
         vt.addMovement(me);
         vt.computeCurrentVelocity(1);
-        XVelocity = 1.1562872f;
-        YVelocity = 1.1562872f;
+        XVelocity = 1.1284428f;
+        YVelocity = 1.1284428f;
         assertEquals(XVelocity, vt.getXVelocity(), ERROR_TOLERANCE);
         assertEquals(YVelocity, vt.getYVelocity(), ERROR_TOLERANCE);
 
+        me.recycle();
+        me = MotionEvent.obtain(0L, 110L, MotionEvent.ACTION_UP, 100f, 100f, 0);
+        vt.addMovement(me);
+        vt.computeCurrentVelocity(1);
+        XVelocity = 1.1284428f;
+        YVelocity = 1.1284428f;
+        assertEquals(XVelocity, vt.getXVelocity(), ERROR_TOLERANCE);
+        assertEquals(YVelocity, vt.getYVelocity(), ERROR_TOLERANCE);
+
+        me.recycle();
         vt.recycle();
     }
 }
diff --git a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
index b2bdfc8..51f1201 100644
--- a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
+++ b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
@@ -54,6 +54,8 @@
     public static final String BLANK_PAGE_URL = "webkit/test_blankPage.html";
     public static final String ADD_JAVA_SCRIPT_INTERFACE_URL = "webkit/test_jsInterface.html";
 
+    public static final String FORM_PAGE_URL = "webkit/form_page.html";
+
     public static final String EXT_WEB_URL1 = "http://www.example.com/";
 
     public static final String getFileUrl(String assetName) {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebDriverTest.java b/tests/tests/webkit/src/android/webkit/cts/WebDriverTest.java
new file mode 100644
index 0000000..93c7b5f
--- /dev/null
+++ b/tests/tests/webkit/src/android/webkit/cts/WebDriverTest.java
@@ -0,0 +1,481 @@
+/*
+ * 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.webkit.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.webkit.webdriver.By;
+import android.webkit.webdriver.WebDriver;
+import android.webkit.webdriver.WebElement;
+import android.webkit.webdriver.WebElementNotFoundException;
+import android.webkit.webdriver.WebElementStaleException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static android.webkit.cts.TestHtmlConstants.FORM_PAGE_URL;
+import static android.webkit.cts.TestHtmlConstants.HELLO_WORLD_URL;
+
+/**
+ * Tests for {@link android.webkit.webdriver.WebDriver}.
+ */
+public class WebDriverTest extends
+        ActivityInstrumentationTestCase2<WebDriverStubActivity>{
+    private WebDriver mDriver;
+    private CtsTestServer mWebServer;
+    private static final String SOME_TEXT = "Some text";
+    private static final String DIV_TEXT = "A div Nested text";
+    private static final String NESTED_TEXT = "Nested text";
+    private static final String DIV_ID = "divId";
+    private static final String SOME_TEXT_ID = "someTextId";
+    private static final String BAD_ID = "BadId";
+    private static final String NESTED_LINK_ID = "nestedLinkId";
+
+    public WebDriverTest() {
+        super(WebDriverStubActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDriver = getActivity().getDriver();
+        mWebServer = new CtsTestServer(getActivity(), false);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mWebServer.shutdown();
+        super.tearDown();
+    }
+
+    public void testGetIsBlocking() {
+        mDriver.get(mWebServer.getDelayedAssetUrl(HELLO_WORLD_URL));
+        assertTrue(mDriver.getPageSource().contains("hello world!"));
+    }
+
+    // By id
+    public void testFindElementById() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.id(SOME_TEXT_ID));
+        assertTrue(SOME_TEXT.equals(element.getText()));
+
+        element = mDriver.findElement(By.id(DIV_ID));
+        assertTrue(DIV_TEXT.equals(element.getText()));
+    }
+
+    public void testFindElementByIdThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.id(BAD_ID));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementById() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.id(NESTED_LINK_ID));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    // By linkText
+    public void testFindElementByLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.id(SOME_TEXT_ID));
+        assertTrue(SOME_TEXT.equals(element.getText()));
+
+        element = mDriver.findElement(By.id(DIV_ID));
+        assertTrue(DIV_TEXT.equals(element.getText()));
+    }
+
+    public void testFindElementByLinkTextThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.id(BAD_ID));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.id(NESTED_LINK_ID));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    // By partialLinkText
+    public void testFindElementByPartialLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.id(SOME_TEXT_ID));
+        assertTrue(SOME_TEXT.equals(element.getText()));
+
+        element = mDriver.findElement(By.id(DIV_ID));
+        assertTrue(DIV_TEXT.equals(element.getText()));
+    }
+
+    public void testFindElementByPartialLinkTextThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.id(BAD_ID));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByPartialLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.id(NESTED_LINK_ID));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    // by name
+    public void testFindElementByName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.id(SOME_TEXT_ID));
+        assertTrue(SOME_TEXT.equals(element.getText()));
+
+        element = mDriver.findElement(By.id(DIV_ID));
+        assertTrue(DIV_TEXT.equals(element.getText()));
+    }
+
+    public void testFindElementByNameThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.id(BAD_ID));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.id(NESTED_LINK_ID));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    // By tagName
+    public void testFindElementByTagName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.id(SOME_TEXT_ID));
+        assertTrue(SOME_TEXT.equals(element.getText()));
+
+        element = mDriver.findElement(By.id(DIV_ID));
+        assertTrue(DIV_TEXT.equals(element.getText()));
+    }
+
+    public void testFindElementByTagNameThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.id(BAD_ID));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByTagName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.id(NESTED_LINK_ID));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    // By xpath
+    public void testFindElementByXPath() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.id(SOME_TEXT_ID));
+        assertTrue(SOME_TEXT.equals(element.getText()));
+
+        element = mDriver.findElement(By.id(DIV_ID));
+        assertTrue(DIV_TEXT.equals(element.getText()));
+    }
+
+    public void testFindElementByXPathThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.id(BAD_ID));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByXPath() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.id(NESTED_LINK_ID));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    public void testGetTextThrowsIfElementIsStale() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement div = mDriver.findElement(By.id(DIV_ID));
+        mDriver.get(mWebServer.getAssetUrl(HELLO_WORLD_URL));
+        try {
+            div.getText();
+            fail("This should have failed.");
+        } catch (WebElementStaleException e) {
+            // This is expected
+        }
+    }
+
+    public void testExecuteScriptShouldReturnAString() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Object result = mDriver.executeScript("return document.title");
+        assertEquals("Test Page", (String) result);
+    }
+
+    public void testExecuteScriptShouldReturnAWebElement() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Object result = mDriver.executeScript(
+                "return document.getElementsByTagName('div')[0];");
+        assertTrue(result instanceof WebElement);
+        assertEquals(DIV_TEXT, ((WebElement) result).getText());
+    }
+
+    public void testExecuteScriptShouldPassAndReturnADouble() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Double expected = new Double(1.2);
+        Object result = mDriver.executeScript("return arguments[0];", expected);
+        assertTrue(result instanceof Double);
+        assertEquals(expected, (Double) result);
+    }
+
+    public void testExecuteScriptShouldPassAndReturnALong() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Long expected = new Long(1);
+        Object result = mDriver.executeScript("return arguments[0];", expected);
+        assertTrue(result instanceof Long);
+        assertEquals(expected, (Long) result);
+    }
+
+    public void testExecuteScriptShouldPassReturnABoolean() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Boolean expected = new Boolean(true);
+        Object result = mDriver.executeScript("return arguments[0] === true;",
+                expected);
+        assertTrue(result instanceof Boolean);
+        assertEquals(expected, (Boolean) result);
+    }
+
+    public void testExecuteScriptShouldReturnAList() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<String> expected = new ArrayList();
+        expected.add("one");
+        expected.add("two");
+        expected.add("three");
+
+        Object result = mDriver.executeScript(
+                "return ['one', 'two', 'three'];");
+
+        assertTrue(expected.equals((List<String>) result));
+    }
+
+    public void testExecuteScriptShouldReturnNestedList() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<Object> expected = new ArrayList();
+        expected.add("one");
+        List<Object> nestedList = new ArrayList();
+        nestedList.add(true);
+        nestedList.add(false);
+        expected.add(nestedList);
+        Map<String, Object> nestedMap = new HashMap();
+        nestedMap.put("bread", "cheese");
+        nestedMap.put("hungry", true);
+        expected.add(nestedMap);
+
+        Object result = mDriver.executeScript(
+                "return ['one', [true, false], "
+                + "{bread:'cheese', hungry:true}];");
+
+        assertTrue(expected.equals(result));
+    }
+
+    public void testExecuteScriptShouldBeAbleToReturnALisOfwebElements() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> result = (List<WebElement>) mDriver.executeScript(
+                "return document.getElementsByTagName('a')");
+        assertEquals(5, result.size());
+    }
+
+    public void testExecuteScriptShouldReturnAMap() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Map<String, Object> expected = new HashMap();
+        expected.put("abc", Long.valueOf(123));
+        expected.put("cat", false);
+        Map<String, Object> nestedMap = new HashMap();
+        nestedMap.put("bread", "cheese");
+        nestedMap.put("hungry", true);
+        expected.put("map", nestedMap);
+        List<String> nestedList = new ArrayList();
+        nestedList.add("bou");
+        nestedList.add("truc");
+        expected.put("list", nestedList);
+
+        Object res = mDriver.executeScript("return {abc:123, cat:false, "
+                + "map:{bread:'cheese', hungry:true}, list:['bou', 'truc']};");
+        assertTrue(res instanceof Map);
+        Map<String, Object> result = (Map<String, Object>) res;
+        assertEquals(expected.size(), result.size());
+
+        assertTrue(expected.equals(result));
+    }
+
+    public void testExecuteScriptShouldThrowIfJsIsBad() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.executeScript("return bou();");
+            fail("This should have failed");
+        } catch (RuntimeException e) {
+            // This is expected.
+        }
+    }
+
+    public void testExecuteScriptShouldbeAbleToPassAString() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        String expected = "bou";
+        Object result = mDriver.executeScript("return arguments[0]", expected);
+        assertEquals(expected, (String) result);
+    }
+
+    public void testExecuteScriptShouldBeAbleToPassWebElement() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement div = mDriver.findElement(By.id(DIV_ID));
+        Object result = mDriver.executeScript(
+                "arguments[0]['flibble'] = arguments[0].getAttribute('id');"
+                + "return arguments[0]['flibble'];", div);
+        assertEquals(DIV_ID, (String) result);
+    }
+
+    public void testExecuteScriptShouldBeAbleToPassAList() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<String> expected = new ArrayList();
+        expected.add("apple");
+        expected.add("cheese");
+        expected.add("food");
+
+        Object result = mDriver.executeScript(
+                "return arguments[0].length", expected);
+        assertEquals(expected.size(), ((Long) result).intValue());
+    }
+
+    public void testExecuteScriptShouldBeAbleToPassNestedLists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<Object> expected = new ArrayList();
+        expected.add("apple");
+        expected.add("cheese");
+        List<Integer> nested = new ArrayList();
+        nested.add(1);
+        nested.add(2);
+        expected.add(nested);
+        expected.add("food");
+
+        Object result = mDriver.executeScript(
+                "return arguments[0][2].length", expected);
+        assertEquals(nested.size(), ((Long) result).intValue());
+    }
+
+    public void testExecuteScriptShouldBeAbleToPassAMap() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Map<String, String> expected = new HashMap();
+        expected.put("apple", "pie");
+        expected.put("cheese", "cake");
+
+        Object result = mDriver.executeScript(
+                "return arguments[0].apple", expected);
+        assertEquals(expected.get("apple"), (String) result);
+    }
+
+    public void testExecuteScriptShouldBeAbleToPassNestedMaps() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Map<String, Object> expected = new HashMap();
+        expected.put("apple", "pie");
+        Map<String, String> nested = new HashMap();
+        nested.put("foo", "boo");
+        expected.put("nested", nested);
+        expected.put("cheese", "cake");
+
+        Object result = mDriver.executeScript(
+                "return arguments[0].nested.foo", expected);
+        assertEquals(((Map<String, Object>)expected.get("nested")).get("foo"),
+                (String) result);
+    }
+
+
+    public void testExecuteScriptShouldThrowIfArgumentIsNotValid() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.executeScript("return arguments[0];", mDriver);
+            fail("This should have failed");
+        } catch (RuntimeException e) {
+            // This is expected.
+        }
+    }
+
+    public void testExecuteScriptHandlesStringCorrectly() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        String cheese = "cheese";
+        String bread = "bread";
+        Object result = mDriver.executeScript(
+                "return 'I love ' + arguments[0] + ' and ' + arguments[1]",
+                cheese, bread);
+        assertEquals("I love cheese and bread", (String) result);
+    }
+
+    public void testExecuteScriptShouldThrowIfNoPageLoaded() {
+        try {
+            mDriver.executeScript("return 'bou';");
+            fail("This should have failed");
+        } catch (RuntimeException e) {
+            // This is expected.
+        }
+    }
+
+    public void testExecuteScriptShouldBeAbleToCreatePersistentValue() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        mDriver.executeScript("document.bidule = ['hello']");
+        Object result = mDriver.executeScript(
+                "return document.bidule.shift();");
+        assertEquals("hello", (String) result);
+    }
+
+    public void testExecuteScriptEscapesQuotesAndBackslash() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return \"foo'\\\"\" == arguments[0];", "foo'\""));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return \"foo'\\\"bar\" == arguments[0];", "foo'\"bar"));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return 'foo\"' == arguments[0];", "foo\""));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return \"foo'\" == arguments[0];", "foo'"));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return \"foo\\\\\\\"\" == arguments[0];", "foo\\\""));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return \"f\\\"o\\\\o\\\\\\\\\\\"\" == arguments[0];",
+                "f\"o\\o\\\\\""));
+    }
+}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
index d6a218e..2923ba2 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
@@ -58,6 +58,7 @@
         System.out.println("  -o FILE              output file or standard out if not given");
         System.out.println("  -f [txt|xml|html]    format of output");
         System.out.println("  -d PATH              path to dexdeps or expected to be in $PATH");
+        System.out.println("  -a PATH              path to the API XML file");
         System.out.println();
         System.exit(1);
     }
@@ -67,6 +68,7 @@
         File outputFile = null;
         int format = FORMAT_TXT;
         String dexDeps = "dexDeps";
+        String apiXmlPath = "";
 
         for (int i = 0; i < args.length; i++) {
             if (args[i].startsWith("-")) {
@@ -85,6 +87,8 @@
                     }
                 } else if ("-d".equals(args[i])) {
                     dexDeps = getExpectedArg(args, ++i);
+                } else if ("-a".equals(args[i])) {
+                    apiXmlPath = getExpectedArg(args, ++i);
                 } else {
                     printUsage();
                 }
@@ -104,7 +108,7 @@
          * 3. Output a report based on the coverage stats in the ApiCoverage object.
          */
 
-        ApiCoverage apiCoverage = getEmptyApiCoverage();
+        ApiCoverage apiCoverage = getEmptyApiCoverage(apiXmlPath);
         for (File testApk : testApks) {
             addApiCoverage(apiCoverage, testApk, dexDeps);
         }
@@ -125,16 +129,17 @@
      * Creates an object representing the API that will be used later to collect coverage
      * statistics as we iterate over the test APKs.
      *
+     * @param apiXmlPath to the API XML file
      * @return an {@link ApiCoverage} object representing the API in current.xml without any
      *     coverage statistics yet
      */
-    private static ApiCoverage getEmptyApiCoverage()
+    private static ApiCoverage getEmptyApiCoverage(String apiXmlPath)
             throws SAXException, IOException {
         XMLReader xmlReader = XMLReaderFactory.createXMLReader();
         CurrentXmlHandler currentXmlHandler = new CurrentXmlHandler();
         xmlReader.setContentHandler(currentXmlHandler);
 
-        File currentXml = new File("frameworks/base/api/current.xml");
+        File currentXml = new File(apiXmlPath);
         FileReader fileReader = null;
         try {
             fileReader = new FileReader(currentXml);
diff --git a/tools/dasm/src/dasm/DAsm.java b/tools/dasm/src/dasm/DAsm.java
index 2b58705..e5f5ead 100644
--- a/tools/dasm/src/dasm/DAsm.java
+++ b/tools/dasm/src/dasm/DAsm.java
@@ -16,6 +16,7 @@
 
 package dasm;
 
+import com.android.dx.dex.DexOptions;
 import com.android.dx.dex.code.ArrayData;
 import com.android.dx.dex.code.CodeAddress;
 import com.android.dx.dex.code.CstInsn;
@@ -82,6 +83,9 @@
     // number of errors reported in a file.
     int errors;
 
+    // options for dex output
+    DexOptions dexOptions = new DexOptions();
+
     // file being processed
     DexFile dexFile;
     int line_num;
@@ -1517,7 +1521,7 @@
      */
     private void createOutputFinisher() {
         if (output_finisher == null)
-            output_finisher = new OutputFinisher(5, regs_count);
+            output_finisher = new OutputFinisher(dexOptions, 5, regs_count);
     }
 
     /**
diff --git a/tools/dasm/src/dasm/DopInfo.java b/tools/dasm/src/dasm/DopInfo.java
index 8939399..c6a0aa7 100644
--- a/tools/dasm/src/dasm/DopInfo.java
+++ b/tools/dasm/src/dasm/DopInfo.java
@@ -16,7 +16,6 @@
 
 package dasm;
 
-import com.android.dx.dex.code.DalvOps;
 import com.android.dx.dex.code.Dop;
 import com.android.dx.dex.code.Dops;
 import com.android.dx.dex.code.InsnFormat;
@@ -44,6 +43,7 @@
 import com.android.dx.dex.code.form.Form35c;
 import com.android.dx.dex.code.form.Form3rc;
 import com.android.dx.dex.code.form.Form51l;
+import com.android.dx.io.Opcodes;
 
 import java.util.Hashtable;
 
@@ -135,24 +135,24 @@
         if (format instanceof Form21h) return ARG_REG_LITERAL;
         if (format instanceof Form21c) {
             switch (dop.getOpcode()) {
-            case DalvOps.CONST_CLASS:
-            case DalvOps.CHECK_CAST:
-            case DalvOps.NEW_INSTANCE:
+            case Opcodes.CONST_CLASS:
+            case Opcodes.CHECK_CAST:
+            case Opcodes.NEW_INSTANCE:
                 return ARG_REG_TYPE;
-            case DalvOps.SGET:
-            case DalvOps.SGET_WIDE:
-            case DalvOps.SGET_OBJECT:
-            case DalvOps.SGET_BOOLEAN:
-            case DalvOps.SGET_BYTE:
-            case DalvOps.SGET_CHAR:
-            case DalvOps.SGET_SHORT:
-            case DalvOps.SPUT:
-            case DalvOps.SPUT_WIDE:
-            case DalvOps.SPUT_OBJECT:
-            case DalvOps.SPUT_BOOLEAN:
-            case DalvOps.SPUT_BYTE:
-            case DalvOps.SPUT_CHAR:
-            case DalvOps.SPUT_SHORT:
+            case Opcodes.SGET:
+            case Opcodes.SGET_WIDE:
+            case Opcodes.SGET_OBJECT:
+            case Opcodes.SGET_BOOLEAN:
+            case Opcodes.SGET_BYTE:
+            case Opcodes.SGET_CHAR:
+            case Opcodes.SGET_SHORT:
+            case Opcodes.SPUT:
+            case Opcodes.SPUT_WIDE:
+            case Opcodes.SPUT_OBJECT:
+            case Opcodes.SPUT_BOOLEAN:
+            case Opcodes.SPUT_BYTE:
+            case Opcodes.SPUT_CHAR:
+            case Opcodes.SPUT_SHORT:
                 return ARG_REG_FIELD;
             default:
                 return ARG_REG_STRING;
@@ -164,23 +164,23 @@
         if (format instanceof Form22s) return ARG_REG_REG_LITERAL;
         if (format instanceof Form22c) {
             switch (dop.getOpcode()) {
-            case DalvOps.INSTANCE_OF:
-            case DalvOps.NEW_ARRAY:
+            case Opcodes.INSTANCE_OF:
+            case Opcodes.NEW_ARRAY:
                 return ARG_REG_REG_TYPE;
-            case DalvOps.IGET:
-            case DalvOps.IGET_WIDE:
-            case DalvOps.IGET_OBJECT:
-            case DalvOps.IGET_BOOLEAN:
-            case DalvOps.IGET_BYTE:
-            case DalvOps.IGET_CHAR:
-            case DalvOps.IGET_SHORT:
-            case DalvOps.IPUT:
-            case DalvOps.IPUT_WIDE:
-            case DalvOps.IPUT_OBJECT:
-            case DalvOps.IPUT_BOOLEAN:
-            case DalvOps.IPUT_BYTE:
-            case DalvOps.IPUT_CHAR:
-            case DalvOps.IPUT_SHORT:
+            case Opcodes.IGET:
+            case Opcodes.IGET_WIDE:
+            case Opcodes.IGET_OBJECT:
+            case Opcodes.IGET_BOOLEAN:
+            case Opcodes.IGET_BYTE:
+            case Opcodes.IGET_CHAR:
+            case Opcodes.IGET_SHORT:
+            case Opcodes.IPUT:
+            case Opcodes.IPUT_WIDE:
+            case Opcodes.IPUT_OBJECT:
+            case Opcodes.IPUT_BOOLEAN:
+            case Opcodes.IPUT_BYTE:
+            case Opcodes.IPUT_CHAR:
+            case Opcodes.IPUT_SHORT:
                 return ARG_REG_REG_FIELD;
             default:
                 return ARG_REG_REG_STRING;
@@ -193,12 +193,12 @@
         if (format instanceof Form31c) return ARG_REG_STRING;
         if (format instanceof Form35c) {
             switch (dop.getOpcode()) {
-            case DalvOps.INVOKE_VIRTUAL:
-            case DalvOps.INVOKE_SUPER:
-            case DalvOps.INVOKE_DIRECT:
-            case DalvOps.INVOKE_STATIC:
+            case Opcodes.INVOKE_VIRTUAL:
+            case Opcodes.INVOKE_SUPER:
+            case Opcodes.INVOKE_DIRECT:
+            case Opcodes.INVOKE_STATIC:
                 return ARG_REGLIST_METHOD;
-            case DalvOps.INVOKE_INTERFACE:
+            case Opcodes.INVOKE_INTERFACE:
                 return ARG_REGLIST_INTFMETHOD;
             default:
                 return ARG_REGLIST_TYPE;
@@ -206,9 +206,9 @@
         }
         if (format instanceof Form3rc) {
             switch (dop.getOpcode()) {
-            case DalvOps.FILLED_NEW_ARRAY_RANGE:
+            case Opcodes.FILLED_NEW_ARRAY_RANGE:
                 return ARG_REGRANGE_TYPE;
-            case DalvOps.INVOKE_INTERFACE_RANGE:
+            case Opcodes.INVOKE_INTERFACE_RANGE:
                 return ARG_REGRANGE_INTFMETHOD;
             default:
                 return ARG_REGRANGE_METHOD;
@@ -228,7 +228,7 @@
     static {
         dopsTable = new Hashtable<String, DopInfo>();
 
-        for (int i = 0; i < DalvOps.MAX_VALUE - DalvOps.MIN_VALUE + 1; i++) {
+        for (int i = 0; i < Opcodes.MAX_VALUE - Opcodes.MIN_VALUE + 1; i++) {
             try {
                 Dop dop = Dops.get(i);
                 add(dop.getName(), dop, getArgsFormat(dop));
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
index 4a2d56c..9bc0945 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.tradefed.build;
 
+import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.build.IFolderBuildInfo;
 
 import java.io.File;
@@ -57,6 +58,29 @@
     }
 
     /**
+     * A helper factory method that creates and validates a {@link CtsBuildHelper} given an
+     * {@link IBuildInfo}.
+     *
+     * @param build the {@link IBuildInfo}
+     * @return the {@link CtsBuildHelper}
+     * @throws IllegalArgumentException if provided <var>build</var> is not a valid CTS build
+     */
+    public static CtsBuildHelper createBuildHelper(IBuildInfo build) {
+        if (!(build instanceof IFolderBuildInfo)) {
+            throw new IllegalArgumentException(String.format(
+                    "Wrong build type. Expected %s, received %s", IFolderBuildInfo.class.getName(),
+                    build.getClass().getName()));
+        }
+        try {
+            CtsBuildHelper ctsBuild = new CtsBuildHelper((IFolderBuildInfo)build);
+            ctsBuild.validateStructure();
+            return ctsBuild;
+        } catch (FileNotFoundException e) {
+            throw new IllegalArgumentException("Invalid CTS build provided.", e);
+        }
+    }
+
+    /**
      * @return a {@link File} representing the parent folder of the CTS installation
      */
     public File getRootDir() {
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 2834793..f6d8142 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
@@ -22,7 +22,6 @@
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IFolderBuildInfo;
 import com.android.tradefed.config.Option;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
@@ -32,7 +31,6 @@
 import com.android.tradefed.testtype.IRemoteTest;
 import com.android.tradefed.testtype.IResumableTest;
 import com.android.tradefed.testtype.IShardableTest;
-import com.android.tradefed.testtype.InstrumentationTest;
 import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
 
 import java.io.BufferedInputStream;
@@ -119,6 +117,7 @@
     private List<KnownTests> mRemainingTests = null;
 
     private CtsBuildHelper mCtsBuild = null;
+    private IBuildInfo mBuildInfo = null;
 
     /**
      * {@inheritDoc}
@@ -201,17 +200,8 @@
      */
     @Override
     public void setBuild(IBuildInfo build) {
-        if (!(build instanceof IFolderBuildInfo)) {
-            throw new IllegalArgumentException(String.format(
-                    "Wrong build type. Expected %s, received %s", IFolderBuildInfo.class.getName(),
-                    build.getClass().getName()));
-        }
-        try {
-            mCtsBuild = new CtsBuildHelper((IFolderBuildInfo)build);
-            mCtsBuild.validateStructure();
-        } catch (FileNotFoundException e) {
-            throw new IllegalArgumentException("Invalid CTS build provided.", e);
-        }
+        mCtsBuild = CtsBuildHelper.createBuildHelper(build);
+        mBuildInfo = build;
     }
 
     /**
@@ -249,12 +239,10 @@
             if (test instanceof IDeviceTest) {
                 ((IDeviceTest)test).setDevice(getDevice());
             }
-            // Increment the timeout for collecting the tests.
-            // TODO: move this to testPackage.createTest() instead and only increase timeout when
-            // tests number is large.
-            if (test instanceof InstrumentationTest) {
-                ((InstrumentationTest)test).setCollectsTestsShellTimeout(10*60*1000);
+            if (test instanceof IBuildReceiver) {
+                ((IBuildReceiver)test).setBuild(mBuildInfo);
             }
+
             ResultFilter filter = new ResultFilter(listener, testPair.getKnownTests());
             test.run(filter);
             mRemainingTests.remove(0);
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
index e4f13b5..f4258d1 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
@@ -27,7 +27,7 @@
  * <p/>
  * Knows how to translate this info into a runnable {@link IRemoteTest}.
  */
-interface ITestPackageDef {
+public interface ITestPackageDef {
 
     /**
      * Get the unique URI of the test package.
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationApkTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationApkTest.java
new file mode 100644
index 0000000..e1bb91e
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationApkTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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 com.android.cts.tradefed.testtype;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.ddmlib.Log;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.InstrumentationTest;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import junit.framework.Assert;
+
+/**
+ * A {@link InstrumentationTest] that will install CTS apks before test execution,
+ * and uninstall on execution completion.
+ */
+public class InstrumentationApkTest extends InstrumentationTest implements IBuildReceiver {
+
+    private static final String LOG_TAG = "InstrumentationApkTest";
+
+    /** the file names of the CTS apks to install */
+    private Collection<String> mInstallFileNames = new ArrayList<String>();
+    private Collection<String> mUninstallPackages = new ArrayList<String>();
+
+    private CtsBuildHelper mCtsBuild = null;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo build) {
+        mCtsBuild  = CtsBuildHelper.createBuildHelper(build);
+    }
+
+    /**
+     * Add an apk to install.
+     *
+     * @param apkFileName the apk file name
+     * @param packageName the apk's Android package name
+     */
+    public void addInstallApk(String apkFileName, String packageName) {
+        mInstallFileNames.add(apkFileName);
+        mUninstallPackages.add(packageName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void run(final ITestInvocationListener listener)
+            throws DeviceNotAvailableException {
+        Assert.assertNotNull("missing device", getDevice());
+        Assert.assertNotNull("missing build", mCtsBuild);
+
+        try {
+            for (String apkFileName : mInstallFileNames) {
+                Log.d(LOG_TAG, String.format("Installing %s on %s", apkFileName,
+                        getDevice().getSerialNumber()));
+                try {
+                    getDevice().installPackage(mCtsBuild.getTestApp(apkFileName), true);
+                } catch (FileNotFoundException e) {
+                    Log.e(LOG_TAG, e);
+                }
+            }
+            super.run(listener);
+        } finally {
+            for (String packageName : mUninstallPackages) {
+                Log.d(LOG_TAG, String.format("Uninstalling %s on %s", packageName,
+                        getDevice().getSerialNumber()));
+                getDevice().uninstallPackage(packageName);
+            }
+        }
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationAppTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationAppTest.java
deleted file mode 100644
index 47fc14a..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationAppTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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 com.android.cts.tradefed.testtype;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.InstrumentationTest;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * A {@link InstrumentationTest] that will install other dependent apks before test execution,
- * and uninstall apps on execution completion.
- */
-public class InstrumentationAppTest extends InstrumentationTest {
-
-    private static final String LOG_TAG = "InstrumentationAppTest";
-
-    // TODO: consider moving this class to tradefed proper
-
-    private Collection<File> mInstallFiles = new ArrayList<File>();
-    private Collection<String> mInstallPackages = new ArrayList<String>();
-
-    /**
-     * Add a dependent apk to install.
-     *
-     * @param apkFile the apk file
-     * @param packageName the apk's Android package name
-     */
-    public void addInstallApp(File apkFile, String packageName) {
-        mInstallFiles.add(apkFile);
-        mInstallPackages.add(packageName);
-    }
-
-    @Override
-    public void run(final ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        if (getDevice() == null) {
-            throw new IllegalStateException("missing device");
-        }
-        try {
-            for (File apkFile : mInstallFiles) {
-                Log.d(LOG_TAG, String.format("Installing %s on %s", apkFile.getName(),
-                        getDevice().getSerialNumber()));
-                getDevice().installPackage(apkFile, true);
-            }
-            super.run(listener);
-        } finally {
-            for (String packageName : mInstallPackages) {
-                Log.d(LOG_TAG, String.format("Uninstalling %s on %s", packageName,
-                        getDevice().getSerialNumber()));
-                getDevice().uninstallPackage(packageName);
-            }
-        }
-    }
-}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JarHostTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JarHostTest.java
index 041079d..2fe6802 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JarHostTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JarHostTest.java
@@ -15,12 +15,15 @@
  */
 package com.android.cts.tradefed.testtype;
 
+import com.android.cts.tradefed.build.CtsBuildHelper;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.result.ITestInvocationListener;
 import com.android.tradefed.result.JUnitToInvocationResultForwarder;
+import com.android.tradefed.testtype.IBuildReceiver;
 import com.android.tradefed.testtype.IDeviceTest;
 import com.android.tradefed.testtype.IRemoteTest;
 import com.android.tradefed.util.CommandStatus;
@@ -28,6 +31,7 @@
 import com.android.tradefed.util.RunUtil;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -39,29 +43,50 @@
 import junit.framework.TestResult;
 
 /**
- * A {@link IRemoteTest} that can run a set of JUnit tests from a jar.
+ * A {@link IRemoteTest} that can run a set of JUnit tests from a CTS jar.
  */
-public class JarHostTest implements IDeviceTest, IRemoteTest {
+public class JarHostTest implements IDeviceTest, IRemoteTest, IBuildReceiver {
 
     private static final String LOG_TAG = "JarHostTest";
 
     private ITestDevice mDevice;
-    private File mJarFile;
+    private String mJarFileName;
     private Collection<TestIdentifier> mTests;
     private long mTimeoutMs = 10 * 60 * 1000;
     private String mRunName;
-    private String mTestAppPath;
+    private CtsBuildHelper mCtsBuild = null;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    /**
+     * Set the CTS build container.
+     * <p/>
+     * Exposed so unit tests can mock the provided build.
+     *
+     * @param buildHelper
+     */
+    void setBuildHelper(CtsBuildHelper buildHelper) {
+        mCtsBuild = buildHelper;
+    }
 
     /**
      * Set the jar file to load tests from.
-     * @param jarFile
+     *
+     * @param jarFileName the file name of the CTS host test jar to use
      */
-    void setJarFile(File jarFile) {
-        mJarFile = jarFile;
+    void setJarFileName(String jarFileName) {
+        mJarFileName = jarFileName;
     }
 
     /**
      * Sets the collection of tests to run
+     *
      * @param tests
      */
     void setTests(Collection<TestIdentifier> tests) {
@@ -90,17 +115,6 @@
     }
 
     /**
-     * Set the filesystem path to test app artifacts needed to run tests.
-     *
-     * @see {@link com.android.hosttest.DeviceTest#setTestAppPath(String)}
-     *
-     * @param testAppPath
-     */
-    void setTestAppPath(String testAppPath) {
-        mTestAppPath = testAppPath;
-    }
-
-    /**
      * {@inheritDoc}
      */
     @Override
@@ -153,7 +167,7 @@
             // all host tests are converted to use tradefed
             com.android.hosttest.DeviceTest deviceTest = (com.android.hosttest.DeviceTest)junitTest;
             deviceTest.setDevice(getDevice().getIDevice());
-            deviceTest.setTestAppPath(mTestAppPath);
+            deviceTest.setTestAppPath(mCtsBuild.getTestCasesDir().getAbsolutePath());
         }
         CommandStatus status = RunUtil.getInstance().runTimed(mTimeoutMs, new IRunnableResult() {
 
@@ -183,7 +197,8 @@
      */
     private Test loadTest(String className, String testName) {
         try {
-            URL urls[] = {mJarFile.getCanonicalFile().toURI().toURL()};
+            File jarFile = mCtsBuild.getTestApp(mJarFileName);
+            URL urls[] = {jarFile.getCanonicalFile().toURI().toURL()};
             Class<?> testClass = loadClass(className, urls);
 
             if (TestCase.class.isAssignableFrom(testClass)) {
@@ -195,16 +210,16 @@
                 return test;
             } else {
                 Log.e(LOG_TAG, String.format("Class '%s' from jar '%s' is not a Test",
-                        className, mJarFile.getAbsolutePath()));
+                        className, mJarFileName));
             }
         } catch (ClassNotFoundException e) {
-            reportLoadError(mJarFile, className, e);
+            reportLoadError(mJarFileName, className, e);
         } catch (IllegalAccessException e) {
-            reportLoadError(mJarFile, className, e);
+            reportLoadError(mJarFileName, className, e);
         } catch (IOException e) {
-            reportLoadError(mJarFile, className, e);
+            reportLoadError(mJarFileName, className, e);
         } catch (InstantiationException e) {
-            reportLoadError(mJarFile, className, e);
+            reportLoadError(mJarFileName, className, e);
         }
         return null;
     }
@@ -225,9 +240,9 @@
         return testClass;
     }
 
-    private void reportLoadError(File jarFile, String className, Exception e) {
+    private void reportLoadError(String jarFileName, String className, Exception e) {
         Log.e(LOG_TAG, String.format("Failed to load test class '%s' from jar '%s'",
-                className, jarFile.getAbsolutePath()));
+                className, jarFileName));
         Log.e(LOG_TAG, e);
     }
 
@@ -241,11 +256,21 @@
         if (mDevice == null) {
             throw new IllegalArgumentException("Device has not been set");
         }
-        if (mJarFile == null) {
-            throw new IllegalArgumentException("jar file has not been set");
+        if (mJarFileName == null) {
+            throw new IllegalArgumentException("jar file name has not been set");
         }
         if (mTests == null) {
             throw new IllegalArgumentException("tests has not been set");
         }
+        if (mCtsBuild == null) {
+            throw new IllegalArgumentException("build has not been set");
+        }
+        try {
+            mCtsBuild.getTestApp(mJarFileName);
+        } catch (FileNotFoundException e) {
+            throw new IllegalArgumentException(String.format(
+                    "Could not find jar %s in CTS build %s", mJarFileName,
+                    mCtsBuild.getRootDir().getAbsolutePath()));
+        }
     }
 }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index fd896f2..04da318 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -136,8 +136,7 @@
             Log.d(LOG_TAG, String.format("Creating host test for %s", mName));
             JarHostTest hostTest = new JarHostTest();
             hostTest.setRunName(mName);
-            hostTest.setJarFile(new File(testCaseDir, mJarPath));
-            hostTest.setTestAppPath(testCaseDir.getAbsolutePath());
+            hostTest.setJarFileName(mJarPath);
             hostTest.setTests(filterTests(mTests, className, methodName));
             return hostTest;
         } else if (mIsSignatureTest) {
@@ -145,7 +144,7 @@
             // points to specialized instrumentation. Eventually this special case for signatureTest
             // can be removed, and it can be treated just like a normal InstrumentationTest
             Log.d(LOG_TAG, String.format("Creating signature test %s", mName));
-            InstrumentationTest instrTest = new InstrumentationTest();
+            InstrumentationApkTest instrTest = new InstrumentationApkTest();
             instrTest.setPackageName(mAppNameSpace);
             instrTest.setRunnerName("android.test.InstrumentationTestRunner");
             instrTest.setClassName(SIGNATURE_TEST_CLASS);
@@ -153,34 +152,22 @@
             // add signature test to list of known tests
             addTest(new TestIdentifier(SIGNATURE_TEST_CLASS, SIGNATURE_TEST_METHOD));
             // mName means 'apk file name' for instrumentation tests
-            File apkFile = new File(testCaseDir, String.format("%s.apk", mName));
-            if (!apkFile.exists()) {
-                Log.w(LOG_TAG, String.format("Could not find apk file %s",
-                        apkFile.getAbsolutePath()));
-                return null;
-            }
-            instrTest.setInstallFile(apkFile);
+            instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
             return instrTest;
         } else if (mIsReferenceAppTest) {
             // a reference app test is just a InstrumentationTest with one extra apk to install
-            InstrumentationAppTest instrTest = new InstrumentationAppTest();
-            File apkFile = new File(testCaseDir, String.format("%s.apk", mApkToTestName));
-            if (!apkFile.exists()) {
-                Log.w(LOG_TAG, String.format("Could not find apk file %s",
-                        apkFile.getAbsolutePath()));
-                return null;
-            }
-            instrTest.addInstallApp(apkFile, mPackageToTest);
-            return setInstrumentationTest(testCaseDir, className, methodName, instrTest);
+            InstrumentationApkTest instrTest = new InstrumentationApkTest();
+            instrTest.addInstallApk(String.format("%s.apk", mApkToTestName), mPackageToTest);
+            return setInstrumentationTest(className, methodName, instrTest);
         } else {
             Log.d(LOG_TAG, String.format("Creating instrumentation test for %s", mName));
-            InstrumentationTest instrTest = new InstrumentationTest();
-            return setInstrumentationTest(testCaseDir, className, methodName, instrTest);
+            InstrumentationApkTest instrTest = new InstrumentationApkTest();
+            return setInstrumentationTest(className, methodName, instrTest);
         }
     }
 
     /**
-     * Populates given {@link InstrumentationTest} with data from the package xml
+     * Populates given {@link InstrumentationApkTest} with data from the package xml
      *
      * @param testCaseDir
      * @param className
@@ -188,20 +175,18 @@
      * @param instrTest
      * @return the populated {@link InstrumentationTest} or <code>null</code>
      */
-    private InstrumentationTest setInstrumentationTest(File testCaseDir, String className,
-            String methodName, InstrumentationTest instrTest) {
+    private InstrumentationApkTest setInstrumentationTest(String className,
+            String methodName, InstrumentationApkTest instrTest) {
         instrTest.setPackageName(mAppNameSpace);
         instrTest.setRunnerName(mRunner);
         instrTest.setClassName(className);
         instrTest.setMethodName(methodName);
         // mName means 'apk file name' for instrumentation tests
-        File apkFile = new File(testCaseDir, String.format("%s.apk", mName));
-        if (!apkFile.exists()) {
-            Log.w(LOG_TAG, String.format("Could not find apk file %s",
-                    apkFile.getAbsolutePath()));
-            return null;
+        instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
+        if (mTests.size() > 1000) {
+            // TODO: hack, large test suites can take longer to collect tests, increase timeout
+            instrTest.setCollectsTestsShellTimeout(10*60*1000);
         }
-        instrTest.setInstallFile(apkFile);
         return instrTest;
     }
 
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/JarHostTestTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/JarHostTestTest.java
index 9a49b77..dfe4413 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/JarHostTestTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/JarHostTestTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.cts.tradefed.testtype;
 
+import com.android.cts.tradefed.build.StubCtsBuildHelper;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
@@ -22,7 +23,6 @@
 
 import org.easymock.EasyMock;
 
-import java.io.File;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -37,6 +37,8 @@
 
     private static final String RUN_NAME = "run";
     private JarHostTest mJarTest;
+    private StubCtsBuildHelper mStubBuildHelper;
+
 
     @Override
     protected void setUp() throws Exception {
@@ -48,6 +50,8 @@
                 return MockTest.class;
             }
         };
+        mStubBuildHelper = new StubCtsBuildHelper();
+        mJarTest.setBuildHelper(mStubBuildHelper);
     }
 
     public static class MockTest extends TestCase {
@@ -80,7 +84,7 @@
         listener.testRunEnded(EasyMock.anyLong(), EasyMock.eq(Collections.EMPTY_MAP));
         mJarTest.setTests(tests);
         mJarTest.setDevice(EasyMock.createMock(ITestDevice.class));
-        mJarTest.setJarFile(new File("fakefile"));
+        mJarTest.setJarFileName("fakefile");
         mJarTest.setRunName(RUN_NAME);
 
         EasyMock.replay(listener);
diff --git a/tools/utils/CollectAllTests.java b/tools/utils/CollectAllTests.java
index c443db2..883d70e 100644
--- a/tools/utils/CollectAllTests.java
+++ b/tools/utils/CollectAllTests.java
@@ -32,13 +32,17 @@
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
 
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
@@ -73,7 +77,6 @@
     private static String jarPath;
 
     private static Map<String,TestClass> testCases;
-    private static Set<String> failed = new HashSet<String>();
 
     private static class MyXMLGenerator extends XMLGenerator {
 
@@ -99,32 +102,30 @@
         }
     }
 
-    private static String OUTPUTFILE = "";
-    private static String MANIFESTFILE = "";
-    private static String TESTSUITECLASS = "";
+    private static String OUTPUTFILE;
+    private static String MANIFESTFILE;
+    private static String JARFILE;
+    private static String LIBCORE_EXPECTATION_DIR;
     private static String ANDROID_MAKE_FILE = "";
-    private static String LIBCORE_EXPECTATION_DIR = null;
-
-    private static Test TESTSUITE;
 
     static XMLGenerator xmlGenerator;
     private static ExpectationStore libcoreVogarExpectationStore;
     private static ExpectationStore ctsVogarExpectationStore;
 
     public static void main(String[] args) {
-        if (args.length > 2) {
+        if (args.length >= 3 && args.length <= 5) {
             OUTPUTFILE = args[0];
-            MANIFESTFILE = args [1];
-            TESTSUITECLASS = args[2];
-            if (args.length > 3) {
+            MANIFESTFILE = args[1];
+            JARFILE = args[2];
+            if (args.length >= 4) {
                 LIBCORE_EXPECTATION_DIR = args[3];
-            }
-            if (args.length > 4) {
-                ANDROID_MAKE_FILE = args[4];
+                if (args.length >= 5) {
+                    ANDROID_MAKE_FILE = args[4];
+                }
             }
         } else {
-            System.out.println("usage: \n" +
-                "\t... CollectAllTests <output-file> <manifest-file> <testsuite-class-name> <makefile-file> <expectation-dir>");
+            System.err.println("usage: CollectAllTests <output-file> <manifest-file> <jar-file>"
+                               + "[expectation-dir [makefile-file]]");
             System.exit(1);
         }
 
@@ -134,11 +135,12 @@
 
         Document manifest = null;
         try {
-            manifest = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new FileInputStream(MANIFESTFILE));
+            manifest = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
+                    new FileInputStream(MANIFESTFILE));
         } catch (Exception e) {
-            System.err.println("cannot open manifest");
+            System.err.println("cannot open manifest " + MANIFESTFILE);
             e.printStackTrace();
-            System.exit(1);;
+            System.exit(1);
         }
 
         Element documentElement = manifest.getDocumentElement();
@@ -150,73 +152,76 @@
         packageName = documentElement.getAttribute("package");
         target = getElementAttribute(documentElement, "instrumentation", "android:targetPackage");
 
-        Class<?> testClass = null;
-        try {
-            testClass = Class.forName(TESTSUITECLASS);
-        } catch (ClassNotFoundException e) {
-            System.err.println("test class not found");
-            e.printStackTrace();
-            System.exit(1);;
-        }
-
-        Method method = null;
-        try {
-            method = testClass.getMethod("suite", new Class<?>[0]);
-        } catch (SecurityException e) {
-            System.err.println("failed to get suite method");
-            e.printStackTrace();
-            System.exit(1);;
-        } catch (NoSuchMethodException e) {
-            System.err.println("failed to get suite method");
-            e.printStackTrace();
-            System.exit(1);;
-        }
-
-        try {
-            TESTSUITE = (Test) method.invoke(null, (Object[])null);
-        } catch (IllegalArgumentException e) {
-            System.err.println("failed to get suite method");
-            e.printStackTrace();
-            System.exit(1);;
-        } catch (IllegalAccessException e) {
-            System.err.println("failed to get suite method");
-            e.printStackTrace();
-            System.exit(1);;
-        } catch (InvocationTargetException e) {
-            System.err.println("failed to get suite method");
-            e.printStackTrace();
-            System.exit(1);;
-        }
-
         try {
             xmlGenerator = new MyXMLGenerator(OUTPUTFILE + ".xml");
         } catch (ParserConfigurationException e) {
-            System.err.println("Can't initialize XML Generator");
+            System.err.println("Can't initialize XML Generator " + OUTPUTFILE + ".xml");
             System.exit(1);
         }
 
         try {
-            libcoreVogarExpectationStore = VogarUtils.provideExpectationStore(LIBCORE_EXPECTATION_DIR);
+            libcoreVogarExpectationStore
+                    = VogarUtils.provideExpectationStore(LIBCORE_EXPECTATION_DIR);
             ctsVogarExpectationStore = VogarUtils.provideExpectationStore(CTS_EXPECTATION_DIR);
         } catch (IOException e) {
-            System.err.println("Can't initialize vogar expectation store");
+            System.err.println("Can't initialize vogar expectation store from "
+                               + LIBCORE_EXPECTATION_DIR);
             e.printStackTrace(System.err);
             System.exit(1);
         }
 
-        testCases = new LinkedHashMap<String, TestClass>();
-        CollectAllTests cat = new CollectAllTests();
-        cat.compose();
-
-        if (!failed.isEmpty()) {
-            System.err.println("The following classes have no default constructor");
-            for (Iterator<String> iterator = failed.iterator(); iterator.hasNext();) {
-                String type = iterator.next();
-                System.err.println(type);
-            }
+        JarFile jarFile = null;
+        try {
+            jarFile = new JarFile(JARFILE);
+        } catch (Exception e) {
+            System.err.println("cannot open jarfile " + JARFILE);
+            e.printStackTrace();
             System.exit(1);
         }
 
+        testCases = new LinkedHashMap<String, TestClass>();
+
+        Enumeration<JarEntry> jarEntries = jarFile.entries();
+        while (jarEntries.hasMoreElements()) {
+            JarEntry jarEntry = jarEntries.nextElement();
+            String name = jarEntry.getName();
+            if (!name.endsWith(".class")) {
+                continue;
+            }
+            String className
+                    = name.substring(0, name.length() - ".class".length()).replace('/', '.');
+            try {
+                Class<?> klass = Class.forName(className,
+                                               false,
+                                               CollectAllTests.class.getClassLoader());
+                if (!TestCase.class.isAssignableFrom(klass)) {
+                    continue;
+                }
+                if (Modifier.isAbstract(klass.getModifiers())) {
+                    continue;
+                }
+                if (!Modifier.isPublic(klass.getModifiers())) {
+                    continue;
+                }
+                try {
+                    klass.getConstructor(new Class<?>[] { String.class } );
+                    addToTests(klass.asSubclass(TestCase.class));
+                    continue;
+                } catch (NoSuchMethodException e) {
+                }
+                try {
+                    klass.getConstructor(new Class<?>[0]);
+                    addToTests(klass.asSubclass(TestCase.class));
+                    continue;
+                } catch (NoSuchMethodException e) {
+                }
+            } catch (ClassNotFoundException e) {
+                System.out.println("class not found " + className);
+                e.printStackTrace();
+                System.exit(1);
+            }
+        }
+
         for (Iterator<TestClass> iterator = testCases.values().iterator(); iterator.hasNext();) {
             TestClass type = iterator.next();
             xmlGenerator.addTestClass(type);
@@ -225,7 +230,7 @@
         try {
             xmlGenerator.dump();
         } catch (Exception e) {
-            System.err.println("cannot dump xml");
+            System.err.println("cannot dump xml to " + OUTPUTFILE + ".xml");
             e.printStackTrace();
             System.exit(1);
         }
@@ -261,7 +266,9 @@
         }
     }
 
-    private static String getElementAttribute(Element element, String elementName, String attributeName) {
+    private static String getElementAttribute(Element element,
+                                              String elementName,
+                                              String attributeName) {
         Element e = getElement(element, elementName);
         if (e != null) {
             return e.getAttribute(attributeName);
@@ -270,65 +277,32 @@
         }
     }
 
-    public void compose() {
-        TestRunner runner = new TestRunner() {
-            @Override
-            protected TestResult createTestResult() {
-                return new TestResult() {
-                    @Override
-                    protected void run(TestCase test) {
-                        addToTests(test);
-                    }
-                };
-            }
-
-            @Override
-            public TestResult doRun(Test test) {
-                return super.doRun(test);
-            }
-
-
-
-        };
-
-        runner.setPrinter(new ResultPrinter(System.out) {
-            @Override
-            protected void printFooter(TestResult result) {
-            }
-
-            @Override
-            protected void printHeader(long runTime) {
-            }
-        });
-        runner.doRun(TESTSUITE);
-    }
-
-    private String getKnownFailure(final Class<? extends TestCase> testClass,
+    private static String getKnownFailure(final Class<? extends TestCase> testClass,
             final String testName) {
         return getAnnotation(testClass, testName, KNOWN_FAILURE);
     }
 
-    private boolean isKnownFailure(final Class<? extends TestCase> testClass,
+    private static boolean isKnownFailure(final Class<? extends TestCase> testClass,
             final String testName) {
         return getAnnotation(testClass, testName, KNOWN_FAILURE) != null;
     }
 
-    private boolean isBrokenTest(final Class<? extends TestCase> testClass,
+    private static boolean isBrokenTest(final Class<? extends TestCase> testClass,
             final String testName)  {
         return getAnnotation(testClass, testName, BROKEN_TEST) != null;
     }
 
-    private boolean isSuppressed(final Class<? extends TestCase> testClass,
+    private static boolean isSuppressed(final Class<? extends TestCase> testClass,
             final String testName)  {
         return getAnnotation(testClass, testName, SUPPRESSED_TEST) != null;
     }
 
-    private boolean hasSideEffects(final Class<? extends TestCase> testClass,
+    private static boolean hasSideEffects(final Class<? extends TestCase> testClass,
             final String testName) {
         return getAnnotation(testClass, testName, SIDE_EFFECT) != null;
     }
 
-    private String getAnnotation(final Class<? extends TestCase> testClass,
+    private static String getAnnotation(final Class<? extends TestCase> testClass,
             final String testName, final String annotationName) {
         try {
             Method testMethod = testClass.getMethod(testName, (Class[])null);
@@ -360,40 +334,66 @@
         return null;
     }
 
-    private void addToTests(TestCase test) {
-
-        String testClassName = test.getClass().getName();
-        String testName = test.getName();
-        String knownFailure = getKnownFailure(test.getClass(), testName);
-
-        if (isKnownFailure(test.getClass(), testName)) {
-            System.out.println("ignoring known failure: " + test);
-            return;
-        } else if (isBrokenTest(test.getClass(), testName)) {
-            System.out.println("ignoring broken test: " + test);
-            return;
-        } else if (isSuppressed(test.getClass(), testName)) {
-            System.out.println("ignoring suppressed test: " + test);
-            return;
-        } else if (hasSideEffects(test.getClass(), testName)) {
-            System.out.println("ignoring test with side effects: " + test);
-            return;
-        } else if (VogarUtils.isVogarKnownFailure(libcoreVogarExpectationStore, test.getClass().getName(), testName)) {
-            System.out.println("ignoring libcore expectation known failure: " + test);
-            return;
-        } else if (VogarUtils.isVogarKnownFailure(ctsVogarExpectationStore, test.getClass().getName(), testName)) {
-            System.out.println("ignoring cts expectation known failure: " + test);
-            return;
-        }
-
-        if (!testName.startsWith("test")) {
-            try {
-                test.runBare();
-            } catch (Throwable e) {
-                e.printStackTrace();
-                return;
+    private static void addToTests(Class<? extends TestCase> test) {
+        Class testClass = test;
+        Set<String> testNames = new HashSet<String>();
+        while (TestCase.class.isAssignableFrom(testClass)) {
+            Method[] testMethods = testClass.getDeclaredMethods();
+            for (Method testMethod : testMethods) {
+                String testName = testMethod.getName();
+                if (testNames.contains(testName)) {
+                    continue;
+                }
+                if (!testName.startsWith("test")) {
+                    continue;
+                }
+                if (testMethod.getParameterTypes().length != 0) {
+                    continue;
+                }
+                if (!testMethod.getReturnType().equals(Void.TYPE)) {
+                    continue;
+                }
+                if (!Modifier.isPublic(testMethod.getModifiers())) {
+                    continue;
+                }
+                testNames.add(testName);
+                addToTests(test, testName);
             }
+            testClass = testClass.getSuperclass();
         }
+    }
+
+    private static void addToTests(Class<? extends TestCase> test, String testName) {
+
+        String testClassName = test.getName();
+        String knownFailure = getKnownFailure(test, testName);
+
+        if (isKnownFailure(test, testName)) {
+            System.out.println("ignoring known failure: " + test + "#" + testName);
+            return;
+        } else if (isBrokenTest(test, testName)) {
+            System.out.println("ignoring broken test: " + test + "#" + testName);
+            return;
+        } else if (isSuppressed(test, testName)) {
+            System.out.println("ignoring suppressed test: " + test + "#" + testName);
+            return;
+        } else if (hasSideEffects(test, testName)) {
+            System.out.println("ignoring test with side effects: " + test + "#" + testName);
+            return;
+        } else if (VogarUtils.isVogarKnownFailure(libcoreVogarExpectationStore,
+                                                  testClassName,
+                                                  testName)) {
+            System.out.println("ignoring libcore expectation known failure: " + test
+                               + "#" + testName);
+            return;
+        } else if (VogarUtils.isVogarKnownFailure(ctsVogarExpectationStore,
+                                                  testClassName,
+                                                  testName)) {
+            System.out.println("ignoring cts expectation known failure: " + test
+                               + "#" + testName);
+            return;
+        }
+
         TestClass testClass = null;
         if (testCases.containsKey(testClassName)) {
             testClass = testCases.get(testClassName);
@@ -403,13 +403,5 @@
         }
 
         testClass.mCases.add(new TestMethod(testName, "", "", knownFailure, false, false));
-
-        try {
-            test.getClass().getConstructor(new Class<?>[0]);
-        } catch (SecurityException e) {
-            failed.add(test.getClass().getName());
-        } catch (NoSuchMethodException e) {
-            failed.add(test.getClass().getName());
-        }
     }
 }
diff --git a/tools/vm-tests/src/util/build/DexBuildStep.java b/tools/vm-tests/src/util/build/DexBuildStep.java
index cc65af9..6aba51c 100644
--- a/tools/vm-tests/src/util/build/DexBuildStep.java
+++ b/tools/vm-tests/src/util/build/DexBuildStep.java
@@ -17,6 +17,7 @@
 package util.build;
 
 import com.android.dx.command.dexer.Main;
+import java.io.IOException;
 
 public class DexBuildStep extends BuildStep {
 
@@ -39,7 +40,13 @@
 
             args.outName = outputFile.fileName.getAbsolutePath();
 
-            int result = Main.run(args);
+            int result = 0;
+            try {
+                result = Main.run(args);
+            } catch (IOException e) {
+                e.printStackTrace();
+                return false;
+            }
 
             if (result == 0) {
                 if (deleteInputFileAfterBuild) {