am e3991bb8: am 2b16bb99: Merge "Fix LocationManagerTest#testExitProximity"

* commit 'e3991bb8ff9e69d964b97f2689b7978a43e41510':
  Fix LocationManagerTest#testExitProximity
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 589f155..60a8cf2 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -18,6 +18,7 @@
 	CtsExternalStorageApp \
 	CtsInstrumentationAppDiffCert \
 	CtsPermissionDeclareApp \
+	CtsPermissionDeclareAppCompat \
 	CtsSharedUidInstall \
 	CtsSharedUidInstallDiffCert \
 	CtsSimpleAppInstall \
@@ -47,14 +48,11 @@
 	$(cts_support_packages) \
 	$(cts_external_packages)
 
-# Temporarily blacklisted packages
-#   CtsWebkitSecurityTestCases \
-
 # Test packages that require an associated test package XML.
 cts_test_packages := \
 	CtsAccelerationTestCases \
-	CtsAccessibilityServiceTestCases \
 	CtsAccountManagerTestCases \
+	CtsAccessibilityServiceTestCases \
 	CtsAccessibilityTestCases \
 	CtsAdminTestCases \
 	CtsAnimationTestCases \
@@ -97,6 +95,7 @@
 	CtsUtilTestCases \
 	CtsViewTestCases \
 	CtsWebkitTestCases \
+	CtsWebkitSecurityTestCases \
 	CtsWidgetTestCases
 
 # All APKs that need to be scanned by the coverage utilities.
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 0898369..a8cb020 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.cts.verifier"
       android:versionCode="1"
-      android:versionName="4.1_r2">
+      android:versionName="1337">
 
     <!-- Using 10 for more complete NFC support... -->
     <uses-sdk android:minSdkVersion="10"></uses-sdk>
@@ -306,6 +306,7 @@
                  android:screenOrientation="landscape">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
 
diff --git a/build/test_package.mk b/build/test_package.mk
index e8d812b..071acee 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -19,6 +19,9 @@
 # Replace "include $(BUILD_PACKAGE)" with "include $(BUILD_CTS_PACKAGE)"
 #
 
+# Disable by default so "m cts" will work in emulator builds
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
 
 cts_package_apk := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).apk
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
index 23d353e..e42ac3b 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
@@ -84,6 +84,9 @@
     // testPermissionDiffCert constants
     private static final String DECLARE_PERMISSION_APK = "CtsPermissionDeclareApp.apk";
     private static final String DECLARE_PERMISSION_PKG = "com.android.cts.permissiondeclareapp";
+    private static final String DECLARE_PERMISSION_COMPAT_APK = "CtsPermissionDeclareAppCompat.apk";
+    private static final String DECLARE_PERMISSION_COMPAT_PKG = "com.android.cts.permissiondeclareappcompat";
+
     private static final String PERMISSION_DIFF_CERT_APK = "CtsUsePermissionDiffCert.apk";
     private static final String PERMISSION_DIFF_CERT_PKG =
         "com.android.cts.usespermissiondiffcertapp";
@@ -311,6 +314,7 @@
         try {
             // cleanup test app that might be installed from previous partial test run
             getDevice().uninstallPackage(DECLARE_PERMISSION_PKG);
+            getDevice().uninstallPackage(DECLARE_PERMISSION_COMPAT_PKG);
             getDevice().uninstallPackage(PERMISSION_DIFF_CERT_PKG);
 
             String installResult = getDevice().installPackage(
@@ -318,6 +322,11 @@
             assertNull(String.format("failed to install declare permission app. Reason: %s",
                     installResult), installResult);
 
+            installResult = getDevice().installPackage(
+                    getTestAppFile(DECLARE_PERMISSION_COMPAT_APK), false);
+            assertNull(String.format("failed to install declare permission compat app. Reason: %s",
+                    installResult), installResult);
+
             // the app will install, but will get error at runtime
             installResult = getDevice().installPackage(getTestAppFile(PERMISSION_DIFF_CERT_APK),
                     false);
@@ -329,6 +338,7 @@
         }
         finally {
             getDevice().uninstallPackage(DECLARE_PERMISSION_PKG);
+            getDevice().uninstallPackage(DECLARE_PERMISSION_COMPAT_PKG);
             getDevice().uninstallPackage(PERMISSION_DIFF_CERT_PKG);
         }
     }
diff --git a/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk b/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
index 6c31fd9..308992e 100644
--- a/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
@@ -27,4 +27,6 @@
 # although not strictly necessary, sign this app with different cert than CtsAppWithData
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk b/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
index ae14b7c..8bcb045 100644
--- a/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
@@ -26,4 +26,6 @@
 
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
index 3c687f1..91d6ccf 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
@@ -22,4 +22,6 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_PACKAGE_NAME := CtsExternalStorageApp
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
index 67b2246..268ac73 100644
--- a/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
@@ -27,4 +27,6 @@
 # sign this app with different cert than CtsTargetInstrumentationApp
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
index 41ddb64..938b325 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
@@ -27,4 +27,6 @@
 # sign this app with a different cert than CtsUsePermissionDiffCert
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/AndroidManifest.xml
index 00c996c..ad7a640 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/AndroidManifest.xml
@@ -41,7 +41,8 @@
         <provider android:name="PermissionContentProvider"
                 android:authorities="ctspermissionwithsignature"
                 android:readPermission="com.android.cts.permissionWithSignature"
-                android:writePermission="com.android.cts.permissionWithSignature">
+                android:writePermission="com.android.cts.permissionWithSignature"
+                android:exported="true">
         </provider>
 
         <!-- Need a way for another app to try to access the permission, but will
@@ -49,7 +50,8 @@
         <provider android:name="PermissionContentProviderGranting"
                 android:authorities="ctspermissionwithsignaturegranting"
                 android:readPermission="com.android.cts.permissionWithSignature"
-                android:writePermission="com.android.cts.permissionWithSignature">
+                android:writePermission="com.android.cts.permissionWithSignature"
+                android:exported="true">
             <grant-uri-permission android:pathPattern="/foo.*" />
             <grant-uri-permission android:pathPattern="/yes.*" />
         </provider>
@@ -68,12 +70,19 @@
             <grant-uri-permission android:pathPattern="/yes.*" />
         </provider>
 
+        <!-- An ambiguous content provider, where "exported" was not specified.
+             Nobody should get access to this. -->
+        <provider android:name="AmbiguousContentProvider"
+                android:authorities="ctsambiguousprovider">
+        </provider>
+
         <!-- Target for tests about how path permissions interact with granting
              URI permissions. -->
         <provider android:name="PermissionContentProviderPath"
                 android:authorities="ctspermissionwithsignaturepath"
                 android:readPermission="com.android.cts.permissionNotUsedWithSignature"
-                android:writePermission="com.android.cts.permissionNotUsedWithSignature">
+                android:writePermission="com.android.cts.permissionNotUsedWithSignature"
+                android:exported="true">
             <path-permission
                     android:pathPrefix="/foo"
                     android:readPermission="com.android.cts.permissionWithSignature"
@@ -88,7 +97,8 @@
         <!-- Target for tests that verify path permissions can restrict access
              when no default top-level permission. -->
         <provider android:name="PermissionContentProviderPathRestricting"
-                android:authorities="ctspermissionwithsignaturepathrestricting">
+                android:authorities="ctspermissionwithsignaturepathrestricting"
+                android:exported="true">
             <!-- Require signature permission to get into path. -->
             <path-permission
                     android:pathPrefix="/foo"
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/AmbiguousContentProvider.java b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/AmbiguousContentProvider.java
new file mode 100644
index 0000000..3536979
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/AmbiguousContentProvider.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.permissiondeclareapp;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+/**
+ * Empty content provider, manifest did not declare exported=true nor exported=false.
+ */
+public class AmbiguousContentProvider extends ContentProvider {
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        // do nothing
+        return 0;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return "got/theMIME";
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public boolean onCreate() {
+        return false;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection,
+            String[] selectionArgs, String sortOrder) {
+        return null;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection,
+            String[] selectionArgs) {
+        return 0;
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk
new file mode 100644
index 0000000..acdc20f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 16
+
+LOCAL_PACKAGE_NAME := CtsPermissionDeclareAppCompat
+
+# sign this app with a different cert than CtsUsePermissionDiffCert
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/AndroidManifest.xml
new file mode 100644
index 0000000..5bbf93f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.permissiondeclareappcompat">
+
+    <application>
+        <!--
+             This provider doesn't specify an android:exported line. Because we specify
+             LOCAL_SDK_VERSION:=16 in Android.mk, we preserve the old behavior of defaulting
+             android:exported="true".
+         -->
+        <provider android:name="AmbiguousContentProvider"
+                android:authorities="ctsambiguousprovidercompat">
+        </provider>
+
+    </application>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/src/com/android/cts/permissiondeclareappcompat/AmbiguousContentProvider.java b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/src/com/android/cts/permissiondeclareappcompat/AmbiguousContentProvider.java
new file mode 100644
index 0000000..8665b70
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/src/com/android/cts/permissiondeclareappcompat/AmbiguousContentProvider.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.permissiondeclareappcompat;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+/**
+ * Empty content provider, all permissions are enforced in manifest
+ */
+public class AmbiguousContentProvider extends ContentProvider {
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        // do nothing
+        return 0;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        return "got/theUnspecifiedMIME";
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public boolean onCreate() {
+        return false;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection,
+            String[] selectionArgs, String sortOrder) {
+        return null;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection,
+            String[] selectionArgs) {
+        return 0;
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk b/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
index f852c56..25ba1fe 100644
--- a/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
@@ -29,4 +29,6 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
index 3f0a6b6..a00b009 100644
--- a/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
@@ -27,4 +27,6 @@
 # sign this app with a different cert than CtsSharedUidInstall
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk b/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
index f7e0f27..3cd78cf 100644
--- a/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
@@ -27,4 +27,6 @@
 # sign this app with a different cert than CtsSimpleAppInstallDiffCert
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
index 06290be..5fbc910 100644
--- a/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
@@ -27,4 +27,6 @@
 # sign this app with a different cert than CtsSimpleAppInstall
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk b/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
index 532403c..cc87e29 100644
--- a/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
@@ -27,4 +27,6 @@
 # sign this app with different cert than CtsInstrumentationAppDiffCert
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
index 44ff270..acf9f6f 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
@@ -27,4 +27,6 @@
 # sign this app with a different cert than CtsPermissionDeclareApp
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
index 41cddf5..a6495a9 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
@@ -35,20 +35,23 @@
  * Accesses app cts/tests/appsecurity-tests/test-apps/PermissionDeclareApp/...
  */
 public class AccessPermissionWithDiffSigTest extends AndroidTestCase {
-    static final ComponentName GRANT_URI_PERM_COMP
+    private static final ComponentName GRANT_URI_PERM_COMP
             = new ComponentName("com.android.cts.permissiondeclareapp",
                     "com.android.cts.permissiondeclareapp.GrantUriPermission");
-    static final Uri PERM_URI = Uri.parse("content://ctspermissionwithsignature");
-    static final Uri PERM_URI_GRANTING = Uri.parse("content://ctspermissionwithsignaturegranting");
-    static final Uri PERM_URI_PATH = Uri.parse("content://ctspermissionwithsignaturepath");
-    static final Uri PERM_URI_PATH_RESTRICTING = Uri.parse(
+    private static final Uri PERM_URI = Uri.parse("content://ctspermissionwithsignature");
+    private static final Uri PERM_URI_GRANTING = Uri.parse("content://ctspermissionwithsignaturegranting");
+    private static final Uri PERM_URI_PATH = Uri.parse("content://ctspermissionwithsignaturepath");
+    private static final Uri PERM_URI_PATH_RESTRICTING = Uri.parse(
             "content://ctspermissionwithsignaturepathrestricting");
-    static final Uri PRIV_URI = Uri.parse("content://ctsprivateprovider");
-    static final Uri PRIV_URI_GRANTING = Uri.parse("content://ctsprivateprovidergranting");
+    private static final Uri PRIV_URI = Uri.parse("content://ctsprivateprovider");
+    private static final Uri PRIV_URI_GRANTING = Uri.parse("content://ctsprivateprovidergranting");
+    private static final String EXPECTED_MIME_TYPE = "got/theMIME";
 
-    static final String EXPECTED_MIME_TYPE = "got/theMIME";
-    
-    public void assertReadingContentUriNotAllowed(Uri uri, String msg) {
+    private static final Uri AMBIGUOUS_URI_COMPAT = Uri.parse("content://ctsambiguousprovidercompat");
+    private static final String EXPECTED_MIME_TYPE_AMBIGUOUS = "got/theUnspecifiedMIME";
+    private static final Uri AMBIGUOUS_URI = Uri.parse("content://ctsambiguousprovider");
+
+    private void assertReadingContentUriNotAllowed(Uri uri, String msg) {
         try {
             getContext().getContentResolver().query(uri, null, null, null, null);
             fail("expected SecurityException reading " + uri + ": " + msg);
@@ -57,15 +60,15 @@
         }
     }
 
-    public void assertReadingContentUriAllowed(Uri uri) {
+    private void assertReadingContentUriAllowed(Uri uri) {
         try {
             getContext().getContentResolver().query(uri, null, null, null, null);
         } catch (SecurityException e) {
-            fail("unexpected SecurityException reading " + uri);
+            fail("unexpected SecurityException reading " + uri + ": " + e.getMessage());
         }
     }
 
-    public void assertReadingClipNotAllowed(ClipData clip, String msg) {
+    private void assertReadingClipNotAllowed(ClipData clip, String msg) {
         for (int i=0; i<clip.getItemCount(); i++) {
             ClipData.Item item = clip.getItemAt(i);
             Uri uri = item.getUri();
@@ -85,7 +88,7 @@
         }
     }
 
-    public void assertWritingContentUriNotAllowed(Uri uri, String msg) {
+    private void assertWritingContentUriNotAllowed(Uri uri, String msg) {
         try {
             getContext().getContentResolver().insert(uri, new ContentValues());
             fail("expected SecurityException writing " + uri + ": " + msg);
@@ -94,15 +97,15 @@
         }
     }
 
-    public void assertWritingContentUriAllowed(Uri uri) {
+    private void assertWritingContentUriAllowed(Uri uri) {
         try {
             getContext().getContentResolver().insert(uri, new ContentValues());
         } catch (SecurityException e) {
-            fail("unexpected SecurityException writing " + uri);
+            fail("unexpected SecurityException writing " + uri + ": " + e.getMessage());
         }
     }
 
-    public void assertWritingClipNotAllowed(ClipData clip, String msg) {
+    private void assertWritingClipNotAllowed(ClipData clip, String msg) {
         for (int i=0; i<clip.getItemCount(); i++) {
             ClipData.Item item = clip.getItemAt(i);
             Uri uri = item.getUri();
@@ -145,8 +148,35 @@
      * since it is not exported from its app.
      */
     public void testReadProviderWhenPrivate() {
-        assertReadingContentUriNotAllowed(PRIV_URI,
-                "shouldn't read private provider");
+        assertReadingContentUriNotAllowed(PRIV_URI, "shouldn't read private provider");
+    }
+
+    /**
+     * Test that the ctsambiguousprovider content provider cannot be read,
+     * since it doesn't have an "exported=" line.
+     */
+    public void testReadProviderWhenAmbiguous() {
+        assertReadingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't read ambiguous provider");
+    }
+
+    /**
+     * Old App Compatibility Test
+     *
+     * Test that the ctsambiguousprovidercompat content provider can be read for older
+     * API versions, because it didn't specify either exported=true or exported=false.
+     */
+    public void testReadProviderWhenAmbiguousCompat() {
+        assertReadingContentUriAllowed(AMBIGUOUS_URI_COMPAT);
+    }
+
+    /**
+     * Old App Compatibility Test
+     *
+     * Test that the ctsambiguousprovidercompat content provider can be written for older
+     * API versions, because it didn't specify either exported=true or exported=false.
+     */
+    public void testWriteProviderWhenAmbiguousCompat() {
+        assertWritingContentUriAllowed(AMBIGUOUS_URI_COMPAT);
     }
 
     /**
@@ -154,16 +184,23 @@
      * since it is not exported from its app.
      */
     public void testWriteProviderWhenPrivate() {
-        assertWritingContentUriNotAllowed(PRIV_URI,
-                "shouldn't write private provider");
+        assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write private provider");
     }
 
-    public static ClipData makeSingleClipData(Uri uri) {
+    /**
+     * Test that the ctsambiguousprovider content provider cannot be written,
+     * since it doesn't have an exported= line.
+     */
+    public void testWriteProviderWhenAmbiguous() {
+        assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write ambiguous provider");
+    }
+
+    private static ClipData makeSingleClipData(Uri uri) {
         return new ClipData("foo", new String[] { "foo/bar" },
                 new ClipData.Item(uri));
     }
 
-    public static ClipData makeMultiClipData(Uri uri) {
+    private static ClipData makeMultiClipData(Uri uri) {
         Uri grantClip1Uri = Uri.withAppendedPath(uri, "clip1");
         Uri grantClip2Uri = Uri.withAppendedPath(uri, "clip2");
         Uri grantClip3Uri = Uri.withAppendedPath(uri, "clip3");
@@ -187,18 +224,18 @@
         return clip;
     }
 
-    public static Intent makeClipIntent(ClipData clip, int flags) {
+    private static Intent makeClipIntent(ClipData clip, int flags) {
         Intent intent = new Intent();
         intent.setClipData(clip);
         intent.addFlags(flags);
         return intent;
     }
 
-    public static Intent makeClipIntent(Uri uri, int flags) {
+    private static Intent makeClipIntent(Uri uri, int flags) {
         return makeClipIntent(makeMultiClipData(uri), flags);
     }
 
-    public void doTryGrantUriActivityPermissionToSelf(Uri uri, int mode) {
+    private void doTryGrantUriActivityPermissionToSelf(Uri uri, int mode) {
         Uri grantDataUri = Uri.withAppendedPath(uri, "data");
         Intent grantIntent = new Intent();
         grantIntent.setData(grantDataUri);
@@ -261,7 +298,7 @@
                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
     }
 
-    public void doTryGrantUriServicePermissionToSelf(Uri uri, int mode) {
+    private void doTryGrantUriServicePermissionToSelf(Uri uri, int mode) {
         Uri grantDataUri = Uri.withAppendedPath(uri, "data");
         Intent grantIntent = new Intent();
         grantIntent.setData(grantDataUri);
@@ -320,7 +357,7 @@
                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
     }
 
-    static class GrantResultReceiver extends BroadcastReceiver {
+    private static class GrantResultReceiver extends BroadcastReceiver {
         boolean mHaveResult = false;
         boolean mGoodResult = false;
         boolean mSucceeded = false;
@@ -389,7 +426,7 @@
         }
     }
 
-    void grantUriPermissionFail(Uri uri, int mode, boolean service) {
+    private void grantUriPermissionFail(Uri uri, int mode, boolean service) {
         Uri grantDataUri = Uri.withAppendedPath(uri, "data");
         Intent grantIntent = new Intent();
         grantIntent.setData(grantDataUri);
@@ -417,7 +454,7 @@
                 + " when should not");
     }
 
-    void doTestGrantUriPermissionFail(Uri uri) {
+    private void doTestGrantUriPermissionFail(Uri uri) {
         grantUriPermissionFail(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, false);
         grantUriPermissionFail(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
         grantUriPermissionFail(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
@@ -450,6 +487,14 @@
     }
 
     /**
+     * Test that the ctsambiguousprovider content provider can not grant
+     * URI permissions to others.
+     */
+    public void testGrantAmbiguousNonGrantingFail() {
+        doTestGrantUriPermissionFail(AMBIGUOUS_URI);
+    }
+
+    /**
      * Test that the ctsprivateprovidergranting content provider can not grant
      * URI permissions to paths outside of the grant tree
      */
@@ -458,7 +503,7 @@
         doTestGrantUriPermissionFail(Uri.withAppendedPath(PRIV_URI_GRANTING, "invalid"));
     }
 
-    void grantClipUriPermission(ClipData clip, int mode, boolean service) {
+    private void grantClipUriPermission(ClipData clip, int mode, boolean service) {
         Intent grantIntent = new Intent();
         if (clip.getItemCount() == 1) {
             grantIntent.setData(clip.getItemAt(0).getUri());
@@ -482,7 +527,7 @@
         getContext().sendBroadcast(intent);
     }
 
-    void assertReadingClipAllowed(ClipData clip) {
+    private void assertReadingClipAllowed(ClipData clip) {
         for (int i=0; i<clip.getItemCount(); i++) {
             ClipData.Item item = clip.getItemAt(i);
             Uri uri = item.getUri();
@@ -510,7 +555,7 @@
         }
     }
 
-    void doTestGrantActivityUriReadPermission(Uri uri, boolean useClip) {
+    private void doTestGrantActivityUriReadPermission(Uri uri, boolean useClip) {
         final Uri subUri = Uri.withAppendedPath(uri, "foo");
         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
@@ -598,7 +643,7 @@
         assertReadingClipNotAllowed(sub2Clip, "shouldn't read after losing granted URI");
     }
 
-    void assertWritingClipAllowed(ClipData clip) {
+    private void assertWritingClipAllowed(ClipData clip) {
         for (int i=0; i<clip.getItemCount(); i++) {
             ClipData.Item item = clip.getItemAt(i);
             Uri uri = item.getUri();
@@ -618,7 +663,7 @@
         }
     }
 
-    void doTestGrantActivityUriWritePermission(Uri uri, boolean useClip) {
+    private void doTestGrantActivityUriWritePermission(Uri uri, boolean useClip) {
         final Uri subUri = Uri.withAppendedPath(uri, "foo");
         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
@@ -833,7 +878,7 @@
         assertReadingClipNotAllowed(sub2Clip, "shouldn't read after losing granted URI");
     }
 
-    void doTestGrantServiceUriWritePermission(Uri uri, boolean useClip) {
+    private void doTestGrantServiceUriWritePermission(Uri uri, boolean useClip) {
         final Uri subUri = Uri.withAppendedPath(uri, "foo");
         final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
         final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
@@ -1069,7 +1114,7 @@
 
     public void testGetMimeTypePermission() {
         // Precondition: no current access.
-        assertWritingContentUriNotAllowed(PERM_URI, "shouldn't write when starting test");
+        assertReadingContentUriNotAllowed(PERM_URI, "shouldn't read when starting test");
         assertWritingContentUriNotAllowed(PERM_URI, "shouldn't write when starting test");
         
         // All apps should be able to get MIME type regardless of permission.
@@ -1078,10 +1123,32 @@
 
     public void testGetMimeTypePrivate() {
         // Precondition: no current access.
-        assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write when starting test");
+        assertReadingContentUriNotAllowed(PRIV_URI, "shouldn't read when starting test");
         assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write when starting test");
         
         // All apps should be able to get MIME type even if provider is private.
         assertEquals(getContext().getContentResolver().getType(PRIV_URI), EXPECTED_MIME_TYPE);
     }
+
+    public void testGetMimeTypeAmbiguous() {
+        // Precondition: no current access.
+        assertReadingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't read when starting test");
+        assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write when starting test");
+
+        // All apps should be able to get MIME type even if provider is private.
+        assertEquals(getContext().getContentResolver().getType(AMBIGUOUS_URI), EXPECTED_MIME_TYPE);
+    }
+
+    /**
+     * Old App Compatibility Test
+     *
+     * We should be able to access the mime type of a content provider of an older
+     * application, even if that application didn't explicitly declare either
+     * exported=true or exported=false
+     */
+    public void testGetMimeTypeAmbiguousCompat() {
+        // All apps should be able to get MIME type even if provider is private.
+        assertEquals(EXPECTED_MIME_TYPE_AMBIGUOUS,
+                getContext().getContentResolver().getType(AMBIGUOUS_URI_COMPAT));
+    }
 }
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
index bdb2887..9e056a9 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
@@ -22,4 +22,6 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 LOCAL_PACKAGE_NAME := CtsWriteExternalStorageApp
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk b/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
index 9365af3..f6543fb 100644
--- a/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
+++ b/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
@@ -26,4 +26,8 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk b/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
index 0d76f2d..29bf9d6 100644
--- a/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
+++ b/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
@@ -26,4 +26,8 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/tests/Android.mk b/tests/Android.mk
index 77340df..15705dd 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -36,6 +36,8 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctsutil ctstestserver ctstestrunner
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
 
 # Build the test APK using its own makefile, and any other CTS-related packages
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index f9999f4..590ee36 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -118,7 +118,8 @@
 
     <application android:label="Android TestCase"
                 android:icon="@drawable/size_48x48"
-                android:name="android.app.cts.MockApplication">
+                android:name="android.app.cts.MockApplication"
+                android:supportsRtl="true">
 
         <activity android:name="android.app.cts.ActionBarActivity" />
         <activity android:name="android.widget.cts.TwoLineListItemStubActivity"
@@ -243,6 +244,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.widget.cts.LayoutDirectionStubActivity"
+            android:label="LayoutDirectionStubActivity">
+            <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.widget.cts.ProgressBarStubActivity"
             android:label="ProgressBarStubActivity">
             <intent-filter>
diff --git a/tests/SignatureTest/Android.mk b/tests/SignatureTest/Android.mk
index 3ebab34..cc0d53c 100644
--- a/tests/SignatureTest/Android.mk
+++ b/tests/SignatureTest/Android.mk
@@ -19,6 +19,8 @@
 LOCAL_MODULE_TAGS := optional
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+# and because it is in data, do not strip classes.dex
+LOCAL_DEX_PREOPT := false
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/acceleration/Android.mk b/tests/acceleration/Android.mk
index 6e30f59..bb6b89f 100644
--- a/tests/acceleration/Android.mk
+++ b/tests/acceleration/Android.mk
@@ -20,6 +20,8 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+LOCAL_DEX_PREOPT := false
+
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/accessibility/Android.mk b/tests/accessibility/Android.mk
index 2ffe162..43fa291 100644
--- a/tests/accessibility/Android.mk
+++ b/tests/accessibility/Android.mk
@@ -24,4 +24,8 @@
 
 LOCAL_SDK_VERSION := current
 
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/tests/accessibilityservice/Android.mk b/tests/accessibilityservice/Android.mk
index 50fe6b0..f9fec93 100644
--- a/tests/accessibilityservice/Android.mk
+++ b/tests/accessibilityservice/Android.mk
@@ -20,6 +20,8 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+LOCAL_DEX_PREOPT := false
+
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java b/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
index 6dce943..d992839 100644
--- a/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
+++ b/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
@@ -119,16 +119,6 @@
              */
             private Class<?> lastClass;
 
-            /**
-             * The minimum time we expect a test to take.
-             */
-            private static final int MINIMUM_TIME = 100;
-
-            /**
-             * The start time of our current test in System.currentTimeMillis().
-             */
-            private long startTime;
-
             @Override
             public void startTest(Test test) {
                 if (test.getClass() != lastClass) {
@@ -140,30 +130,12 @@
                         test.getClass().getClassLoader());
 
                 mEnvironment.reset();
-
-                startTime = System.currentTimeMillis();
             }
 
             @Override
             public void endTest(Test test) {
                 if (test instanceof TestCase) {
                     cleanup((TestCase)test);
-
-                    /*
-                     * Make sure all tests take at least MINIMUM_TIME to
-                     * complete. If they don't, we wait a bit. The Cupcake
-                     * Binder can't handle too many operations in a very
-                     * short time, which causes headache for the CTS.
-                     */
-                    long timeTaken = System.currentTimeMillis() - startTime;
-
-                    if (timeTaken < MINIMUM_TIME) {
-                        try {
-                            Thread.sleep(MINIMUM_TIME - timeTaken);
-                        } catch (InterruptedException ignored) {
-                            // We don't care.
-                        }
-                    }
                 }
             }
 
diff --git a/tests/deviceadmin/Android.mk b/tests/deviceadmin/Android.mk
index 7322ad5..c354599 100644
--- a/tests/deviceadmin/Android.mk
+++ b/tests/deviceadmin/Android.mk
@@ -28,4 +28,6 @@
 
 LOCAL_SDK_VERSION := current
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 9228564..0d4f101 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -1,77 +1,2 @@
 [
-  {
-    names: [
-      "com.android.cts.appsecurity.AppSecurityTests#testReadExternalStorageEnforced",
-      "com.android.cts.appsecurity.AppSecurityTests#testReadExternalStorageUnenforced"
-    ],
-    bug: 6721185
-  },
-  {
-    name: "android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverText",
-    bug: 6468754
-  },
-  {
-    name: "android.accessibilityservice.cts.AccessibilityWindowQueryTest#testPerformGlobalActionBack",
-    bug: 6365037
-  },
-  {
-    names: [
-      "android.media.cts.StreamingMediaPlayerTest#testRTSP_MPEG4SP_AAC_Video1",
-      "android.media.cts.StreamingMediaPlayerTest#testRTSP_MPEG4SP_AAC_Video2"
-    ],
-    bug: 6422606
-  },
-  {
-    names: [
-      "android.media.cts.StreamingMediaPlayerTest#testRTSP_H263_AMR_Video1",
-      "android.media.cts.StreamingMediaPlayerTest#testRTSP_H263_AMR_Video2"
-    ],
-    bug: 6216077
-  },
-  {
-    names: [
-      "android.media.cts.StreamingMediaPlayerTest#testRTSP_H264Base_AAC_Video1",
-      "android.media.cts.StreamingMediaPlayerTest#testRTSP_H264Base_AAC_Video2"
-    ],
-    bug: 6215719
-  },
-  {
-    name: "android.nativemedia.sl.SLObjectCreationTest#testAudioRecorderCreation",
-    bug: 4970300
-  },
-  {
-    name: "android.opengl.cts.AttachShaderTest#test_glAttachedShaders_invalidshader",
-    bug: 6404341
-  },
-  {
-    name: "android.openglperf.cts.GlVboPerfTest#testVboWithVaryingIndexBufferNumbers",
-    bug: 5898262
-  },
-  {
-    name: "android.text.cts.AndroidCharacterTest#testMirror",
-    bug: 4371654
-  },
-  {
-    name: "android.text.format.cts.DateUtilsTest#test2038",
-    bug: 6293653
-  },
-  {
-    description: "flakey libcore tests",
-    names: [
-      "libcore.java.net.ConcurrentCloseTest",
-      "libcore.java.net.SocketTest#testAvailable",
-      "libcore.java.net.URLConnectionTest",
-      "libcore.java.util.prefs.OldAbstractPreferencesTest",
-      "libcore.java.util.prefs.OldPreferencesTest#testAddNodeChangeListener",
-      "libcore.net.http.HttpResponseCacheTest#testClientPrematureDisconnectWithChunkedEncoding",
-      "org.apache.harmony.luni.tests.java.net.URLConnectionTest",
-      "org.apache.harmony.xnet.provider.jsse.NativeCryptoTest#test_SSL_do_handshake_server_timeout"
-    ]
-  },
-  {
-    description: "MediaPlayerFlakyNetworkTest tests",
-    name: "android.media.cts.MediaPlayerFlakyNetworkTest",
-    bug: 6782035
-  }
 ]
-
diff --git a/tests/res/layout/layoutdirection_layout.xml b/tests/res/layout/layoutdirection_layout.xml
new file mode 100644
index 0000000..e506dc1
--- /dev/null
+++ b/tests/res/layout/layoutdirection_layout.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2012 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:orientation="vertical">
+
+    <LinearLayout android:id="@+id/layout_linearlayout_ltr"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:layoutDirection="ltr">
+
+        <LinearLayout android:id="@+id/layout_linearlayout_ltr_child_1"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="ltr" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_ltr_child_2"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="rtl" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_ltr_child_3"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="inherit" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_ltr_child_4"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="locale" />
+
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/layout_linearlayout_rtl"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:layoutDirection="rtl">
+
+        <LinearLayout android:id="@+id/layout_linearlayout_rtl_child_1"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="ltr" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_rtl_child_2"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="rtl" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_rtl_child_3"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="inherit" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_rtl_child_4"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="locale" />
+
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/layout_linearlayout_locale"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:layoutDirection="locale">
+
+        <LinearLayout android:id="@+id/layout_linearlayout_locale_child_1"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="ltr" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_locale_child_2"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="rtl" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_locale_child_3"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="inherit" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_locale_child_4"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="locale" />
+
+    </LinearLayout>
+
+    <LinearLayout android:id="@+id/layout_linearlayout_inherit"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:layoutDirection="inherit">
+
+        <LinearLayout android:id="@+id/layout_linearlayout_inherit_child_1"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="ltr" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_inherit_child_2"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="rtl" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_inherit_child_3"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="inherit" />
+
+        <LinearLayout android:id="@+id/layout_linearlayout_inherit_child_4"
+                      android:layout_width="wrap_content"
+                      android:layout_height="wrap_content"
+                      android:layoutDirection="locale" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/tests/res/layout/relative_layout.xml b/tests/res/layout/relative_layout.xml
index 669e86e..db4b2e8 100644
--- a/tests/res/layout/relative_layout.xml
+++ b/tests/res/layout/relative_layout.xml
@@ -162,4 +162,97 @@
         android:layout_height="match_parent"
         android:prompt="@string/text_view_hello"/>
 
+    <RelativeLayout
+            android:id="@+id/relative_sublayout_attrs_2"
+            android:background="@drawable/blue"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+
+        <!-- view21, centered within its parent. -->
+        <TextView
+                android:id="@+id/relative_view21"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerInParent="true"
+                android:text="@string/relative_view1"/>
+
+        <!-- view22, below view1 and has same start position with view21. -->
+        <TextView
+                android:id="@+id/relative_view22"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/relative_view21"
+                android:layout_alignStart="@id/relative_view21"
+                android:text="@string/relative_view2"/>
+
+        <!-- view23, has same top position with view21 and same bottom position with view22,
+             and on the end of view1. -->
+        <TextView
+                android:id="@+id/relative_view23"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignTop="@id/relative_view21"
+                android:layout_alignBottom="@id/relative_view22"
+                android:layout_toEndOf="@id/relative_view21"
+                android:text="@string/relative_view3"/>
+
+        <!-- view24, has same end position with view23 and above view23. -->
+        <TextView
+                android:id="@+id/relative_view24"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignEnd="@id/relative_view23"
+                android:layout_above="@id/relative_view23"
+                android:text="@string/relative_view4"/>
+
+        <!-- view25 goes on the start-bottom -->
+        <TextView
+                android:id="@+id/relative_view25"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentBottom="true"
+                android:layout_alignParentStart="true"
+                android:text="@string/relative_view5"/>
+
+        <!-- view26 goes on the top-end -->
+        <TextView
+                android:id="@+id/relative_view26"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentTop="true"
+                android:layout_alignParentEnd="true"
+                android:text="@string/relative_view6"/>
+
+        <!-- view27, has same baseline with view26 and centered horizontally within its parent. -->
+        <TextView
+                android:id="@+id/relative_view27"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignBaseline="@id/relative_view26"
+                android:layout_centerHorizontal="true"
+                android:text="@string/relative_view7"/>
+
+        <!-- view28, centered vertically within its parent and on the start of view21. -->
+        <TextView
+                android:id="@+id/relative_view28"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toStartOf="@id/relative_view21"
+                android:layout_centerVertical="true"
+                android:text="@string/relative_view8"/>
+
+        <!-- view29, has same top and bottom position with view23 and same start position
+             with its parent. -->
+        <TextView
+                android:id="@+id/relative_view29"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignStart="@id/gravity_bottom"
+                android:layout_alignTop="@id/relative_view23"
+                android:layout_alignBottom="@id/relative_view23"
+                android:layout_alignWithParentIfMissing="true"
+                android:text="@string/relative_view9"/>
+
+    </RelativeLayout>
+
 </RelativeLayout>
diff --git a/tests/src/android/widget/cts/LayoutDirectionStubActivity.java b/tests/src/android/widget/cts/LayoutDirectionStubActivity.java
new file mode 100644
index 0000000..66f24f74
--- /dev/null
+++ b/tests/src/android/widget/cts/LayoutDirectionStubActivity.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import com.android.cts.stub.R;
+
+/**
+ * A minimal application for layout direction test.
+ */
+public class LayoutDirectionStubActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.layoutdirection_layout);
+    }
+}
diff --git a/tests/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml b/tests/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml
index 383f209..cb3d153 100644
--- a/tests/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml
+++ b/tests/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml
@@ -20,6 +20,7 @@
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:orientation="horizontal"
+          android:layoutDirection="ltr"
           android:contentDescription="@string/firstLinearLayout" >
 
           <TextView
@@ -55,6 +56,7 @@
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:orientation="horizontal"
+          android:layoutDirection="rtl"
           android:contentDescription="@string/secondLinearLayout"
           android:clickable="true"
           android:importantForAccessibility="no" >
diff --git a/tests/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml b/tests/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
index 26f60bf..fe420bc 100644
--- a/tests/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
+++ b/tests/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
@@ -4,6 +4,7 @@
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="vertical"
+    android:layoutDirection="rtl"
     android:importantForAccessibility="yes"
     android:contentDescription="@string/rootLinearLayout">
 
@@ -20,6 +21,7 @@
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:orientation="horizontal"
+          android:layoutDirection="ltr"
           android:importantForAccessibility="no"
           android:contentDescription="@string/firstLinearLayout" >
 
@@ -57,6 +59,7 @@
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:orientation="horizontal"
+          android:layoutDirection="rtl"
           android:contentDescription="@string/secondLinearLayout"
           android:clickable="true"
           android:importantForAccessibility="no" >
diff --git a/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
index 71945ac..f8f1f43 100644
--- a/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
+++ b/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
@@ -20,7 +20,6 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
-import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.Interpolator;
@@ -250,5 +249,3 @@
         this.runTestOnUiThread(mAnimationRunnable);
     }
 }
-
-
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
index e8e32ee..e64da89 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
@@ -31,8 +31,8 @@
  * BluetoothAdapter}.
  */
 public class BasicAdapterTest extends AndroidTestCase {
-    private static final int DISABLE_TIMEOUT = 60000; // ms timeout for BT disable
-    private static final int ENABLE_TIMEOUT = 60000;  // ms timeout for BT enable
+    private static final int DISABLE_TIMEOUT = 5000;  // ms timeout for BT disable
+    private static final int ENABLE_TIMEOUT = 10000;  // ms timeout for BT enable
     private static final int POLL_TIME = 400;         // ms to poll BT state
 
     private boolean mHasBluetooth;
@@ -227,13 +227,12 @@
             return;
         }
 
+        assertEquals(BluetoothAdapter.STATE_ON, adapter.getState());
+        assertTrue(adapter.isEnabled());
         adapter.disable();
         for (int i=0; i<DISABLE_TIMEOUT/POLL_TIME; i++) {
             sleep(POLL_TIME);
             switch (adapter.getState()) {
-            case BluetoothAdapter.STATE_ON:
-                assertTrue(adapter.isEnabled());
-                continue;
             case BluetoothAdapter.STATE_OFF:
                 assertFalse(adapter.isEnabled());
                 return;
@@ -256,13 +255,12 @@
             return;
         }
 
+        assertEquals(BluetoothAdapter.STATE_OFF, adapter.getState());
+        assertFalse(adapter.isEnabled());
         adapter.enable();
         for (int i=0; i<ENABLE_TIMEOUT/POLL_TIME; i++) {
             sleep(POLL_TIME);
             switch (adapter.getState()) {
-            case BluetoothAdapter.STATE_OFF:
-                assertFalse(adapter.isEnabled());
-                continue;
             case BluetoothAdapter.STATE_ON:
                 assertTrue(adapter.isEnabled());
                 return;
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index bc9a822..75e90cf 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -535,6 +535,41 @@
         assertEquals(Align.RIGHT, p.getTextAlign());
     }
 
+    public void testAccessTextLocale() {
+        Paint p = new Paint();
+
+        final Locale defaultLocale = Locale.getDefault();
+
+        // Check default
+        assertEquals(defaultLocale, p.getTextLocale());
+
+        // Check setter / getter
+        p.setTextLocale(Locale.US);
+        assertEquals(Locale.US, p.getTextLocale());
+
+        p.setTextLocale(Locale.CHINESE);
+        assertEquals(Locale.CHINESE, p.getTextLocale());
+
+        p.setTextLocale(Locale.JAPANESE);
+        assertEquals(Locale.JAPANESE, p.getTextLocale());
+
+        p.setTextLocale(Locale.KOREAN);
+        assertEquals(Locale.KOREAN, p.getTextLocale());
+
+        // Check reverting back to default
+        p.setTextLocale(defaultLocale);
+        assertEquals(defaultLocale, p.getTextLocale());
+
+        // Check that we cannot pass a null locale
+        try {
+            p.setTextLocale(null);
+            assertFalse(true);
+        }
+        catch (IllegalArgumentException iae) {
+            // OK !!
+        }
+    }
+
     public void testGetFillPath() {
         Paint p = new Paint();
         Path path1 = new Path();
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
index 33d81f3..5af5607 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
@@ -397,7 +397,7 @@
         }
     }
 
-    private class MockCallback implements Drawable.Callback2 {
+    private class MockCallback implements Drawable.Callback {
         private Drawable mInvalidateDrawable;
         private Drawable mScheduleDrawable;
         private Runnable mRunnable;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
index d2c2244..0672db6 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
@@ -943,7 +943,7 @@
         }
     }
 
-    private class MockCallBack implements Drawable.Callback2 {
+    private class MockCallBack implements Drawable.Callback {
         private boolean mCalledInvalidateDrawable;
 
         private boolean mCalledScheduleDrawable;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
index f14f59f..df29211 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
@@ -567,17 +567,6 @@
         assertSame(mockDrawable, mockDrawable.mutate());
     }
 
-    public void getResolvedLayoutDirectionSelf() {
-        MockDrawable mockDrawable = new MockDrawable();
-        MockCallback mockCallback = new MockCallback(1);
-        mockDrawable.setCallback(mockCallback);
-        assertEquals(1, mockDrawable.getResolvedLayoutDirectionSelf());
-
-        mockCallback = new MockCallback(0);
-        mockDrawable.setCallback(mockCallback);
-        assertEquals(0, mockDrawable.getResolvedLayoutDirectionSelf());
-    }
-
     private static class MockDrawable extends Drawable {
         private ColorFilter mColorFilter;
 
@@ -612,20 +601,13 @@
         }
     }
 
-    private static class MockCallback implements Drawable.Callback2 {
+    private static class MockCallback implements Drawable.Callback {
         private Drawable mInvalidateDrawable;
         private Drawable mScheduleDrawable;
         private Runnable mRunnable;
         private long mWhen;
-        private int mLayoutDirection;
 
         public MockCallback() {
-            // 0 for LTR layout direction
-            this(0);
-        }
-
-        public MockCallback(int direction) {
-            mLayoutDirection = direction;
         }
 
         public Drawable getInvalidateDrawable() {
@@ -658,9 +640,5 @@
             mScheduleDrawable = who;
             mRunnable = what;
         }
-
-        public int getResolvedLayoutDirection(Drawable who) {
-            return mLayoutDirection;
-        }
     }
 }
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
index bf688d2..4e4648f 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
@@ -335,7 +335,7 @@
         assertFalse(cb.hasCalledUnschedule());
     }
 
-    private static class MockCallback implements Drawable.Callback2 {
+    private static class MockCallback implements Drawable.Callback {
         private boolean mCalledInvalidate;
         private boolean mCalledSchedule;
         private boolean mCalledUnschedule;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java
index 75838e0..a3398f6 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java
@@ -231,7 +231,7 @@
         assertEquals(50, ((BitmapDrawable) d3.getDrawable()).getPaint().getAlpha());
     }
 
-    private static class MockCallback implements Drawable.Callback2 {
+    private static class MockCallback implements Drawable.Callback {
         private boolean mCalledInvalidate;
         private boolean mCalledSchedule;
         private boolean mCalledUnschedule;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
index 305f32d..e0cd2ee 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
@@ -114,7 +114,7 @@
         assertFalse(cb.hasCalledUnschedule());
     }
 
-    private static class MockCallback implements Drawable.Callback2 {
+    private static class MockCallback implements Drawable.Callback {
         private boolean mCalledInvalidate;
         private boolean mCalledSchedule;
         private boolean mCalledUnschedule;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java
index aeb21cf..25b08d5 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java
@@ -242,7 +242,7 @@
         }
     }
 
-    private class MockCallBack implements Drawable.Callback2 {
+    private class MockCallBack implements Drawable.Callback {
         private boolean mHasCalledInvalidateDrawable;
 
         public boolean hasCalledInvalidateDrawable() {
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
index d0a2bf0..440d054 100755
--- a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
@@ -2754,4 +2754,63 @@
         }
         terminateMessageLooper();
     }
+
+    public void testPreviewCallbackWithPicture() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testPreviewCallbackWithPictureByCamera(id);
+        }
+    }
+
+    private void testPreviewCallbackWithPictureByCamera(int cameraId)
+            throws Exception {
+        initializeMessageLooper(cameraId);
+
+        SimplePreviewStreamCb callback = new SimplePreviewStreamCb(1);
+        mCamera.setPreviewCallback(callback);
+
+        Log.v(TAG, "Starting preview");
+        mCamera.startPreview();
+
+        // Wait until callbacks are flowing
+        for (int i = 0; i < 30; i++) {
+            assertTrue("testPreviewCallbackWithPicture: Not receiving preview callbacks!",
+                    mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE ) );
+            mPreviewDone.close();
+        }
+
+        // Now take a picture
+        Log.v(TAG, "Taking picture now");
+
+        Size pictureSize = mCamera.getParameters().getPictureSize();
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback,
+                mJpegPictureCallback);
+
+        waitForSnapshotDone();
+
+        assertTrue("Shutter callback not received", mShutterCallbackResult);
+        assertTrue("Raw picture callback not received", mRawPictureCallbackResult);
+        assertTrue("Jpeg picture callback not received", mJpegPictureCallbackResult);
+        assertNotNull(mJpegData);
+        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
+        bmpOptions.inJustDecodeBounds = true;
+        BitmapFactory.decodeByteArray(mJpegData, 0, mJpegData.length, bmpOptions);
+        assertEquals(pictureSize.width, bmpOptions.outWidth);
+        assertEquals(pictureSize.height, bmpOptions.outHeight);
+
+        // Restart preview, confirm callbacks still happen
+        Log.v(TAG, "Restarting preview");
+        mCamera.startPreview();
+
+        for (int i = 0; i < 30; i++) {
+            assertTrue("testPreviewCallbackWithPicture: Not receiving preview callbacks!",
+                    mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE ) );
+            mPreviewDone.close();
+        }
+
+        mCamera.stopPreview();
+
+        terminateMessageLooper();
+    }
 }
diff --git a/tests/tests/holo/res/drawable-hdpi/display_info.png b/tests/tests/holo/res/drawable-hdpi/display_info.png
deleted file mode 100644
index 10b3950..0000000
--- a/tests/tests/holo/res/drawable-hdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-land-hdpi/display_info.png b/tests/tests/holo/res/drawable-land-hdpi/display_info.png
deleted file mode 100644
index a665018..0000000
--- a/tests/tests/holo/res/drawable-land-hdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-land-ldpi/display_info.png b/tests/tests/holo/res/drawable-land-ldpi/display_info.png
deleted file mode 100644
index 64c8f3a..0000000
--- a/tests/tests/holo/res/drawable-land-ldpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-land-mdpi/display_info.png b/tests/tests/holo/res/drawable-land-mdpi/display_info.png
deleted file mode 100644
index f3e6765..0000000
--- a/tests/tests/holo/res/drawable-land-mdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-land-tvdpi/display_info.png b/tests/tests/holo/res/drawable-land-tvdpi/display_info.png
deleted file mode 100644
index 99de970..0000000
--- a/tests/tests/holo/res/drawable-land-tvdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-land-xhdpi/display_info.png b/tests/tests/holo/res/drawable-land-xhdpi/display_info.png
deleted file mode 100644
index 4c0c2b4..0000000
--- a/tests/tests/holo/res/drawable-land-xhdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/display_info.png b/tests/tests/holo/res/drawable-ldpi/display_info.png
deleted file mode 100644
index af1fda5..0000000
--- a/tests/tests/holo/res/drawable-ldpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/display_info.png b/tests/tests/holo/res/drawable-mdpi/display_info.png
deleted file mode 100644
index 4378b14..0000000
--- a/tests/tests/holo/res/drawable-mdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-hdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-hdpi/display_info.png
deleted file mode 100644
index 1e61b19..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-hdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-land-hdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-land-hdpi/display_info.png
deleted file mode 100644
index 123440e..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-land-hdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-land-ldpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-land-ldpi/display_info.png
deleted file mode 100644
index 7b8a0ad..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-land-ldpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-land-mdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-land-mdpi/display_info.png
deleted file mode 100644
index e285898..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-land-mdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-land-tvdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-land-tvdpi/display_info.png
deleted file mode 100644
index af4eaaa8..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-land-tvdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-land-xhdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-land-xhdpi/display_info.png
deleted file mode 100644
index 995af67..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-land-xhdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-ldpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-ldpi/display_info.png
deleted file mode 100644
index 4d9d810..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-ldpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-mdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-mdpi/display_info.png
deleted file mode 100644
index b875d76..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-mdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-tvdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-tvdpi/display_info.png
deleted file mode 100644
index 6db0c61..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-tvdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-xhdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-xhdpi/display_info.png
deleted file mode 100644
index 0ebb8c7..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-xhdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/display_info.png b/tests/tests/holo/res/drawable-tvdpi/display_info.png
deleted file mode 100644
index d9825fb..0000000
--- a/tests/tests/holo/res/drawable-tvdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/display_info.png b/tests/tests/holo/res/drawable-xhdpi/display_info.png
deleted file mode 100644
index 585af2f..0000000
--- a/tests/tests/holo/res/drawable-xhdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/layout/display_info.xml b/tests/tests/holo/res/layout/display_info.xml
index 9804b8c..130ce1f 100644
--- a/tests/tests/holo/res/layout/display_info.xml
+++ b/tests/tests/holo/res/layout/display_info.xml
@@ -13,20 +13,8 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    >
-    <ImageView
-        android:src="@drawable/display_info"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        />
-    <TextView 
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/text"
         android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
+        android:layout_height="fill_parent"
         />
-</LinearLayout>
-
diff --git a/tests/tests/holo/res/values/strings.xml b/tests/tests/holo/res/values/strings.xml
index d2f6fd6..5eb7d82 100644
--- a/tests/tests/holo/res/values/strings.xml
+++ b/tests/tests/holo/res/values/strings.xml
@@ -24,7 +24,7 @@
     <string name="task_clear_diff_bitmaps">Clear Diff Bitmaps</string>
 
     <string name="display_info">Display Info</string>
-    <string name="display_info_text">Density DPI: %1$d\nDensity Bucket: %2$s\nWidth DP: %3$d\nHeight DP: %4$d</string>
+    <string name="display_info_text">Density DPI: %1$d\nDensity Bucket: %2$s</string>
 
     <string name="pick_theme">Pick Theme</string>
     <string name="pick_layout">Pick Layout</string>
diff --git a/tests/tests/holo/src/android/holo/cts/DisplayInfoActivity.java b/tests/tests/holo/src/android/holo/cts/DisplayInfoActivity.java
index bdd7925..a11179a 100644
--- a/tests/tests/holo/src/android/holo/cts/DisplayInfoActivity.java
+++ b/tests/tests/holo/src/android/holo/cts/DisplayInfoActivity.java
@@ -37,13 +37,9 @@
         DisplayMetrics metrics = new DisplayMetrics();
         display.getMetrics(metrics);
 
-        DisplayMetrics dm = getResources().getDisplayMetrics();
-        int width = Math.round(dm.widthPixels / dm.density);
-        int height = Math.round(dm.heightPixels / dm.density);
-
         TextView text = (TextView) findViewById(R.id.text);
         text.setText(getString(R.string.display_info_text, metrics.densityDpi,
-                getScreenDensityBucket(metrics), width, height));
+                getScreenDensityBucket(metrics)));
     }
 
     private String getScreenDensityBucket(DisplayMetrics metrics) {
diff --git a/tests/tests/location/src/android/location/cts/LocationManagerTest.java b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
index 46e777f..008960e 100755
--- a/tests/tests/location/src/android/location/cts/LocationManagerTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
@@ -36,7 +36,6 @@
 import android.provider.Settings;
 import android.test.InstrumentationTestCase;
 
-import java.lang.Thread;
 import java.util.List;
 import java.lang.Thread;
 
@@ -608,9 +607,6 @@
 
         // now update to trigger exit proximity proximity
         mIntentReceiver.clearReceivedIntents();
-
-        // delay 2 seconds since location update in less than 1s will be neglected.
-        Thread.sleep(2000);
         updateLocation(20, 20);
         waitForReceiveBroadcast();
         assertProximityType(false);
diff --git a/tests/tests/media/res/raw/test_subtitle1_srt.3gp b/tests/tests/media/res/raw/test_subtitle1_srt.3gp
new file mode 100644
index 0000000..8dbc240
--- /dev/null
+++ b/tests/tests/media/res/raw/test_subtitle1_srt.3gp
@@ -0,0 +1,39 @@
+1
+00:00:0,000 --> 00:00:0,500
+2:0000
+
+2
+00:00:1,000 --> 00:00:1,500
+2:1000
+
+3
+00:00:2,000 --> 00:00:2,500
+2:2000
+
+4
+00:00:3,000 --> 00:00:3,500
+2:3000
+
+5
+00:00:4,000 --> 00:00:4,500
+2:4000
+
+6
+00:00:5,000 --> 00:00:5,500
+2:5000
+
+7
+00:00:6,000 --> 00:00:6,500
+2:6000
+
+8
+00:00:7,000 --> 00:00:7,500
+2:7000
+
+9
+00:00:8,000 --> 00:00:8,500
+2:8000
+
+10
+00:00:9,000 --> 00:00:9,500
+2:9000
diff --git a/tests/tests/media/res/raw/test_subtitle2_srt.3gp b/tests/tests/media/res/raw/test_subtitle2_srt.3gp
new file mode 100644
index 0000000..7ac2e72
--- /dev/null
+++ b/tests/tests/media/res/raw/test_subtitle2_srt.3gp
@@ -0,0 +1,39 @@
+1
+00:00:0,500 --> 00:00:1,000
+3:500
+
+2
+00:00:1,500 --> 00:00:2,000
+3:1500
+
+3
+00:00:2,500 --> 00:00:3,000
+3:2500
+
+4
+00:00:3,500 --> 00:00:4,000
+3:3500
+
+5
+00:00:4,500 --> 00:00:5,000
+3:4500
+
+6
+00:00:5,500 --> 00:00:6,000
+3:5500
+
+7
+00:00:6,500 --> 00:00:7,000
+3:6500
+
+8
+00:00:7,500 --> 00:00:8,000
+3:7500
+
+9
+00:00:8,500 --> 00:00:9,000
+3:8500
+
+10
+00:00:9,500 --> 00:00:10,000
+3:9500
diff --git a/tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp b/tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp
new file mode 100644
index 0000000..1de14a5
--- /dev/null
+++ b/tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index f85375d..94fc008 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -22,6 +22,8 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import java.nio.ByteBuffer;
+
 public class AudioTrackTest extends AndroidTestCase {
     private String TAG = "AudioTrackTest";
     private final long WAIT_MSEC = 200;
@@ -1314,6 +1316,27 @@
         track.release();
     }
 
+    public void testResourceLeakage() throws Exception {
+        final int BUFFER_SIZE = 600 * 1024;
+        ByteBuffer data = ByteBuffer.allocate(BUFFER_SIZE);
+        for (int i = 0; i < 10; i++) {
+            Log.i(TAG, "testResourceLeakage round " + i);
+            data.rewind();
+            AudioTrack track = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
+                                              44100,
+                                              AudioFormat.CHANNEL_OUT_STEREO,
+                                              AudioFormat.ENCODING_PCM_16BIT,
+                                              data.capacity(),
+                                              AudioTrack.MODE_STREAM);
+            assertTrue(track != null);
+            track.write(data.array(), 0, data.capacity());
+            track.play();
+            Thread.sleep(100);
+            track.stop();
+            track.release();
+        }
+    }
+
     private class MockAudioTrack extends AudioTrack {
 
         public MockAudioTrack(int streamType, int sampleRateInHz, int channelConfig,
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 0c39531..4e78805 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -23,15 +23,20 @@
 import android.media.AudioManager;
 import android.media.MediaPlayer;
 import android.media.MediaRecorder;
+import android.media.MediaMetadataRetriever;
+import android.media.TimedText;
 import android.media.audiofx.AudioEffect;
 import android.media.audiofx.Visualizer;
 import android.net.Uri;
 import android.os.Environment;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.util.Log;
 
 import java.io.File;
+import java.util.StringTokenizer;
 import java.util.UUID;
+import java.util.Vector;
 import java.util.concurrent.CountDownLatch;
 
 /**
@@ -44,10 +49,63 @@
 public class MediaPlayerTest extends MediaPlayerTestBase {
 
     private String RECORDED_FILE;
+    private static final String LOG_TAG = "MediaPlayerTest";
 
     private static final int  RECORDED_VIDEO_WIDTH  = 176;
     private static final int  RECORDED_VIDEO_HEIGHT = 144;
     private static final long RECORDED_DURATION_MS  = 3000;
+    private Vector<Integer> mTimedTextTrackIndex = new Vector<Integer>();
+
+    public class SubtitleMonitor {
+        private int selectedTrack;
+        private int numSignal;
+
+        public synchronized void reset() {
+            selectedTrack = 0;
+            numSignal = 0;
+        }
+
+        public synchronized void setSelectedTrack(int index) {
+            selectedTrack = index;
+        }
+
+        public synchronized int getSelectedTrack() {
+            return selectedTrack;
+        }
+
+        public synchronized void signal() {
+            numSignal++;
+            notifyAll();
+        }
+
+        public synchronized int getNumSignal() {
+            return numSignal;
+        }
+
+        public synchronized void waitForSignal(int targetCount) throws InterruptedException {
+            while (numSignal < targetCount) {
+                wait();
+            }
+        }
+
+        public synchronized void waitForSignal(int targetCount, long millis)
+                throws InterruptedException {
+            if (millis == 0) {
+                waitForSignal(targetCount);
+                return;
+            }
+            long deadline = System.currentTimeMillis() + millis;
+            while (numSignal < targetCount) {
+                long delay = deadline - System.currentTimeMillis();
+                if (delay < 0) {
+                    return;
+                }
+                wait(delay);
+            }
+        }
+    }
+
+    private SubtitleMonitor mSubtitleStatus = new SubtitleMonitor();
 
     private File mOutFile;
 
@@ -412,6 +470,7 @@
         checkOrientation(angle);
         recordVideo(width, height, angle, file, durationMs);
         checkDisplayedVideoSize(width, height, angle, file);
+        checkVideoRotationAngle(angle, file);
     }
 
     private void checkOrientation(int angle) throws Exception {
@@ -453,6 +512,17 @@
         playVideoTest(file, displayWidth, displayHeight);
     }
 
+    private void checkVideoRotationAngle(int angle, String file) {
+        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+        retriever.setDataSource(file);
+        String rotation = retriever.extractMetadata(
+                    MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
+        retriever.release();
+        retriever = null;
+        assertNotNull(rotation);
+        assertEquals(Integer.parseInt(rotation), angle);
+    }
+
     public void testLocalVideo_MP4_H264_480x360_500kbps_25fps_AAC_Stereo_128kbps_44110Hz()
             throws Exception {
         playVideoTest(
@@ -639,6 +709,100 @@
                 R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_stereo_128kbps_22050hz, 176, 144);
     }
 
+    private void readTimedTextTracks() throws Exception {
+        mTimedTextTrackIndex.clear();
+        MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
+        if (trackInfos == null || trackInfos.length == 0) {
+            return;
+        }
+        for (int i = 0; i < trackInfos.length; ++i) {
+            if (trackInfos[i] == null) continue;
+            if (trackInfos[i].getTrackType() ==
+                 MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
+                mTimedTextTrackIndex.add(i);
+            }
+        }
+    }
+
+    private int getTimedTextTrackCount() {
+        return mTimedTextTrackIndex.size();
+    }
+
+    private void selectSubtitleTrack(int index) throws Exception {
+        int trackIndex = mTimedTextTrackIndex.get(index);
+        mMediaPlayer.selectTrack(trackIndex);
+        mSubtitleStatus.setSelectedTrack(index);
+    }
+
+    public void testChangeSubtitleTrack() throws Exception {
+        loadResource(R.raw.testvideo_with_2_subtitles);
+        readTimedTextTracks();
+        assertEquals(getTimedTextTrackCount(), 2);
+
+        // Adds two more external subtitle files.
+        loadSubtitleSource(R.raw.test_subtitle1_srt);
+        loadSubtitleSource(R.raw.test_subtitle2_srt);
+        readTimedTextTracks();
+        assertEquals(getTimedTextTrackCount(), 4);
+
+        mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
+        mMediaPlayer.setScreenOnWhilePlaying(true);
+        mMediaPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+        mMediaPlayer.setOnTimedTextListener(new MediaPlayer.OnTimedTextListener() {
+            @Override
+            public void onTimedText(MediaPlayer mp, TimedText text) {
+                final int toleranceMs = 100;
+                final int durationMs = 500;
+                int posMs = mMediaPlayer.getCurrentPosition();
+                if (text != null) {
+                    String plainText = text.getText();
+                    if (plainText != null) {
+                        StringTokenizer tokens = new StringTokenizer(plainText.trim(), ":");
+                        int subtitleTrackIndex = Integer.parseInt(tokens.nextToken());
+                        int startMs = Integer.parseInt(tokens.nextToken());
+                        Log.w(LOG_TAG, "text: " + plainText.trim() +
+                              ", trackId: " + subtitleTrackIndex + ", posMs: " + posMs);
+                        assertTrue(posMs >= startMs - toleranceMs);
+                        assertTrue(posMs < startMs + durationMs + toleranceMs);
+                        assertEquals(mSubtitleStatus.getSelectedTrack(), subtitleTrackIndex);
+                        mSubtitleStatus.signal();
+                    }
+                }
+            }
+        });
+
+        mMediaPlayer.prepare();
+        assertFalse(mMediaPlayer.isPlaying());
+
+        mSubtitleStatus.reset();
+        selectSubtitleTrack(0);
+
+        mMediaPlayer.start();
+        assertTrue(mMediaPlayer.isPlaying());
+
+        // Waits until at least two subtitles are fired. Timeout is 2 sec.
+        // Please refer the test srt files:
+        // test_subtitle1_srt.3gp and test_subtitle2_srt.3gp
+        mSubtitleStatus.waitForSignal(2, 2000);
+        assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+        mSubtitleStatus.reset();
+
+        selectSubtitleTrack(1);
+        mSubtitleStatus.waitForSignal(2, 2000);
+        assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+        mSubtitleStatus.reset();
+
+        selectSubtitleTrack(2);
+        mSubtitleStatus.waitForSignal(2, 2000);
+        assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+        mSubtitleStatus.reset();
+
+        selectSubtitleTrack(3);
+        mSubtitleStatus.waitForSignal(2, 2000);
+        assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+        mMediaPlayer.stop();
+    }
+
     public void testCallback() throws Throwable {
         final int mp4Duration = 8484;
 
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
index 8b9da47..203afc2 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
@@ -33,6 +33,7 @@
     protected static final int SLEEP_TIME = 1000;
     protected static final int LONG_SLEEP_TIME = 6000;
     protected static final int STREAM_RETRIES = 20;
+    protected static boolean sUseScaleToFitMode = false;
 
     public static class Monitor {
         private boolean signalled;
@@ -74,6 +75,7 @@
     }
 
     protected Monitor mOnVideoSizeChangedCalled = new Monitor();
+    protected Monitor mOnVideoRenderingStartCalled = new Monitor();
     protected Monitor mOnBufferingUpdateCalled = new Monitor();
     protected Monitor mOnPrepareCalled = new Monitor();
     protected Monitor mOnSeekCompleteCalled = new Monitor();
@@ -132,6 +134,25 @@
         try {
             mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
                     afd.getLength());
+
+            // Although it is only meant for video playback, it should not
+            // cause issues for audio-only playback.
+            int videoScalingMode = sUseScaleToFitMode?
+                                    MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT
+                                  : MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING;
+
+            mMediaPlayer.setVideoScalingMode(videoScalingMode);
+        } finally {
+            afd.close();
+        }
+        sUseScaleToFitMode = !sUseScaleToFitMode;  // Alternate the scaling mode
+    }
+
+    protected void loadSubtitleSource(int resid) throws Exception {
+        AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
+        try {
+            mMediaPlayer.addTimedTextSource(afd.getFileDescriptor(), afd.getStartOffset(),
+                      afd.getLength(), MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP);
         } finally {
             afd.close();
         }
@@ -209,6 +230,15 @@
                 return true;
             }
         });
+        mMediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+            @Override
+            public boolean onInfo(MediaPlayer mp, int what, int extra) {
+                if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
+                    mOnVideoRenderingStartCalled.signal();
+                }
+                return true;
+            }
+        });
         try {
           mMediaPlayer.prepare();
         } catch (IOException e) {
@@ -218,6 +248,7 @@
 
         mMediaPlayer.start();
         mOnVideoSizeChangedCalled.waitForSignal();
+        mOnVideoRenderingStartCalled.waitForSignal();
         mMediaPlayer.setVolume(leftVolume, rightVolume);
 
         // waiting to complete
diff --git a/tests/tests/media/src/android/media/cts/MediaRandomTest.java b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
new file mode 100644
index 0000000..f1e3e8e
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.cts;
+
+
+import android.media.MediaRecorder;
+import android.media.MediaPlayer;
+import android.view.SurfaceHolder;
+import android.test.ActivityInstrumentationTestCase2;
+import android.os.Environment;
+import android.util.Log;
+
+import java.util.Random;
+
+public class MediaRandomTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
+    private static final String TAG = "MediaRandomTest";
+
+    private static final String OUTPUT_FILE =
+                Environment.getExternalStorageDirectory().toString() + "/record.3gp";
+
+    private static final int NUMBER_OF_RECORDER_RANDOM_ACTIONS = 100000;
+
+    private MediaRecorder mRecorder;
+    private volatile boolean mMediaServerDied = false;
+    private volatile int mAction;
+    private volatile int mParam;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        getInstrumentation().waitForIdleSync();
+        try {
+            // Running this on UI thread make sure that
+            // onError callback can be received.
+            runTestOnUiThread(new Runnable() {
+                public void run() {
+                    mRecorder = new MediaRecorder();
+                }
+            });
+        } catch (Throwable e) {
+            e.printStackTrace();
+            fail();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mRecorder != null) {
+            mRecorder.release();
+            mRecorder = null;
+        }
+        super.tearDown();
+    }
+
+    /**
+     * This is a watchdog used to stop the process if it hasn't been pinged
+     * for more than specified milli-seconds. It is used like:
+     *
+     * Watchdog w = new Watchdog(10000);  // 10 seconds.
+     * w.start();       // start the watchdog.
+     * ...
+     * w.ping();
+     * ...
+     * w.ping();
+     * ...
+     * w.end();        // ask the watchdog to stop.
+     * w.join();        // join the thread.
+     */
+    class Watchdog extends Thread {
+        private final long mTimeoutMs;
+        private boolean mWatchdogStop;
+        private boolean mWatchdogPinged;
+
+        public Watchdog(long timeoutMs) {
+            mTimeoutMs = timeoutMs;
+            mWatchdogStop = false;
+            mWatchdogPinged = false;
+        }
+
+        public synchronized void run() {
+            while (true) {
+                // avoid early termination by "spurious" waitup.
+                final long startTimeMs = System.currentTimeMillis();
+                long remainingWaitTimeMs = mTimeoutMs;
+                do {
+                    try {
+                        wait(remainingWaitTimeMs);
+                    } catch (InterruptedException ex) {
+                        // ignore.
+                    }
+                    remainingWaitTimeMs = mTimeoutMs - (System.currentTimeMillis() - startTimeMs);
+                } while (remainingWaitTimeMs > 0);
+
+                if (mWatchdogStop) {
+                    break;
+                }
+
+                if (!mWatchdogPinged) {
+                    fail("Action " + mAction + " Param " + mParam
+                            + " waited over " + (mTimeoutMs - remainingWaitTimeMs) + " ms");
+                    return;
+                }
+                mWatchdogPinged = false;
+            }
+        }
+
+        public synchronized void ping() {
+            mWatchdogPinged = true;
+            this.notify();
+        }
+
+        public synchronized void end() {
+            mWatchdogStop = true;
+            this.notify();
+        }
+    }
+
+    public MediaRandomTest() {
+        super("com.android.cts.media", MediaStubActivity.class);
+    }
+
+    public void testmRecorderRandomAction() throws Exception {
+        try {
+            long seed = System.currentTimeMillis();
+            Log.v(TAG, "seed = " + seed);
+            Random r = new Random(seed);
+
+            mMediaServerDied = false;
+            mRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {
+                @Override
+                public void onError(MediaRecorder recorder, int what, int extra) {
+                    // FIXME:
+                    // replace the constant with MediaRecorder.MEDIA_RECORDER_ERROR_SERVER_DIED,
+                    // if it becomes public.
+                    if (mRecorder == recorder &&
+                        what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
+                        Log.e(TAG, "mediaserver process died");
+                        mMediaServerDied = true;
+                    }
+                }
+            });
+
+            final int[] width  = {176, 352, 320, 640, 1280, 1920};
+            final int[] height = {144, 288, 240, 480,  720, 1080};
+            final SurfaceHolder surfaceHolder = getActivity().getSurfaceHolder();
+
+            Watchdog watchdog = new Watchdog(5000);
+            watchdog.start();
+            for (int i = 0; i < NUMBER_OF_RECORDER_RANDOM_ACTIONS; i++) {
+                watchdog.ping();
+                assertTrue(!mMediaServerDied);
+
+                mAction = (int)(r.nextInt(14));
+                mParam = (int)(r.nextInt(1000000));
+                try {
+                    switch (mAction) {
+                    case 0:
+                        mRecorder.setAudioSource(mParam % 3);
+                        break;
+                    case 1:
+                        // XXX:
+                        // Fix gralloc source and change
+                        // mRecorder.setVideoSource(mParam % 3);
+                        mRecorder.setVideoSource(mParam % 2);
+                        break;
+                    case 2:
+                        mRecorder.setOutputFormat(mParam % 5);
+                        break;
+                    case 3:
+                        mRecorder.setAudioEncoder(mParam % 3);
+                        break;
+                    case 4:
+                        mRecorder.setVideoEncoder(mParam % 5);
+                        break;
+                    case 5:
+                        mRecorder.setPreviewDisplay(surfaceHolder.getSurface());
+                        break;
+                    case 6:
+                        int index = mParam % width.length;
+                        mRecorder.setVideoSize(width[index], height[index]);
+                        break;
+                    case 7:
+                        mRecorder.setVideoFrameRate(mParam % 40 - 5);
+                        break;
+                    case 8:
+                        mRecorder.setOutputFile(OUTPUT_FILE);
+                        break;
+                    case 9:
+                        mRecorder.prepare();
+                        break;
+                    case 10:
+                        mRecorder.start();
+                        break;
+                    case 11:
+                        Thread.sleep(mParam % 20);
+                        break;
+                    case 12:
+                        mRecorder.stop();
+                        break;
+                    case 13:
+                        mRecorder.reset();
+                        break;
+                    default:
+                        break;
+                    }
+                } catch (Exception e) {
+                }
+            }
+            watchdog.end();
+            watchdog.join();
+        } catch (Exception e) {
+            Log.v(TAG, e.toString());
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index 55be9ac..f31f552 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -18,11 +18,13 @@
 
 import android.content.pm.PackageManager;
 import android.hardware.Camera;
+import android.media.MediaMetadataRetriever;
 import android.media.MediaRecorder;
 import android.media.MediaRecorder.OnErrorListener;
 import android.media.MediaRecorder.OnInfoListener;
 import android.media.MediaMetadataRetriever;
 import android.os.Environment;
+import android.os.ConditionVariable;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
 import android.view.Surface;
@@ -43,6 +45,7 @@
     private final String OUTPUT_PATH2;
     private static final float TOLERANCE = 0.0002f;
     private static final int RECORD_TIME = 3000;
+    private static final int THREE_MINUTES = 180000;
     private static final int VIDEO_WIDTH = 176;
     private static final int VIDEO_HEIGHT = 144;
     private static final int VIDEO_BIT_RATE_IN_BPS = 128000;
@@ -62,6 +65,8 @@
     private MediaStubActivity mActivity = null;
 
     private MediaRecorder mMediaRecorder;
+    private ConditionVariable mMaxDurationCond;
+    private ConditionVariable mMaxFileSizeCond;
 
     public MediaRecorderTest() {
         super("com.android.cts.media", MediaStubActivity.class);
@@ -97,10 +102,23 @@
                 mMediaRecorder = new MediaRecorder();
                 mOutFile = new File(OUTPUT_PATH);
                 mOutFile2 = new File(OUTPUT_PATH2);
+
+                mMaxDurationCond = new ConditionVariable();
+                mMaxFileSizeCond = new ConditionVariable();
+
                 mMediaRecorder.setOutputFile(OUTPUT_PATH);
                 mMediaRecorder.setOnInfoListener(new OnInfoListener() {
                     public void onInfo(MediaRecorder mr, int what, int extra) {
                         mOnInfoCalled = true;
+                        if (what ==
+                            MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
+                            Log.v(TAG, "max duration reached");
+                            mMaxDurationCond.open();
+                        } else if (what ==
+                            MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
+                            Log.v(TAG, "max file size reached");
+                            mMaxFileSizeCond.open();
+                        }
                     }
                 });
                 mMediaRecorder.setOnErrorListener(new OnErrorListener() {
@@ -127,6 +145,10 @@
             mCamera.release();
             mCamera = null;
         }
+        mMaxDurationCond.close();
+        mMaxDurationCond = null;
+        mMaxFileSizeCond.close();
+        mMaxFileSizeCond = null;
         mActivity = null;
         super.tearDown();
     }
@@ -352,30 +374,74 @@
         if (!hasMicrophone()) {
             return;
         }
+        testSetMaxDuration(20000, 1000);
+    }
+
+    private void testSetMaxDuration(long durationMs, long toleranceMs) throws Exception {
         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
         mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
-        mMediaRecorder.setMaxDuration(0);
+        mMediaRecorder.setMaxDuration((int)durationMs);
         mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
         mMediaRecorder.prepare();
         mMediaRecorder.start();
-        Thread.sleep(RECORD_TIME * 30);
+        long startTimeMs = System.currentTimeMillis();
+        if (!mMaxDurationCond.block(durationMs + toleranceMs)) {
+            fail("timed out waiting for MEDIA_RECORDER_INFO_MAX_DURATION_REACHED");
+        }
+        long endTimeMs = System.currentTimeMillis();
+        long actualDurationMs = endTimeMs - startTimeMs;
         mMediaRecorder.stop();
-        checkOutputExist();
+        checkRecordedTime(durationMs, actualDurationMs, toleranceMs);
+    }
+
+    private void checkRecordedTime(long expectedMs, long actualMs, long tolerance) {
+        assertEquals(expectedMs, actualMs, tolerance);
+        long actualFileDurationMs = getRecordedFileDurationMs(OUTPUT_PATH);
+        assertEquals(actualFileDurationMs, actualMs, tolerance);
+    }
+
+    private int getRecordedFileDurationMs(final String fileName) {
+        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+        retriever.setDataSource(fileName);
+        String durationStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
+        assertNotNull(durationStr);
+        return Integer.parseInt(durationStr);
     }
 
     public void testSetMaxFileSize() throws Exception {
         if (!hasMicrophone()) {
             return;
         }
+        testSetMaxFileSize(512 * 1024, 50 * 1024);
+    }
+
+    private void testSetMaxFileSize(
+            long fileSize, long tolerance) throws Exception {
         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
         mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
         mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
-        mMediaRecorder.setMaxFileSize(0);
+        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
+        mMediaRecorder.setVideoSize(VIDEO_WIDTH, VIDEO_HEIGHT);
+        mMediaRecorder.setVideoEncodingBitRate(256000);
+        mMediaRecorder.setPreviewDisplay(mActivity.getSurfaceHolder().getSurface());
+        mMediaRecorder.setMaxFileSize(fileSize);
         mMediaRecorder.prepare();
         mMediaRecorder.start();
-        Thread.sleep(RECORD_TIME * 30);
+
+        // Recording a scene with moving objects would greatly help reduce
+        // the time for waiting.
+        if (!mMaxFileSizeCond.block(THREE_MINUTES)) {
+            fail("timed out waiting for MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED");
+        }
         mMediaRecorder.stop();
-        checkOutputExist();
+        checkOutputFileSize(OUTPUT_PATH, fileSize, tolerance);
+    }
+
+    private void checkOutputFileSize(final String fileName, long fileSize, long tolerance) {
+        assertTrue(mOutFile.exists());
+        assertEquals(fileSize, mOutFile.length(), tolerance);
+        assertTrue(mOutFile.delete());
     }
 
     public void testOnErrorListener() throws Exception {
diff --git a/tests/tests/opengl/Android.mk b/tests/tests/opengl/Android.mk
index 0610c5f..98f11e9 100644
--- a/tests/tests/opengl/Android.mk
+++ b/tests/tests/opengl/Android.mk
@@ -27,9 +27,9 @@
 # All tests should include android.test.runner.
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_JNI_SHARED_LIBRARIES := libopengltest_jni
 
-LOCAL_JNI_SHARED_LIBRARIES := libopengltest
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/opengl/AndroidManifest.xml b/tests/tests/opengl/AndroidManifest.xml
index 4619512..266216f 100644
--- a/tests/tests/opengl/AndroidManifest.xml
+++ b/tests/tests/opengl/AndroidManifest.xml
@@ -31,15 +31,17 @@
          <activity
             android:label="@string/app_name"
             android:name="android.opengl.cts.OpenGLES20ActivityOne">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
+         </activity>
+          <activity
+            android:label="@string/app_name"
+            android:name="android.opengl.cts.OpenGLES20ActivityTwo">
          </activity> 
          <uses-library  android:name="android.test.runner" />
          <activity
-            android:name="android.opengl.cts.OpenGLES20NativeActivity"
+            android:name="android.opengl.cts.OpenGLES20NativeActivityOne"
+            android:label="@string/app_name" />
+         <activity
+            android:name="android.opengl.cts.OpenGLES20NativeActivityTwo"
             android:label="@string/app_name" />
     </application>
 
diff --git a/tests/tests/opengl/libopengltest/Android.mk b/tests/tests/opengl/libopengltest/Android.mk
index a54816e..a141550 100755
--- a/tests/tests/opengl/libopengltest/Android.mk
+++ b/tests/tests/opengl/libopengltest/Android.mk
@@ -17,7 +17,7 @@
 #
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
-LOCAL_MODULE := libopengltest
+LOCAL_MODULE := libopengltest_jni
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := common.cpp \
                    gl2_jni_libone.cpp \
@@ -27,6 +27,12 @@
                    attach_shader_four.cpp \
                    attach_shader_five.cpp \
                    attach_shader_six.cpp \
+                   attach_shader_seven.cpp \
+                   attach_shader_eight.cpp \
+                   attach_shader_nine.cpp \
+                   attach_shader_ten.cpp \
+                   attach_shader_eleven.cpp \
+                   color_one.cpp
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
diff --git a/tests/tests/opengl/libopengltest/attach_shader_eight.cpp b/tests/tests/opengl/libopengltest/attach_shader_eight.cpp
new file mode 100755
index 0000000..180399b
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_eight.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "attach_shader_eight.h"
+
+#define  LOG_TAG    "attach_shader_eight"
+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+Data attachShaderEight(){
+    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+
+    GLuint program = glCreateProgram();
+    glAttachShader(program, fragmentShader);
+
+    GLint error = glGetError();
+    Data data = {error, -9 , -1};
+    glDeleteShader(fragmentShader);
+    glDeleteProgram(program);
+    return data;
+}
diff --git a/tests/tests/opengl/libopengltest/attach_shader_eight.h b/tests/tests/opengl/libopengltest/attach_shader_eight.h
new file mode 100755
index 0000000..2f317e2
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_eight.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ATTACH_SHADER_EIGHT_H_
+#define _ATTACH_SHADER_EIGHT_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+Data attachShaderEight();
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/attach_shader_eleven.cpp b/tests/tests/opengl/libopengltest/attach_shader_eleven.cpp
new file mode 100755
index 0000000..597de83
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_eleven.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "attach_shader_eleven.h"
+#include "common.h"
+#include "vertex.h"
+
+#define  LOG_TAG    "attach_shader_eleven"
+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+Data attachShaderEleven(){
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, attach_shader_successful_complile_vertex);
+    GLuint program = glCreateProgram();
+    glAttachShader(program, vertexShader);
+
+    GLsizei maxCount = 10;
+    GLsizei count;
+    GLuint shaders[maxCount];
+
+    glGetAttachedShaders(program, maxCount,
+         &count,
+         shaders);
+    LOGI("Attached Shader First element :  %d\n", *shaders);
+    LOGI("ShaderCount %d\n", count);
+    GLint error = glGetError();
+    Data data = {error, count, -1};
+
+    glDeleteProgram(program);
+    return data;
+}
diff --git a/tests/tests/opengl/libopengltest/attach_shader_eleven.h b/tests/tests/opengl/libopengltest/attach_shader_eleven.h
new file mode 100755
index 0000000..5cb39c1
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_eleven.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+#ifndef _ATTACH_SHADER_ELEVEN_H_
+#define _ATTACH_SHADER_ELEVEN_H_
+
+Data attachShaderEleven();
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/attach_shader_nine.cpp b/tests/tests/opengl/libopengltest/attach_shader_nine.cpp
new file mode 100755
index 0000000..154c351
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_nine.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "attach_shader_nine.h"
+
+#define  LOG_TAG    "attach_shader_nine"
+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+Data attachShaderNine(){
+    GLuint fragmentShader = 0;
+    GLuint program = glCreateProgram();
+    glAttachShader(program, fragmentShader);
+
+    GLint error = glGetError();
+    Data data = {error, -9, -1};
+    glDeleteShader(fragmentShader);
+    glDeleteProgram(program);
+    return data;
+}
diff --git a/tests/tests/opengl/libopengltest/attach_shader_nine.h b/tests/tests/opengl/libopengltest/attach_shader_nine.h
new file mode 100755
index 0000000..e2ea44f
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_nine.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ATTACH_SHADER_NINE_H_
+#define _ATTACH_SHADER_NINE_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+Data attachShaderNine();
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/attach_shader_seven.cpp b/tests/tests/opengl/libopengltest/attach_shader_seven.cpp
new file mode 100755
index 0000000..f7e9c47
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_seven.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "attach_shader_seven.h"
+
+#define  LOG_TAG    "attach_shader_seven"
+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+Data attachShaderSeven(){
+    GLuint vertexShaderOne = glCreateShader(GL_VERTEX_SHADER);
+    GLuint vertexShaderTwo = glCreateShader(GL_VERTEX_SHADER);
+
+    GLuint program = glCreateProgram();
+    glAttachShader(program, vertexShaderOne);
+    glAttachShader(program, vertexShaderTwo);
+
+
+    GLint error = glGetError();
+    Data data = {error, -9 , -1};
+    glDeleteShader(vertexShaderOne);
+    glDeleteShader(vertexShaderTwo);
+    glDeleteProgram(program);
+    return data;
+}
diff --git a/tests/tests/opengl/libopengltest/attach_shader_seven.h b/tests/tests/opengl/libopengltest/attach_shader_seven.h
new file mode 100755
index 0000000..b13ac55
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_seven.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ATTACH_SHADER_SEVEN_H_
+#define _ATTACH_SHADER_SEVEN_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+Data attachShaderSeven();
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/attach_shader_ten.cpp b/tests/tests/opengl/libopengltest/attach_shader_ten.cpp
new file mode 100755
index 0000000..3bc197e
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_ten.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "attach_shader_ten.h"
+#include "common.h"
+#include "shader.h"
+#define  LOG_TAG    "attach_shader_ten"
+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+Data attachShaderTen(){
+    GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, attach_shader_successful_complile_shader);
+    GLuint program = glCreateProgram();
+    glAttachShader(program, fragmentShader);
+
+    GLsizei maxCount = 10;
+    GLsizei count;
+    GLuint shaders[maxCount];
+
+    glGetAttachedShaders(program, maxCount,
+         &count,
+         shaders);
+    LOGI("Attached Shader First element :  %d\n", *shaders);
+    LOGI("ShaderCount %d\n", count);
+    GLint error = glGetError();
+    Data data = {error, count, -1};
+    glDeleteShader(fragmentShader);
+    glDeleteProgram(program);
+    return data;
+}
diff --git a/tests/tests/opengl/libopengltest/attach_shader_ten.h b/tests/tests/opengl/libopengltest/attach_shader_ten.h
new file mode 100755
index 0000000..9bb8d0b
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_ten.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+#ifndef _ATTACH_SHADER_TEN_H_
+#define _ATTACH_SHADER_TEN_H_
+
+Data attachShaderTen();
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/color_one.cpp b/tests/tests/opengl/libopengltest/color_one.cpp
new file mode 100755
index 0000000..27d400c
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/color_one.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "color_one.h"
+#include "common.h"
+#include "vertex.h"
+#include "shader.h"
+
+#define  LOG_TAG    "color_one"
+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+
+static const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+        0.5f, -0.5f };
+GLuint gProgram;
+GLuint gvPositionHandle;
+GLuint gvColorHandle;
+int width;
+int height;
+
+float dataFloat[4];
+void initColorOne(int w, int h){
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, color_one_vertex_shader_one);
+    GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, color_one_fragment_shader_one);
+    gProgram = glCreateProgram();
+    LOGI("Program %d\n", gProgram);
+    width = w;
+    height = h;
+    glAttachShader(gProgram, vertexShader);
+    checkGlError("glAttachShader");
+    glAttachShader(gProgram, fragmentShader);
+    checkGlError("glAttachShader");
+    glBindAttribLocation(gProgram, 0, "vPosition");
+    glBindAttribLocation(gProgram, 1, "vColor");
+    glLinkProgram(gProgram);
+    GLint linkStatus = GL_FALSE;
+    glGetProgramiv(gProgram, GL_LINK_STATUS, &linkStatus);
+    if (linkStatus != GL_TRUE) {
+        GLint bufLength = 0;
+        glGetProgramiv(gProgram, GL_INFO_LOG_LENGTH, &bufLength);
+        if (bufLength) {
+            char* buf = (char*) malloc(bufLength);
+            if (buf) {
+                glGetProgramInfoLog(gProgram, bufLength, NULL, buf);
+                LOGE("Could not link program:\n%s\n", buf);
+                free(buf);
+             }
+        }
+    }
+    LOGI("w %d, h %d\n",w, h);
+    glViewport(0, 0, w, h);
+
+    checkGlError("glViewport");
+    gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+    gvColorHandle = glGetAttribLocation(gProgram, "vColor");
+    GLsizei maxCount = 10;
+    GLsizei count;
+    GLuint shaders[maxCount];
+
+    glGetAttachedShaders(gProgram, maxCount,
+         &count,
+         shaders);
+    LOGI("Attached Shader First element :  %d\n", *shaders);
+    LOGI("ShaderCount %d\n", count);
+    GLint error = glGetError();
+    return;
+}
+
+float* drawColorOne(float mColor[]){
+     LOGI("drawColorOne start");
+    static float grey;
+    grey = 0.01f;
+
+    glClearColor(grey, grey, grey, 1.0f);
+    checkGlError("glClearColor");
+    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    checkGlError("glClear");
+
+    glUseProgram(gProgram);
+    checkGlError("glUseProgram");
+
+    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+    checkGlError("glVertexAttribPointer");
+    glEnableVertexAttribArray(0);
+    checkGlError("glEnableVertexAttribArray");
+
+    glVertexAttribPointer(gvColorHandle,4, GL_FLOAT, GL_FALSE, 0, mColor);
+    checkGlError("glVertexAttribPointer");
+    glEnableVertexAttribArray(1);
+    checkGlError("glEnableVertexAttribArray");
+
+    glDrawArrays(GL_TRIANGLES, 0, 3);
+    checkGlError("glDrawArrays");
+    GLubyte data[4*1];
+
+
+    glReadPixels(width/2, height/2, 1,1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&data);
+    for(int i = 0; i < sizeof(data); i++){
+        dataFloat[i] = data[i];
+    }
+
+    return dataFloat;
+}
+
+void deleteColorOne() {
+     glDeleteProgram(gProgram);
+}
+
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        LOGI("after %s() glError (0x%x)\n", op, error);
+    }
+}
diff --git a/tests/tests/opengl/libopengltest/color_one.h b/tests/tests/opengl/libopengltest/color_one.h
new file mode 100755
index 0000000..21dd9fd
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/color_one.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _COLOR_ONE_H_
+#define _COLOR_ONE_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+void initColorOne(int w,int h);
+float* drawColorOne(float color[]);
+
+static void checkGlError(const char* op);
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/gl2_jni_libone.cpp b/tests/tests/opengl/libopengltest/gl2_jni_libone.cpp
index 9433702..fe49b1b 100755
--- a/tests/tests/opengl/libopengltest/gl2_jni_libone.cpp
+++ b/tests/tests/opengl/libopengltest/gl2_jni_libone.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 #include <jni.h>
 #include <android/log.h>
 
@@ -24,12 +23,19 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
+
 #include "attach_shader_one.h"
 #include "attach_shader_two.h"
 #include "attach_shader_three.h"
 #include "attach_shader_four.h"
 #include "attach_shader_five.h"
 #include "attach_shader_six.h"
+#include "attach_shader_seven.h"
+#include "attach_shader_eight.h"
+#include "attach_shader_nine.h"
+#include "attach_shader_ten.h"
+#include "attach_shader_eleven.h"
+#include "color_one.h"
 
 #define  LOG_TAG    "gl2_jni_libone"
 #define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
@@ -40,7 +46,7 @@
 
 
 extern "C" JNIEXPORT void JNICALL Java_android_opengl_cts_GL2JniLibOne_init
-  (JNIEnv *, jclass pClass, jint pCategory, jint pSubCategory)  {
+  (JNIEnv *, jclass pClass, jint pCategory, jint pSubCategory, jint width, jint height)  {
     LOGI("Category :  %d\n", pCategory);
 
     if(pCategory == 1) {
@@ -72,6 +78,34 @@
             Data data = attachShaderSix();
             LOGI("Attach Shader Error :  %d\n", data.mShaderError);
             errorAttachShader = data.mShaderError;
+        }else if(pSubCategory == 7) {
+            Data data = attachShaderSeven();
+            LOGI("Attach Shader Error :  %d\n", data.mShaderError);
+            errorAttachShader = data.mShaderError;
+        }else if(pSubCategory == 8) {
+            Data data = attachShaderEight();
+            LOGI("Attach Shader Error :  %d\n", data.mShaderError);
+            errorAttachShader = data.mShaderError;
+        }else if(pSubCategory == 9) {
+            Data data = attachShaderNine();
+            LOGI("Attach Shader Error :  %d\n", data.mShaderError);
+            errorAttachShader = data.mShaderError;
+        }else if(pSubCategory == 10) {
+            Data data = attachShaderTen();
+            LOGI("Attach Shader Error :  %d\n", data.mShaderError);
+            LOGI("Shader Count :  %d\n", data.mShaderCount);
+            errorAttachShader = data.mShaderError;
+            shaderCount = data.mShaderCount;
+        }else if(pSubCategory == 11) {
+            Data data = attachShaderEleven();
+            LOGI("Attach Shader Error :  %d\n", data.mShaderError);
+            LOGI("Shader Count :  %d\n", data.mShaderCount);
+            errorAttachShader = data.mShaderError;
+            shaderCount = data.mShaderCount;
+        }
+    }else if(pCategory == 3){//Color Test
+        if(pSubCategory == 1){
+            initColorOne( width,height);
         }
     }
 }
@@ -97,4 +131,23 @@
     return shaderCount;
 }
 
+extern "C" JNIEXPORT jfloatArray JNICALL Java_android_opengl_cts_GL2JniLibOne_draw(JNIEnv * env,
+        jclass obj, jint pCategory, jint pSubCategory, jfloatArray color)
+{
+    LOGI("Inside draw %d %d", pCategory, pSubCategory);
+    jfloatArray result;
+    if(pCategory == 3){
+        if(pSubCategory == 1){
+            result = env->NewFloatArray(4);
 
+            jfloat *lColor =  env->GetFloatArrayElements(color,0);
+
+            float * actualColor = drawColorOne(lColor);
+            for( int i= 0; i < sizeof(actualColor); i++) {
+                LOGI("actualColor[%d] ; %f", i, actualColor[i]);
+            }
+            env->SetFloatArrayRegion(result, 0, 4, actualColor);
+        }
+    }
+    return result;
+}
diff --git a/tests/tests/opengl/libopengltest/shader.h b/tests/tests/opengl/libopengltest/shader.h
new file mode 100755
index 0000000..12131f1
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/shader.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _SHADER_H_
+#define _SHADER_H_
+
+static const char attach_shader_successful_complile_shader[] =
+           "attribute vec3 gtf_Normal;\n"
+            "attribute vec4 gtf_Vertex;\n"
+            "uniform mat3 gtf_NormalMatrix;\n"
+            "uniform mat4 gtf_ModelViewMatrix;\n"
+            "uniform mat4 gtf_ModelViewProjectionMatrix;\n"
+
+            "varying float lightIntensity;\n"
+            "varying vec3 Position;\n"
+            "uniform vec3 LightPosition;\n"
+            "uniform float Scale;\n"
+            "void main(void) {\n"
+            "vec4 pos = gtf_ModelViewMatrix * gtf_Vertex;\n"
+            "Position = vec3(gtf_Vertex) * Scale;\n"
+            "vec3 tnorm = normalize(gtf_NormalMatrix * gtf_Normal);\n"
+            "lightIntensity = dot(normalize(LightPosition - vec3(pos)), tnorm) * 1.5;\n"
+            "gl_Position = gtf_ModelViewProjectionMatrix * gtf_Vertex;\n";
+
+static const char color_one_fragment_shader_one[] =
+        "precision mediump float;     \n"
+        "varying vec4 varyColor;      \n"
+        "void main()                  \n"
+        "{                            \n"
+        "  gl_FragColor = varyColor;  \n"
+        "}       ";
+
+static const char color_one_fragment_shader[] =
+        "precision mediump float;     \n"
+        "void main()                  \n"
+        "{                            \n"
+        "  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);  \n"
+        "}       ";
+
+#endif
diff --git a/tests/tests/opengl/libopengltest/vertex.h b/tests/tests/opengl/libopengltest/vertex.h
new file mode 100755
index 0000000..50a4c7a
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/vertex.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _VERTEX_H_
+#define _VERTEX_H_
+
+static const char attach_shader_successful_complile_vertex[] =
+    "#ifdef GL_ES \n"
+    "precision mediump float;\n"
+    "#endif\n"
+    "uniform float    mortarThickness;\n"
+    "uniform vec3    brickColor;\n"
+    "uniform vec3    mortarColor;\n"
+    " \n"
+    "uniform float    brickMortarWidth;\n"
+    "uniform float    brickMortarHeight;\n"
+    "uniform float    mwf; \n"
+    "uniform float    mhf; \n"
+    ""
+    "varying vec3  Position; \n"
+    "varying float lightIntensity; \n"
+    " \n"
+    "void main (void) \n"
+    "{\n"
+    "    vec3    ct; \n"
+    "    float    ss, tt, w, h; \n"
+    " \n"
+    "    vec3 pos = Position; \n"
+    ""
+    "    ss = pos.x / brickMortarWidth; \n"
+    "    tt = pos.z / brickMortarHeight; \n"
+    ""
+    "    if (fract (tt * 0.5) > 0.5) \n"
+    "        ss += 0.5; \n"
+    ""
+    "    ss = fract (ss); \n"
+    "    tt = fract (tt); \n"
+
+    "    w = step (mwf, ss) - step (1.0 - mwf, ss); \n"
+    "    h = step (mhf, tt) - step (1.0 - mhf, tt); \n"
+    ""
+    "    ct = clamp(mix (mortarColor, brickColor, w * h) * lightIntensity, 0.0, 1.0); \n"
+    ""
+    "    gl_FragColor = vec4 (ct, 1.0); \n"
+    "} \n";
+
+static const char color_one_vertex_shader_one[] =
+        "attribute vec4 vPosition;    \n"
+        "attribute vec4 vColor;       \n"
+        "varying vec4 varyColor;      \n"
+        "void main()                  \n"
+        "{                            \n"
+        "   gl_Position = vPosition;  \n"
+        "   varyColor = vColor;       \n"
+        "}                            \n";
+
+static const char color_one_vertex_shader[] =
+        "attribute vec4 vPosition;    \n"
+        "void main()                  \n"
+        "{                            \n"
+        "   gl_Position = vPosition;  \n"
+        "}                            \n";
+
+#endif
diff --git a/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java
index 21efd6f..62ca1f9 100644
--- a/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java
@@ -29,8 +29,8 @@
 
     private OpenGLES20ActivityOne getShaderActivity(int viewType, int viewIndex) {
         Intent intent = new Intent();
-        intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_TYPE, viewType);
-        intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_INDEX, viewIndex);
+        intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_TYPE, viewType);
+        intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_INDEX, viewIndex);
         setActivityIntent(intent);
         OpenGLES20ActivityOne activity = getActivity();
         assertTrue(activity.waitForFrameDrawn());
@@ -133,4 +133,16 @@
         int error = mActivity.glGetError();
         assertEquals(GLES20.GL_NO_ERROR, error);
     }
+
+    public void test_glAttachShaders_successfulcompile_attach_vert() throws Throwable {
+        mActivity = getShaderActivity(Constants.SHADER, 11);
+        int error = mActivity.glGetError();
+        assertEquals(GLES20.GL_NO_ERROR, error);
+    }
+
+    public void test_glAttachShaders_successfulcompile_attach_invalid_handle_frag() throws Throwable {
+        mActivity = getShaderActivity(Constants.SHADER, 12);
+        int error = mActivity.glGetError();
+        assertTrue(GLES20.GL_NO_ERROR != error);
+    }
 }
diff --git a/tests/tests/opengl/src/android/opengl/cts/ColorBufferTest.java b/tests/tests/opengl/src/android/opengl/cts/ColorBufferTest.java
new file mode 100755
index 0000000..5ec1ce1
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/ColorBufferTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+public class ColorBufferTest extends ActivityInstrumentationTestCase2<OpenGLES20ActivityTwo> {
+    private static final long SLEEP_TIME = 500l;
+    public ColorBufferTest(Class<OpenGLES20ActivityTwo> activityClass) {
+        super(activityClass);
+    }
+
+    private OpenGLES20ActivityTwo mActivity;
+
+    public ColorBufferTest() {
+        super(OpenGLES20ActivityTwo.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+    }
+    /**
+     *Test: Attach an two valid shaders to a program
+     * <pre>
+     * shader count : 2
+     * error        : GLES20.GL_NO_ERROR
+     * </pre>
+     */
+    public void test_RGBA_1001() throws Throwable {
+        float r = 1.0f;
+        float g = 0.0f;
+        float b = 0.0f;
+        float a = 1.0f;
+        final float[] vertexColors =  getVertexColors(r, g, b, a);
+        mActivity = getActivity();
+        float[] expectedColor = {r, g, b, a};
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_1101() throws Throwable {
+        float r = 1.0f;
+        float g = 1.0f;
+        float b = 0.0f;
+        float a = 1.0f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_1111() throws Throwable {
+        float r = 1.0f;
+        float g = 1.0f;
+        float b = 1.0f;
+        float a = 1.0f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_0101() throws Throwable {
+        float r = 0.0f;
+        float g = 1.0f;
+        float b = 0.0f;
+        float a = 1.0f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_0011() throws Throwable {
+        float r = 0.0f;
+        float g = 0.0f;
+        float b = 1.0f;
+        float a = 1.0f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_0000() throws Throwable {
+        float r = 0.0f;
+        float g = 0.0f;
+        float b = 0.0f;
+        float a = 0.0f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_rand_val_one() throws Throwable {
+        float r = 0.6f;
+        float g = 0.7f;
+        float b = 0.25f;
+        float a = 0.5f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    private float[] getVertexColors(float r, float g, float b, float a) {
+        float[] vertexColors =
+              { r, g, b, a,
+                r, g, b, a,
+                r, g, b, a,
+                r, g, b, a
+               };
+        return vertexColors;
+    }
+
+    private void compare(float[] expectedColor, float[] actualColor) {
+        assertNotNull(actualColor);
+        assertEquals(4, actualColor.length);
+        float r = expectedColor[0];
+        float g = expectedColor[1];
+        float b = expectedColor[2];
+        float a = expectedColor[3];
+        //We are giving 0.1 buffer as colors might not be exactly same as input color
+        assertTrue(Math.abs(r - (actualColor[0]/255)) < 0.1f);
+        assertTrue(Math.abs(g - (actualColor[1]/255)) < 0.1f);
+        assertTrue(Math.abs(b - (actualColor[2]/255)) < 0.1f);
+        //assertTrue(Math.abs(a - (actualColor[3]/255)) < 0.1f);
+    }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/Constants.java b/tests/tests/opengl/src/android/opengl/cts/Constants.java
index 9bd1acc..cba455a 100644
--- a/tests/tests/opengl/src/android/opengl/cts/Constants.java
+++ b/tests/tests/opengl/src/android/opengl/cts/Constants.java
@@ -18,4 +18,5 @@
 public class Constants {
     public static final int SHADER = 1;
     public static final int PROGRAM = 2;
+    public static final int COLOR = 3;
 }
diff --git a/tests/tests/opengl/src/android/opengl/cts/GL2JniLibOne.java b/tests/tests/opengl/src/android/opengl/cts/GL2JniLibOne.java
index 26de6ff..c306fc7 100755
--- a/tests/tests/opengl/src/android/opengl/cts/GL2JniLibOne.java
+++ b/tests/tests/opengl/src/android/opengl/cts/GL2JniLibOne.java
@@ -18,11 +18,12 @@
 
 public class GL2JniLibOne {
      static {
-         System.loadLibrary("opengltest");
+         System.loadLibrary("opengltest_jni");
      }
 
-     public static native void init(int category, int subcategory);
+     public static native void init(int category, int subcategory, int width, int height);
      public static native void step();
+     public static native float[] draw(int category, int subcategory, float[] color);
 
      public static native int getAttachShaderError();
      public static native int getLoadShaderError();
diff --git a/tests/tests/opengl/src/android/opengl/cts/NativeAttachShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/NativeAttachShaderTest.java
index dbe3ea6..9985e87 100755
--- a/tests/tests/opengl/src/android/opengl/cts/NativeAttachShaderTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/NativeAttachShaderTest.java
@@ -20,24 +20,20 @@
 import android.test.ActivityInstrumentationTestCase2;
 
 public class NativeAttachShaderTest
-        extends ActivityInstrumentationTestCase2<OpenGLES20NativeActivity> {
+        extends ActivityInstrumentationTestCase2<OpenGLES20NativeActivityOne> {
 
-    public NativeAttachShaderTest(Class<OpenGLES20NativeActivity> activityClass) {
-        super(activityClass);
-    }
-
-    private OpenGLES20NativeActivity mActivity;
+    private OpenGLES20NativeActivityOne mActivity;
 
     public NativeAttachShaderTest() {
-        super(OpenGLES20NativeActivity.class);
+        super(OpenGLES20NativeActivityOne.class);
     }
 
-    private OpenGLES20NativeActivity getShaderActivity(int viewType, int viewIndex) {
+    private OpenGLES20NativeActivityOne getShaderActivity(int viewType, int viewIndex) {
         Intent intent = new Intent();
-        intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_TYPE, viewType);
-        intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_INDEX, viewIndex);
+        intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_TYPE, viewType);
+        intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_INDEX, viewIndex);
         setActivityIntent(intent);
-        OpenGLES20NativeActivity activity = getActivity();
+        OpenGLES20NativeActivityOne activity = getActivity();
         assertTrue(activity.waitForFrameDrawn());
         return activity;
     }
@@ -113,4 +109,37 @@
         int error = mActivity.mRenderer.mAttachShaderError;;
         assertEquals(GLES20.GL_NO_ERROR, error);
     }
+
+    public void test_glAttachShaders_emptyvertexshader_emptyvertexshader() throws Throwable {
+        mActivity = getShaderActivity(Constants.SHADER, 7);
+        int error = mActivity.mRenderer.mAttachShaderError;
+        assertTrue(GLES20.GL_NO_ERROR != error);
+    }
+
+    public void test_glAttachShaders_programobject_attach_fragshaderobject() throws Throwable {
+        mActivity = getShaderActivity(Constants.SHADER, 8);
+        int error = mActivity.mRenderer.mAttachShaderError;
+        // The operations are valid
+        assertEquals(GLES20.GL_NO_ERROR, error);
+    }
+
+    public void test_glAttachShaders_invalidshader_attach_valid_handle() throws Throwable{
+        mActivity = getShaderActivity(Constants.SHADER, 9);
+        int error = mActivity.mRenderer.mAttachShaderError;
+        assertTrue(GLES20.GL_NO_ERROR != error);
+    }
+
+    public void test_glAttachShaders_successfulcompile_attach_frag() throws Throwable {
+        mActivity = getShaderActivity(Constants.SHADER, 10);
+        int shaderCount = mActivity.mRenderer.mShaderCount;
+        assertEquals(1,shaderCount);
+        int error = mActivity.mRenderer.mAttachShaderError;
+        assertEquals(GLES20.GL_NO_ERROR, error);
+    }
+
+    public void test_glAttachShaders_successfulcompile_attach_vert() throws Throwable {
+        mActivity = getShaderActivity(Constants.SHADER, 11);
+        int error = mActivity.mRenderer.mAttachShaderError;
+        assertEquals(GLES20.GL_NO_ERROR, error);
+    }
 }
diff --git a/tests/tests/opengl/src/android/opengl/cts/NativeColorBufferTest.java b/tests/tests/opengl/src/android/opengl/cts/NativeColorBufferTest.java
new file mode 100755
index 0000000..7f4dbb2
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/NativeColorBufferTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+public class NativeColorBufferTest extends ActivityInstrumentationTestCase2<OpenGLES20NativeActivityTwo> {
+    private static final long SLEEP_TIME = 500l;
+    private static final String TAG = NativeColorBufferTest.class.getName();
+    public NativeColorBufferTest(Class<OpenGLES20NativeActivityTwo> activityClass) {
+        super(activityClass);
+    }
+
+    private OpenGLES20NativeActivityTwo mActivity;
+
+    public NativeColorBufferTest() {
+        super(OpenGLES20NativeActivityTwo.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+    }
+
+    public void test_RGBA_1001() throws Throwable {
+        float r = 1.0f;
+        float g = 0.0f;
+        float b = 0.0f;
+        float a = 1.0f;
+        final float[] vertexColors =  getVertexColors(r, g, b, a);
+        mActivity = getActivity();
+        float[] expectedColor = {r, g, b, a};
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_1101() throws Throwable {
+        float r = 1.0f;
+        float g = 1.0f;
+        float b = 0.0f;
+        float a = 1.0f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_1111() throws Throwable {
+        float r = 1.0f;
+        float g = 1.0f;
+        float b = 1.0f;
+        float a = 1.0f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_0101() throws Throwable {
+        float r = 0.0f;
+        float g = 1.0f;
+        float b = 0.0f;
+        float a = 1.0f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_0011() throws Throwable {
+        float r = 0.0f;
+        float g = 0.0f;
+        float b = 1.0f;
+        float a = 1.0f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_0000() throws Throwable {
+        float r = 0.0f;
+        float g = 0.0f;
+        float b = 0.0f;
+        float a = 0.0f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    public void test_RGBA_rand_val_one() throws Throwable {
+        float r = 0.6f;
+        float g = 0.7f;
+        float b = 0.25f;
+        float a = 0.5f;
+        final float[] vertexColors = getVertexColors(r, g, b, a);
+
+        float[] expectedColor = {r, g, b, a};
+        mActivity = getActivity();
+        this.runTestOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setView(Constants.COLOR, 1, vertexColors);
+            }
+        });
+        assertTrue(mActivity.waitForFrameDrawn());
+        float[] actualColor = mActivity.getActualColor();
+        compare(expectedColor, actualColor);
+    }
+
+    private float[] getVertexColors(float r, float g, float b, float a) {
+        float[] vertexColors =
+              { r, g, b, a,
+                r, g, b, a,
+                r, g, b, a
+               };
+        return vertexColors;
+    }
+
+    private void compare(float[] expectedColor, float[] actualColor) {
+        assertNotNull(actualColor);
+        assertEquals(4, actualColor.length);
+        float r = expectedColor[0];
+        float g = expectedColor[1];
+        float b = expectedColor[2];
+        float a = expectedColor[3];
+        //We are giving 0.1 buffer as colors might not be exactly same as input color
+        assertTrue(Math.abs(r - (actualColor[0]/255.0)) < 0.1f);
+        assertTrue(Math.abs(g - (actualColor[1]/255.0)) < 0.1f);
+        assertTrue(Math.abs(b - (actualColor[2]/255.0)) < 0.1f);
+        float actualAlpha = (float) (actualColor[3]/255.0);
+        //Commented as of now as the Alpha being returned is always 1
+        //assertTrue(Math.abs(a - (actualColor[3]/255)) < 0.1f);
+    }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/NativeRendererOneColorBufferTest.java b/tests/tests/opengl/src/android/opengl/cts/NativeRendererOneColorBufferTest.java
new file mode 100755
index 0000000..623daea
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/NativeRendererOneColorBufferTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.opengl.cts;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+import java.util.concurrent.CountDownLatch;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.util.Log;
+
+public class NativeRendererOneColorBufferTest extends RendererBase {
+    private int mProgramObject;
+    private int mWidth;
+    private int mHeight;
+    private FloatBuffer mVertices;
+    private ShortBuffer mIndexBuffer;
+
+    private static String TAG = "HelloTriangleRenderer";
+
+    // Our vertices.
+    private float mVerticesData[] = {
+           -0.5f,  0.5f, 0.0f,  // 0, Top Left
+           -0.5f, -0.5f, 0.0f,  // 1, Bottom Left
+            0.5f, -0.5f, 0.0f,  // 2, Bottom Right
+            0.5f,  0.5f, 0.0f,  // 3, Top Right
+    };
+
+    private float[] mVertexColor = {};
+
+    private short[] mIndices = { 0, 1, 2, 0, 2, 3 };
+    private FloatBuffer mColor;
+
+    public NativeRendererOneColorBufferTest(Context context, CountDownLatch latch) {
+        super(latch);
+    }
+
+    public NativeRendererOneColorBufferTest(Context context, float[] color, CountDownLatch latch) {
+        super(latch);
+        this.mVertexColor = color;
+    }
+
+    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
+
+    }
+
+    public void doOnDrawFrame(GL10 glUnused) {
+      Log.i(TAG,"onDrawFrame start");
+
+      float[] result = GL2JniLibOne.draw(3, 1, mVertexColor);
+      mColorOne = result;
+    }
+
+    public float[] getActualRGBA() {
+        return this.mColorOne;
+    }
+
+    public void onSurfaceChanged(GL10 glUnused, int width, int height) {
+        mWidth = width;
+        mHeight = height;
+        Log.i(TAG,"onSurfaceCreated start");
+        GL2JniLibOne.init(3,1, width, height);
+        Log.i(TAG,"onSurfaceCreated finish");
+    }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java
index a8388c2..5acac32 100644
--- a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java
@@ -89,6 +89,7 @@
         public OpenGLES20View(Context context, int type, int index, CountDownLatch latch) {
             super(context);
             setEGLContextClientVersion(2);
+
             if (type == Constants.SHADER) {
                 if (index == 1) {
                     mRenderer = new RendererOneShaderTest(latch);
@@ -110,6 +111,10 @@
                     mRenderer = new RendererNineShaderTest(latch);
                 } else if(index == 10) {
                     mRenderer = new RendererTenShaderTest(latch);
+                } else if(index == 11) {
+                    mRenderer = new RendererElevenShaderTest(latch);
+                } else if(index == 12) {
+                    mRenderer = new RendererTwelveShaderTest(latch);
                 } else {
                     throw new RuntimeException();
                 }
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityTwo.java b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityTwo.java
new file mode 100755
index 0000000..6bb34e4
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityTwo.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLSurfaceView.Renderer;
+import android.os.Bundle;
+
+import java.lang.InterruptedException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+
+public class OpenGLES20ActivityTwo extends Activity {
+    OpenGLES20View view;
+    Renderer mRenderer;
+    int mRendererType;
+    private CountDownLatch mLatch = new CountDownLatch(1);
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    public boolean waitForFrameDrawn() {
+        boolean result = false;
+        try {
+            result = mLatch.await(10L, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            // just return false
+        }
+        return result;
+    }
+
+    public void setView(int type, int i, float[] vertexColors ) {
+        view = new OpenGLES20View(this,type,i, vertexColors, mLatch);
+        setContentView(view);
+    }
+
+    public void setView(int type, int i) {
+        float[] f = {};
+        view = new OpenGLES20View(this, type, i, f, mLatch)  ;
+        setContentView(view);
+    }
+
+    public int getNoOfAttachedShaders() {
+       return ((RendererBase)mRenderer).mShaderCount[0];
+    }
+
+    public int glGetError() {
+        return ((RendererBase)mRenderer).mError;
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        view.onPause();
+
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if(view != null) {
+            view.onResume();
+        }
+    }
+
+    public float[] getActualColor() {
+        return ((RendererBase) mRenderer).mColorOne;
+    }
+
+    class OpenGLES20View extends GLSurfaceView {
+
+        public OpenGLES20View(Context context, int type, int index, float[] rgba,
+                              CountDownLatch latch) {
+            super(context);
+            setEGLContextClientVersion(2);
+            if(type == Constants.COLOR) {
+                if(index == 1) {
+                    mRenderer = new RendererOneColorBufferTest(context, rgba, latch);
+                }else {
+                    throw new RuntimeException();
+                }
+            }
+            setRenderer(mRenderer);
+        }
+
+        @Override
+        public void setEGLContextClientVersion(int version) {
+            super.setEGLContextClientVersion(version);
+        }
+
+    }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivity.java b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityOne.java
similarity index 81%
rename from tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivity.java
rename to tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityOne.java
index 36f986b..ac4fce5 100755
--- a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivity.java
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityOne.java
@@ -1,23 +1,9 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
 package android.opengl.cts;
 
 import android.app.Activity;
 import android.content.Context;
 import android.opengl.GLSurfaceView;
+
 import android.os.Bundle;
 import android.util.Log;
 import android.view.Window;
@@ -30,7 +16,7 @@
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
-public class OpenGLES20NativeActivity extends Activity {
+public class OpenGLES20NativeActivityOne extends Activity {
 
     public static final String EXTRA_VIEW_TYPE = "viewType";
     public static final String EXTRA_VIEW_INDEX = "viewIndex";
@@ -49,7 +35,6 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-
         Window window = getWindow();
         window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
 
@@ -122,16 +107,16 @@
     }
 
     public void onSurfaceChanged(GL10 gl, int width, int height) {
-
-    }
-
-    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
         Log.i(TAG ,"onSurfaceCreated");
-        GL2JniLibOne.init(mCategory, mTestCase);
+        GL2JniLibOne.init(mCategory, mTestCase, width, height);
         this.mAttachShaderError = GL2JniLibOne.getAttachShaderError();
         Log.i(TAG,"error:" + mAttachShaderError);
         this.mShaderCount = GL2JniLibOne.getAttachedShaderCount();
         Log.i(TAG,"ShaderCount:" + mShaderCount);
         mLatch.countDown();
     }
+
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+
+    }
 }
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityTwo.java b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityTwo.java
new file mode 100755
index 0000000..6bdf95f
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityTwo.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLSurfaceView.Renderer;
+import android.os.Bundle;
+
+import java.lang.InterruptedException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class OpenGLES20NativeActivityTwo extends Activity {
+    OpenGLES20View view;
+    Renderer mRenderer;
+    int mRendererType;
+
+    private CountDownLatch mLatch = new CountDownLatch(1);
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    public boolean waitForFrameDrawn() {
+        boolean result = false;
+        try {
+            result = mLatch.await(10L, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            // just return false
+        }
+        return result;
+    }
+
+    public void setView(int type, int i, float[] vertexColors ) {
+        view = new OpenGLES20View(this,type,i, vertexColors, mLatch);
+        setContentView(view);
+    }
+
+    public void setView(int type, int i) {
+
+    }
+
+    public int getNoOfAttachedShaders() {
+       return ((RendererBase)mRenderer).mShaderCount[0];
+    }
+
+    public int glGetError() {
+        return ((RendererBase)mRenderer).mError;
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        if(view != null) {
+            view.onPause();
+        }
+
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        if(view != null) {
+            view.onResume();
+        }
+    }
+
+    public float[] getActualColor() {
+        return ((RendererBase) mRenderer).mColorOne;
+    }
+
+    class OpenGLES20View extends GLSurfaceView {
+
+        @Override
+        public void onPause() {
+            super.onPause();
+        }
+
+        @Override
+        public void onResume() {
+            super.onResume();
+        }
+
+        public OpenGLES20View(Context context, int type, int index, float[] rgba,
+                              CountDownLatch latch) {
+            super(context);
+            setEGLContextClientVersion(2);
+            if(type == Constants.COLOR) {
+                if(index == 1) {
+                    mRenderer = new NativeRendererOneColorBufferTest(context, rgba, latch);
+                }else {
+                    throw new RuntimeException();
+                }
+            }
+            setRenderer(mRenderer);
+        }
+
+        @Override
+        public void setEGLContextClientVersion(int version) {
+            super.setEGLContextClientVersion(version);
+        }
+
+    }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/ProgramTest.java b/tests/tests/opengl/src/android/opengl/cts/ProgramTest.java
index 4c59070..a69c8e5 100644
--- a/tests/tests/opengl/src/android/opengl/cts/ProgramTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/ProgramTest.java
@@ -29,8 +29,8 @@
 
     private OpenGLES20ActivityOne getShaderActivity(int viewType, int viewIndex) {
         Intent intent = new Intent();
-        intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_TYPE, viewType);
-        intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_INDEX, viewIndex);
+        intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_TYPE, viewType);
+        intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_INDEX, viewIndex);
         setActivityIntent(intent);
         return getActivity();
     }
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererBase.java b/tests/tests/opengl/src/android/opengl/cts/RendererBase.java
index d015fcd..994c1c6 100644
--- a/tests/tests/opengl/src/android/opengl/cts/RendererBase.java
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererBase.java
@@ -30,6 +30,7 @@
     FloatBuffer floatBuffer;
     int mProgram;
     int maPositionHandle;
+    float[] mColorOne = new float[4];
 
     int[] mShaderCount = null;
     int mError;
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererElevenShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/RendererElevenShaderTest.java
new file mode 100755
index 0000000..35df7b5
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererElevenShaderTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+import java.util.concurrent.CountDownLatch;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+
+public class RendererElevenShaderTest extends RendererBase {
+    private String fragmentShaderCode = Vertex.successfulcompile_vertex;
+
+    public RendererElevenShaderTest(CountDownLatch latch) {
+        super(latch);
+    }
+
+    @Override
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+        mProgram =  GLES20.glCreateProgram();
+
+        GLES20.glAttachShader(mProgram, fragmentShader);
+        GLES20.glLinkProgram(mProgram);
+
+        mError = GLES20.glGetError();
+        mLatch.countDown();
+    }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererOneColorBufferTest.java b/tests/tests/opengl/src/android/opengl/cts/RendererOneColorBufferTest.java
new file mode 100755
index 0000000..50a4085
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererOneColorBufferTest.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.opengl.cts;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+import java.util.concurrent.CountDownLatch;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.util.Log;
+
+public class RendererOneColorBufferTest extends RendererBase {
+    private int mProgramObject;
+    private int mWidth;
+    private int mHeight;
+    private FloatBuffer mVertices;
+    private ShortBuffer mIndexBuffer;
+
+    private static String TAG = "HelloTriangleRenderer";
+
+    // Our vertices.
+    private float mVerticesData[] = {
+           -0.5f,  0.5f, 0.0f,  // 0, Top Left
+           -0.5f, -0.5f, 0.0f,  // 1, Bottom Left
+            0.5f, -0.5f, 0.0f,  // 2, Bottom Right
+            0.5f,  0.5f, 0.0f,  // 3, Top Right
+    };
+
+    private float[] mVertexColor = {1.0f,0.0f,0.0f,1.0f,
+            1.0f,0.0f,0.0f,1.0f,
+            1.0f,0.0f,0.0f,1.0f,
+            1.0f,0.0f,0.0f,1.0f};
+
+    // The order we like to connect them.
+    private short[] mIndices = { 0, 1, 2, 0, 2, 3 };
+    private FloatBuffer mColor;
+
+
+    public RendererOneColorBufferTest(Context context, CountDownLatch latch) {
+        super(latch);
+        mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4)
+        .order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mVertices.put(mVerticesData).position(0);
+
+        ByteBuffer ibb = ByteBuffer.allocateDirect(mIndices.length * 2);
+        ibb.order(ByteOrder.nativeOrder());
+        mIndexBuffer = ibb.asShortBuffer();
+        mIndexBuffer.put(mIndices);
+        mIndexBuffer.position(0);
+
+        mColor = ByteBuffer.allocateDirect(mVertexColor.length*4).
+                order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mColor.put(mVertexColor).position(0);
+    }
+
+    public RendererOneColorBufferTest(Context context, float[] colors, CountDownLatch latch) {
+        super(latch);
+        mVertexColor = colors;
+        mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4)
+        .order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mVertices.put(mVerticesData).position(0);
+
+        ByteBuffer ibb = ByteBuffer.allocateDirect(mIndices.length * 2);
+        ibb.order(ByteOrder.nativeOrder());
+        mIndexBuffer = ibb.asShortBuffer();
+        mIndexBuffer.put(mIndices);
+        mIndexBuffer.position(0);
+
+        mColor = ByteBuffer.allocateDirect(mVertexColor.length*4).
+                order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mColor.put(mVertexColor).position(0);
+    }
+
+    private int LoadShader(int type, String shaderSrc) {
+        int shader;
+        int[] compiled = new int[1];
+
+        // Create the shader object
+        shader = GLES20.glCreateShader(type);
+
+        if (shader == 0)
+            return 0;
+
+        // Load the shader source
+        GLES20.glShaderSource(shader, shaderSrc);
+
+        // Compile the shader
+        GLES20.glCompileShader(shader);
+
+        // Check the compile status
+        GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
+
+        if (compiled[0] == 0) {
+            Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
+            GLES20.glDeleteShader(shader);
+            return 0;
+        }
+        return shader;
+    }
+
+
+    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
+        String vShaderStr =
+              "attribute vec4 vPosition;    \n"
+            + "attribute vec4 vColor;       \n"
+            + "varying vec4 varyColor;      \n"
+            + "void main()                  \n"
+            + "{                            \n"
+            + "   gl_Position = vPosition;  \n"
+            + "   varyColor = vColor;       \n"
+            + "}                            \n";
+
+        String fShaderStr =
+            "precision mediump float;       \n"
+            + "varying vec4 varyColor;      \n"
+            + "void main()                  \n"
+            + "{                            \n"
+            + "  gl_FragColor = varyColor;  \n"
+            + "}                            \n";
+
+        int vertexShader;
+        int fragmentShader;
+        int programObject;
+        int[] linked = new int[1];
+
+        // Load the vertex/fragment shaders
+        vertexShader = LoadShader(GLES20.GL_VERTEX_SHADER, vShaderStr);
+        fragmentShader = LoadShader(GLES20.GL_FRAGMENT_SHADER, fShaderStr);
+
+        // Create the program object
+        programObject = GLES20.glCreateProgram();
+
+        if (programObject == 0)
+            return;
+
+        GLES20.glAttachShader(programObject, vertexShader);
+        GLES20.glAttachShader(programObject, fragmentShader);
+
+        // Bind vPosition to attribute 0
+        GLES20.glBindAttribLocation(programObject, 0, "vPosition");
+        GLES20.glBindAttribLocation(programObject, 1, "vColor");
+
+        // Link the program
+        GLES20.glLinkProgram(programObject);
+
+        // Check the link status
+        GLES20.glGetProgramiv(programObject, GLES20.GL_LINK_STATUS, linked, 0);
+
+        if (linked[0] == 0)
+        {
+            Log.e(TAG, "Error linking program:");
+            Log.e(TAG, GLES20.glGetProgramInfoLog(programObject));
+            GLES20.glDeleteProgram(programObject);
+            return;
+        }
+
+        // Store the program object
+        mProgramObject = programObject;
+
+        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    }
+
+    public void doOnDrawFrame(GL10 glUnused)
+    {
+        // Set the viewport
+        GLES20.glViewport(0, 0, mWidth, mHeight);
+
+        // Clear the color buffer
+        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+
+        // Use the program object
+        GLES20.glUseProgram(mProgramObject);
+
+        // Load the vertex data
+        GLES20.glVertexAttribPointer(0,3, GLES20.GL_FLOAT, false, 0, mVertices);
+        GLES20.glEnableVertexAttribArray(0);
+
+        int mColorHandle = GLES20.glGetAttribLocation(mProgramObject, "vColor");
+        GLES20.glVertexAttribPointer(mColorHandle,4, GLES20.GL_FLOAT, false, 0, mColor);
+        GLES20.glEnableVertexAttribArray(1);
+
+        GLES20.glDrawElements(GLES20.GL_TRIANGLES, mIndices.length, 
+                GLES20.GL_UNSIGNED_SHORT, mIndexBuffer);
+
+        int x = 1;
+        int y =1;
+        IntBuffer   pinbuffer   = IntBuffer.allocate(1*1*4);
+        IntBuffer   poutbuffer  = IntBuffer.allocate(x*y*4);
+           int         i,j,z;
+           int []      pin         = pinbuffer.array();
+           int []      pout        = poutbuffer.array();
+
+        GLES20.glReadPixels(mWidth/2, mWidth/2, 1, 1, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE,
+                pinbuffer);
+        int pixel = pin[0];
+        float a = (pixel >> 24) & 0xFF;
+        float b = (pixel >> 16) & 0xFF;
+        float g = (pixel >> 8) & 0xFF;
+        float r = pixel & 0xFF;
+        Log.i(TAG,"rgba" + r + " " + g + " " + b + " " + a);
+        mColorOne[0] = r;
+        mColorOne[1] = g;
+        mColorOne[2] = b;
+        mColorOne[3] = a;
+    }
+
+    public float[] getActualRGBA() {
+        return this.mColorOne;
+    }
+
+    public void onSurfaceChanged(GL10 glUnused, int width, int height) {
+        mWidth = width;
+        mHeight = height;
+    }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererTwelveShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/RendererTwelveShaderTest.java
new file mode 100755
index 0000000..a3dab8e
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererTwelveShaderTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+import java.util.concurrent.CountDownLatch;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+
+public class RendererTwelveShaderTest extends RendererBase {
+    private String fragmentShaderCode = Shaders.successfulcompile_frag;
+
+    public RendererTwelveShaderTest(CountDownLatch latch) {
+        super(latch);
+    }
+
+    @Override
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+        //invalid value
+        mProgram =  0;
+
+        GLES20.glAttachShader(mProgram, fragmentShader);
+        GLES20.glLinkProgram(mProgram);
+
+        mError = GLES20.glGetError();
+        mLatch.countDown();
+    }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/Vertex.java b/tests/tests/opengl/src/android/opengl/cts/Vertex.java
new file mode 100755
index 0000000..5041167
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/Vertex.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+public class Vertex {
+    public static String successfulcompile_vertex =
+          "attribute vec3 gtf_Normal; \n"
+        + "attribute vec4 gtf_Vertex; \n"
+        + "uniform mat3 gtf_NormalMatrix; \n"
+        + "uniform mat4 gtf_ModelViewMatrix; \n"
+        + "uniform mat4 gtf_ModelViewProjectionMatrix; \n"
+        + "\n"
+        + "varying float lightIntensity; \n"
+        + "varying vec3 Position; \n"
+        + "uniform vec3 LightPosition; \n"
+        + "uniform float Scale; \n"
+        + "\n"
+        + "void main(void) { \n"
+        + "    vec4 pos = gtf_ModelViewMatrix * gtf_Vertex; \n"
+        + "    Position = vec3(gtf_Vertex) * Scale; \n"
+        + "    vec3 tnorm = normalize(gtf_NormalMatrix * gtf_Normal); \n"
+        + "    lightIntensity = dot(normalize(LightPosition - vec3(pos)), tnorm) * 1.5; \n"
+        + "    gl_Position = gtf_ModelViewProjectionMatrix * gtf_Vertex; \n"
+        + "}";
+}
diff --git a/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java b/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java
index aa8874c..7e06697 100644
--- a/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java
+++ b/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java
@@ -20,14 +20,17 @@
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.StaticLayout;
+import android.text.TextDirectionHeuristics;
 import android.text.TextPaint;
 import android.text.Layout.Alignment;
 import android.text.style.MetricAffectingSpan;
+import android.util.Log;
 
 public class StaticLayoutLineBreakingTest extends AndroidTestCase {
     // Span test are currently not supported because text measurement uses the MeasuredText
     // internal mWorkPaint instead of the provided MockTestPaint.
     private static final boolean SPAN_TESTS_SUPPORTED = false;
+    private static final boolean DEBUG = false;
 
     private static final float SPACE_MULTI = 1.0f;
     private static final float SPACE_ADD = 0.0f;
@@ -89,7 +92,7 @@
             case 'L': return 50.0f;
             case 'C': return 100.0f; // equals to WIDTH
             case ' ': return 10.0f;
-            case '.': return 0.0f; // 0-width character
+            case '_': return 0.0f; // 0-width character
             case SURR_FIRST: return 7.0f;
             case SURR_SECOND: return 3.0f; // Sum of SURR_FIRST-SURR_SECOND is 10
             default: return 10.0f;
@@ -100,11 +103,13 @@
         return new StaticLayout(source, mTextPaint, width, ALIGN, SPACE_MULTI, SPACE_ADD, false);
     }
 
-    private static StaticLayout getStaticLayout(CharSequence source) {
-        return getStaticLayout(source, WIDTH);
+    private static int[] getBreaks(CharSequence source) {
+        return getBreaks(source, WIDTH);
     }
 
-    private static int[] getBreaks(StaticLayout staticLayout) {
+    private static int[] getBreaks(CharSequence source, int width) {
+        StaticLayout staticLayout = getStaticLayout(source, width);
+
         int[] breaks = new int[staticLayout.getLineCount() - 1];
         for (int line = 0; line < breaks.length; line++) {
             breaks[line] = staticLayout.getLineEnd(line);
@@ -112,14 +117,28 @@
         return breaks;
     }
 
-    private static void layout(CharSequence source, int[] breaks) {
-        StaticLayout staticLayout = getStaticLayout(source);
-        layout(staticLayout, source, breaks);
+    private static void debugLayout(CharSequence source, StaticLayout staticLayout) {
+        if (DEBUG) {
+            int count = staticLayout.getLineCount();
+            Log.i("StaticLayoutLineBreakingTest", "\"" + source.toString() + "\": " +
+                    count + " lines");
+            for (int line = 0; line < count; line++) {
+                int lineStart = staticLayout.getLineStart(line);
+                int lineEnd = staticLayout.getLineEnd(line);
+                Log.i("StaticLayoutLineBreakingTest", "Line " + line + " [" + lineStart + ".." +
+                        lineEnd + "]\t" + source.subSequence(lineStart, lineEnd));
+            }
+        }
     }
 
-    private static void layout(StaticLayout staticLayout, CharSequence source, int[] breaks) {
-        //Log.i("StaticLayoutLineWrappingTest", "String " + source.toString() + "; " +
-        //        staticLayout.getLineCount() + " lines");
+    private static void layout(CharSequence source, int[] breaks) {
+        layout(source, breaks, WIDTH);
+    }
+
+    private static void layout(CharSequence source, int[] breaks, int width) {
+        StaticLayout staticLayout = getStaticLayout(source, width);
+
+        debugLayout(source, staticLayout);
 
         int lineCount = breaks.length + 1;
         assertEquals("Number of lines", lineCount, staticLayout.getLineCount());
@@ -128,9 +147,6 @@
             int lineStart = staticLayout.getLineStart(line);
             int lineEnd = staticLayout.getLineEnd(line);
 
-            //Log.i("StaticLayoutLineWrappingTest", "Line " + line + " [" + lineStart + ".." +
-            //        lineEnd + "]\t" + source.subSequence(lineStart, lineEnd));
-
             if (line == 0) {
                 assertEquals("Line start for first line", 0, lineStart);
             } else {
@@ -145,6 +161,34 @@
         }
     }
 
+    private static void layoutMaxLines(CharSequence source, int[] breaks, int maxLines) {
+        StaticLayout staticLayout = new StaticLayout(source, 0, source.length(), mTextPaint, WIDTH,
+                ALIGN, TextDirectionHeuristics.LTR, SPACE_MULTI, SPACE_ADD, false /* includePad */,
+                null, WIDTH, maxLines);
+
+        debugLayout(source, staticLayout);
+
+        int lineCount = staticLayout.getLineCount();
+        assertTrue("Number of lines", lineCount <= maxLines);
+
+        for (int line = 0; line < lineCount; line++) {
+            int lineStart = staticLayout.getLineStart(line);
+            int lineEnd = staticLayout.getLineEnd(line);
+
+            if (line == 0) {
+                assertEquals("Line start for first line", 0, lineStart);
+            } else {
+                assertEquals("Line start for line " + line, breaks[line - 1], lineStart);
+            }
+
+            if (line == lineCount - 1 && line != breaks.length - 1) {
+                assertEquals("Line end for last line", source.length(), lineEnd);
+            } else {
+                assertEquals("Line end for line " + line, breaks[line], lineEnd);
+            }
+        }
+    }
+
     final static int MAX_SPAN_COUNT = 10;
     final static int[] spanStarts = new int[MAX_SPAN_COUNT];
     final static int[] spanEnds = new int[MAX_SPAN_COUNT];
@@ -218,7 +262,7 @@
         layout("  XX  XXX  ", NO_BREAK);
         layout("XX XXX XXX ", NO_BREAK);
         layout("XX XXX XXX     ", NO_BREAK);
-        layout("XXXXXXXXXX     ", new int[] {10}); // Bug, should be NO_BREAK as above
+        layout("XXXXXXXXXX     ", NO_BREAK);
         //      01234567890
     }
 
@@ -235,18 +279,18 @@
         layout("XXXXXXX XXX", new int[] {8});
         layout("XXXXXX XXXX", new int[] {7});
         //      01234567890
-        layout("LL LL", new int[] {2, 3}); // Bug: should be {3}
+        layout("LL LL", new int[] {3});
         layout("LLLL", new int[] {2});
-        layout("C C", new int[] {1, 2}); // Bug: should be {2}
+        layout("C C", new int[] {2});
         layout("CC", new int[] {1});
     }
 
     public void testSpaceAtBreak() {
         //      0123456789012
         layout("XXXX XXXXX X", new int[] {11});
-        layout("XXXXXXXXXX X", new int[] {10}); // Bug: should be {11}. Consume spaces in the non ok case too
-        layout("XXXXXXXXXV X", new int[] {10}); // Bug: should be {11}
-        layout("C X", new int[] {1}); // Should be 2
+        layout("XXXXXXXXXX X", new int[] {11});
+        layout("XXXXXXXXXV X", new int[] {11});
+        layout("C X", new int[] {2});
     }
 
     public void testMultipleSpacesAtBreak() {
@@ -260,10 +304,10 @@
 
     public void testZeroWidthCharacters() {
         //      0123456789012345678901234
-        layout("X.X.X.X.X.X.X.X.X.X", NO_BREAK);
-        layout("...X.X.X.X.X.X.X.X.X.X...", NO_BREAK);
-        layout("C.X", new int[] {2});
-        layout("C..X", new int[] {3});
+        layout("X_X_X_X_X_X_X_X_X_X", NO_BREAK);
+        layout("___X_X_X_X_X_X_X_X_X_X___", NO_BREAK);
+        layout("C_X", new int[] {2});
+        layout("C__X", new int[] {3});
     }
 
     /**
@@ -289,11 +333,6 @@
         layout(spanify("012 456 89 <LXX> XX XX"), new int[] {11, 18});
     }
 
-    public void testWithOverlappingSpans() {
-        // TODO Also try overlapping spans. The current implementation does not care, but would be
-        // good to have before any serious refactoring.
-    }
-
     /*
      * Adding a span to the string should not change the layout, since the metrics are unchanged.
      */
@@ -307,8 +346,7 @@
 
         for (String text : texts) {
             // Get the line breaks without any span
-            StaticLayout sl = getStaticLayout(text);
-            int[] breaks = getBreaks(sl);
+            int[] breaks = getBreaks(text);
 
             // Add spans on all possible offsets
             for (int spanStart = 0; spanStart < text.length(); spanStart++) {
@@ -333,8 +371,7 @@
 
         for (String text : texts) {
             // Get the line breaks without any span
-            StaticLayout sl = getStaticLayout(text);
-            int[] breaks = getBreaks(sl);
+            int[] breaks = getBreaks(text);
 
             // Add spans on all possible offsets
             for (int spanStart1 = 0; spanStart1 < text.length(); spanStart1++) {
@@ -355,8 +392,82 @@
         }
     }
 
-    public void testBreakCondition() {
-        // Try all the different line break characters, space, tab, ','...
+    public static String replace(String string, char c, char r) {
+        return string.replaceAll(String.valueOf(c), String.valueOf(r));
+    }
+
+    public void testClassIS() {
+        char[] classISCharacters = new char[] {'.', ',', ':', ';'};
+        char[] digitCharacters = new char[] {'0', '\u0660', '\u06F0', '\u0966', '\uFF10'};
+
+        for (char c : classISCharacters) {
+            // .,:; are class IS breakpoints...
+            //              01234567
+            layout(replace("L XXX#X", '#', c), new int[] {6});
+            layout(replace("L XXXX#X", '#', c), new int[] {2});
+
+            // ...except when adjacent to digits
+            for (char d : digitCharacters) {
+                //                      01234567
+                layout(replace(replace("L XX0#X", '#', c), '0', d), new int[] {2});
+                layout(replace(replace("L XXX#0", '#', c), '0', d), new int[] {2});
+                layout(replace(replace("L XXX0#X", '#', c), '0', d), new int[] {2});
+                layout(replace(replace("L XXXX#0", '#', c), '0', d), new int[] {2});
+            }
+        }
+    }
+
+    public void testClassSYandHY() {
+        char[] classSYorHYCharacters = new char[] {'/', '-'};
+        char[] digitCharacters = new char[] {'0', '\u0660', '\u06F0', '\u0966', '\uFF10'};
+
+        for (char c : classSYorHYCharacters) {
+            // / is a class SY breakpoint, - a class HY...
+            //              01234567
+            layout(replace("L XXX#X", '#', c), new int[] {6});
+            layout(replace("L XXXX#X", '#', c), new int[] {2});
+
+            // ...except when followed by a digits
+            for (char d : digitCharacters) {
+                //                      01234567
+                layout(replace(replace("L XX0#X", '#', c), '0', d), new int[] {6});
+                layout(replace(replace("L XXX#0", '#', c), '0', d), new int[] {2});
+                layout(replace(replace("L XXX0#X", '#', c), '0', d), new int[] {2});
+                layout(replace(replace("L XXXX#0", '#', c), '0', d), new int[] {2});
+            }
+        }
+    }
+
+    public void testClassID() {
+        char ideographic = '\u8a9e'; // regular ideographic character
+        char hyphen = '\u30A0'; // KATAKANA-HIRAGANA DOUBLE HYPHEN, ideographic but non starter
+
+        // Single ideographs are normal characters
+        layout("L XXX" + ideographic, NO_BREAK);
+        layout("L XXX" + ideographic + "X", new int[] {2});
+        layout("L XXXX" + ideographic, new int[] {2});
+        layout("L XXXX" + ideographic + "X", new int[] {2});
+
+        // Two adjacent ideographs create a possible breakpoint
+        layout("L X" + ideographic + ideographic + "X", NO_BREAK);
+        layout("L X" + ideographic + ideographic + "XX", new int[] {4});
+        layout("L XX" + ideographic + ideographic + "XX", new int[] {5});
+        layout("L XXX" + ideographic + ideographic + "X", new int[] {6});
+        layout("L XXXX" + ideographic + ideographic + "X", new int[] {2});
+
+        // Except when the second one is a non starter
+        layout("L X" + ideographic + hyphen + "X", NO_BREAK);
+        layout("L X" + ideographic + hyphen + "XX", new int[] {2});
+        layout("L XX" + ideographic + hyphen + "XX", new int[] {2});
+        layout("L XXX" + ideographic + hyphen + "X", new int[] {2});
+        layout("L XXXX" + ideographic + hyphen + "X", new int[] {2});
+
+        // When the non-starter is first, a pair of ideographic characters is a line break
+        layout("L X" + hyphen + ideographic + "X", NO_BREAK);
+        layout("L X" + hyphen + ideographic + "XX", new int[] {4});
+        layout("L XX" + hyphen + ideographic + "XX", new int[] {5});
+        layout("L XXX" + hyphen + ideographic + "X", new int[] {6});
+        layout("L XXXX" + hyphen + ideographic + "X", new int[] {2});
     }
 
     public void testReplacementSpan() {
@@ -387,19 +498,58 @@
 
     public void testNarrowWidth() {
         int[] widths = new int[] { 0, 4, 10 };
-        String[] texts = new String[] { "", "X", " ", "XX", "XX ", "X ", "XXX", "XXX ", "X X",
-            " X X " /* Bug "X  X", ".X..", "  ", "XX  ", "X." should work too */ };
+        String[] texts = new String[] { "", "X", " ", "XX", " X", "XXX" };
 
         for (String text: texts) {
             // 15 is such that only one character will fit
-            StaticLayout reference = getStaticLayout(text, 15);
-            int[] breaks = getBreaks(reference);
+            int[] breaks = getBreaks(text, 15);
 
             // Width under 15 should all lead to the same line break
             for (int width: widths) {
-                StaticLayout sl = getStaticLayout(text, width);
-                layout(sl, text, breaks);
+                layout(text, breaks, width);
             }
         }
     }
+
+    public void testNarrowWidthWithSpace() {
+        int[] widths = new int[] { 0, 4 };
+        for (int width: widths) {
+            layout("X ", new int[] {1}, width);
+            layout("X  ", new int[] {1}, width);
+            layout("XX ", new int[] {1, 2}, width);
+            layout("XX  ", new int[] {1, 2}, width);
+            layout("X  X", new int[] {1, 3}, width);
+            layout("X X", new int[] {1, 2}, width);
+
+            layout(" ", NO_BREAK, width);
+            layout(" X", new int[] {1}, width);
+            layout("  ", NO_BREAK, width);
+            layout(" X X", new int[] {1, 2, 3}, width);
+            layout("  X", new int[] {2}, width);
+        }
+    }
+
+    public void testNarrowWidthZeroWidth() {
+        int[] widths = new int[] { 0, 4 };
+        for (int width: widths) {
+            layout("X.", new int[] {1}, width);
+            layout("X__", new int[] {1}, width);
+            layout("X__X", new int[] {1, 3}, width); // Could be {1}
+            layout("X__X_", new int[] {1, 3, 4}, width); // Could be {1, 4}
+
+            layout("_", NO_BREAK, width);
+            layout("__", NO_BREAK, width);
+            layout("_X", new int[] {1}, width); // Could be NO_BREAK
+            layout("_X_", new int[] {1, 2}, width); // Could be {2}
+            layout("_X__", new int[] {1, 2}, width); // Could be {2}
+        }
+    }
+
+    public void testMaxLines() {
+        layoutMaxLines("C", NO_BREAK, 1);
+        layoutMaxLines("C C", new int[] {2}, 1);
+        layoutMaxLines("C C", new int[] {2}, 2);
+        layoutMaxLines("CC", new int[] {1}, 1);
+        layoutMaxLines("CC", new int[] {1}, 2);
+    }
 }
diff --git a/tests/tests/text/src/android/text/format/cts/TimeTest.java b/tests/tests/text/src/android/text/format/cts/TimeTest.java
index c1587ae..98ba55f 100644
--- a/tests/tests/text/src/android/text/format/cts/TimeTest.java
+++ b/tests/tests/text/src/android/text/format/cts/TimeTest.java
@@ -125,6 +125,49 @@
         }
     }
 
+    public void testParseNull() {
+        Time t = new Time();
+        try {
+            t.parse(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            t.parse3339(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    // http://code.google.com/p/android/issues/detail?id=16002
+    // We'd leak one JNI global reference each time parsing failed.
+    // This would cause a crash when we filled the global reference table.
+    public void testBug16002() {
+        Time t = new Time();
+        for (int i = 0; i < 8192; ++i) {
+            try {
+                t.parse3339("xxx");
+                fail();
+            } catch (TimeFormatException expected) {
+            }
+        }
+    }
+
+    // http://code.google.com/p/android/issues/detail?id=22225
+    // We'd leak one JNI global reference each time parsing failed.
+    // This would cause a crash when we filled the global reference table.
+    public void testBug22225() {
+        Time t = new Time();
+        for (int i = 0; i < 8192; ++i) {
+            try {
+                t.parse("xxx");
+                fail();
+            } catch (TimeFormatException expected) {
+            }
+        }
+    }
+
     public void testIsEpoch() {
         Time time = new Time();
         assertTrue(Time.isEpoch(time));
diff --git a/tests/tests/view/src/android/view/cts/GravityTest.java b/tests/tests/view/src/android/view/cts/GravityTest.java
index 86bbb2c..86b1283 100644
--- a/tests/tests/view/src/android/view/cts/GravityTest.java
+++ b/tests/tests/view/src/android/view/cts/GravityTest.java
@@ -16,6 +16,7 @@
 
 package android.view.cts;
 
+import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View;
 
 import android.graphics.Rect;
@@ -288,4 +289,55 @@
         assertEquals(30, inoutRect.top);
         assertEquals(50, inoutRect.bottom);
     }
+
+    @SmallTest
+    public void testGetAbsoluteGravity() throws Exception {
+        assertOneGravity(Gravity.LEFT, Gravity.LEFT, false);
+        assertOneGravity(Gravity.LEFT, Gravity.LEFT, true);
+
+        assertOneGravity(Gravity.RIGHT, Gravity.RIGHT, false);
+        assertOneGravity(Gravity.RIGHT, Gravity.RIGHT, true);
+
+        assertOneGravity(Gravity.TOP, Gravity.TOP, false);
+        assertOneGravity(Gravity.TOP, Gravity.TOP, true);
+
+        assertOneGravity(Gravity.BOTTOM, Gravity.BOTTOM, false);
+        assertOneGravity(Gravity.BOTTOM, Gravity.BOTTOM, true);
+
+        assertOneGravity(Gravity.CENTER_VERTICAL, Gravity.CENTER_VERTICAL, false);
+        assertOneGravity(Gravity.CENTER_VERTICAL, Gravity.CENTER_VERTICAL, true);
+
+        assertOneGravity(Gravity.CENTER_HORIZONTAL, Gravity.CENTER_HORIZONTAL, false);
+        assertOneGravity(Gravity.CENTER_HORIZONTAL, Gravity.CENTER_HORIZONTAL, true);
+
+        assertOneGravity(Gravity.CENTER, Gravity.CENTER, false);
+        assertOneGravity(Gravity.CENTER, Gravity.CENTER, true);
+
+        assertOneGravity(Gravity.FILL_VERTICAL, Gravity.FILL_VERTICAL, false);
+        assertOneGravity(Gravity.FILL_VERTICAL, Gravity.FILL_VERTICAL, true);
+
+        assertOneGravity(Gravity.FILL_HORIZONTAL, Gravity.FILL_HORIZONTAL, false);
+        assertOneGravity(Gravity.FILL_HORIZONTAL, Gravity.FILL_HORIZONTAL, true);
+
+        assertOneGravity(Gravity.FILL, Gravity.FILL, false);
+        assertOneGravity(Gravity.FILL, Gravity.FILL, true);
+
+        assertOneGravity(Gravity.CLIP_HORIZONTAL, Gravity.CLIP_HORIZONTAL, false);
+        assertOneGravity(Gravity.CLIP_HORIZONTAL, Gravity.CLIP_HORIZONTAL, true);
+
+        assertOneGravity(Gravity.CLIP_VERTICAL, Gravity.CLIP_VERTICAL, false);
+        assertOneGravity(Gravity.CLIP_VERTICAL, Gravity.CLIP_VERTICAL, true);
+
+        assertOneGravity(Gravity.LEFT, Gravity.START, false);
+        assertOneGravity(Gravity.RIGHT, Gravity.START, true);
+
+        assertOneGravity(Gravity.RIGHT, Gravity.END, false);
+        assertOneGravity(Gravity.LEFT, Gravity.END, true);
+    }
+
+    private void assertOneGravity(int expected, int initial, boolean isRtl) {
+        final int layoutDirection = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
+
+        assertEquals(expected, Gravity.getAbsoluteGravity(initial, layoutDirection));
+    }
 }
diff --git a/tests/tests/view/src/android/view/cts/LocaleUtilTest.java b/tests/tests/view/src/android/view/cts/LocaleUtilTest.java
new file mode 100644
index 0000000..5be1f99
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/LocaleUtilTest.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.cts;
+
+import android.test.AndroidTestCase;
+import android.util.LocaleUtil;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.util.Locale;
+
+import static android.view.View.LAYOUT_DIRECTION_LTR;
+import static android.view.View.LAYOUT_DIRECTION_RTL;
+
+/**
+ * Test {@link LocaleUtil}.
+ */
+public class LocaleUtilTest extends AndroidTestCase {
+
+    @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "getLayoutDirectionFromLocale",
+            args = {Locale.class}
+    )
+    public void testGetLayoutDirectionFromLocale() {
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(null));
+
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.ENGLISH));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.FRANCE));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.FRENCH));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMAN));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMANY));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALIAN));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALY));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.UK));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.US));
+
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.ROOT));
+
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINA));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINESE));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPAN));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPANESE));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREA));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREAN));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.PRC));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.TAIWAN));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE));
+
+        Locale locale = new Locale("ar");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "AE");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "BH");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "DZ");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "EG");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "IQ");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "JO");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "KW");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "LB");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "LY");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "MA");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "OM");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "QA");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "SA");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "SD");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "SY");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "TN");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "YE");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("fa");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("fa", "AF");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("fa", "IR");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+// TODO: uncomment when ICU is fixed (4.8.1.1 version of ICS broke the following unit tests)
+//        locale = new Locale("iw");
+//        assertEquals(LAYOUT_DIRECTION_RTL,
+//                LocaleUtil.getLayoutDirectionFromLocale(locale));
+//        locale = new Locale("iw", "IL");
+//        assertEquals(LAYOUT_DIRECTION_RTL,
+//                LocaleUtil.getLayoutDirectionFromLocale(locale));
+//        locale = new Locale("he");
+//        assertEquals(LAYOUT_DIRECTION_RTL,
+//                LocaleUtil.getLayoutDirectionFromLocale(locale));
+//        locale = new Locale("he", "IL");
+//        assertEquals(LAYOUT_DIRECTION_RTL,
+//                LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("pa_Arab");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("pa_Arab", "PK");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("ps");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ps", "AF");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("ur");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ur", "IN");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ur", "PK");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("uz_Arab");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("uz_Arab", "AF");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+        // Locale without a real language
+        locale = new Locale("zz");
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                LocaleUtil.getLayoutDirectionFromLocale(locale));
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupTest.java b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
index e975a27..1fc9a88 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
@@ -1496,6 +1496,8 @@
         assertEquals(0, vg.getPaddingTop());
         assertEquals(0, vg.getPaddingLeft());
         assertEquals(0, vg.getPaddingRight());
+        assertEquals(0, vg.getPaddingStart());
+        assertEquals(0, vg.getPaddingEnd());
 
         vg.setPadding(left, top, right, bottom);
 
@@ -1503,6 +1505,83 @@
         assertEquals(top, vg.getPaddingTop());
         assertEquals(left, vg.getPaddingLeft());
         assertEquals(right, vg.getPaddingRight());
+
+        assertEquals(left, vg.getPaddingStart());
+        assertEquals(right, vg.getPaddingEnd());
+        assertEquals(false, vg.isPaddingRelative());
+
+        // force RTL direction
+        vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+        assertEquals(bottom, vg.getPaddingBottom());
+        assertEquals(top, vg.getPaddingTop());
+        assertEquals(left, vg.getPaddingLeft());
+        assertEquals(right, vg.getPaddingRight());
+
+        assertEquals(right, vg.getPaddingStart());
+        assertEquals(left, vg.getPaddingEnd());
+        assertEquals(false, vg.isPaddingRelative());
+    }
+
+    public void testSetPaddingRelative() {
+        final int start = 1;
+        final int top = 2;
+        final int end = 3;
+        final int bottom = 4;
+
+        MockViewGroup vg = new MockViewGroup(mContext);
+
+        assertEquals(0, vg.getPaddingBottom());
+        assertEquals(0, vg.getPaddingTop());
+        assertEquals(0, vg.getPaddingLeft());
+        assertEquals(0, vg.getPaddingRight());
+        assertEquals(0, vg.getPaddingStart());
+        assertEquals(0, vg.getPaddingEnd());
+
+        vg.setPaddingRelative(start, top, end, bottom);
+
+        assertEquals(bottom, vg.getPaddingBottom());
+        assertEquals(top, vg.getPaddingTop());
+        assertEquals(start, vg.getPaddingLeft());
+        assertEquals(end, vg.getPaddingRight());
+
+        assertEquals(start, vg.getPaddingStart());
+        assertEquals(end, vg.getPaddingEnd());
+        assertEquals(true, vg.isPaddingRelative());
+
+        // force RTL direction after setting relative padding
+        vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+        assertEquals(bottom, vg.getPaddingBottom());
+        assertEquals(top, vg.getPaddingTop());
+        assertEquals(end, vg.getPaddingLeft());
+        assertEquals(start, vg.getPaddingRight());
+
+        assertEquals(start, vg.getPaddingStart());
+        assertEquals(end, vg.getPaddingEnd());
+        assertEquals(true, vg.isPaddingRelative());
+
+        // force RTL direction before setting relative padding
+        vg = new MockViewGroup(mContext);
+        vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+        assertEquals(0, vg.getPaddingBottom());
+        assertEquals(0, vg.getPaddingTop());
+        assertEquals(0, vg.getPaddingLeft());
+        assertEquals(0, vg.getPaddingRight());
+        assertEquals(0, vg.getPaddingStart());
+        assertEquals(0, vg.getPaddingEnd());
+
+        vg.setPaddingRelative(start, top, end, bottom);
+
+        assertEquals(bottom, vg.getPaddingBottom());
+        assertEquals(top, vg.getPaddingTop());
+        assertEquals(end, vg.getPaddingLeft());
+        assertEquals(start, vg.getPaddingRight());
+
+        assertEquals(start, vg.getPaddingStart());
+        assertEquals(end, vg.getPaddingEnd());
+        assertEquals(true, vg.isPaddingRelative());
     }
 
     public void testSetPersistentDrawingCache() {
diff --git a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
index d92fd9b..453e200 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
@@ -83,5 +83,90 @@
 
         assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.startMargin);
         assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.endMargin);
+
+        assertEquals(false, mMarginLayoutParams.isMarginRelative());
+    }
+
+    public void testSetMarginsRelative() {
+        // create a new MarginLayoutParams instance
+        mMarginLayoutParams = new ViewGroup.MarginLayoutParams(320, 480);
+        mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+        assertEquals(20, mMarginLayoutParams.startMargin);
+        assertEquals(30, mMarginLayoutParams.topMargin);
+        assertEquals(120, mMarginLayoutParams.endMargin);
+        assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+        assertEquals(0, mMarginLayoutParams.leftMargin);
+        assertEquals(0, mMarginLayoutParams.rightMargin);
+
+        assertEquals(true, mMarginLayoutParams.isMarginRelative());
+    }
+
+    public void testResolveMarginsRelative() {
+        ViewGroup vg = new LinearLayout(mContext);
+
+        // LTR / normal margin case
+        mMarginLayoutParams = new ViewGroup.MarginLayoutParams(320, 480);
+        mMarginLayoutParams.setMargins(20, 30, 120, 140);
+        vg.setLayoutParams(mMarginLayoutParams);
+        vg.requestLayout();
+
+        assertEquals(20, mMarginLayoutParams.leftMargin);
+        assertEquals(30, mMarginLayoutParams.topMargin);
+        assertEquals(120, mMarginLayoutParams.rightMargin);
+        assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+        assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.startMargin);
+        assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.endMargin);
+
+        assertEquals(false, mMarginLayoutParams.isMarginRelative());
+
+        // LTR / relative margin case
+        mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+        vg.setLayoutParams(mMarginLayoutParams);
+        vg.requestLayout();
+
+        assertEquals(20, mMarginLayoutParams.startMargin);
+        assertEquals(30, mMarginLayoutParams.topMargin);
+        assertEquals(120, mMarginLayoutParams.endMargin);
+        assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+        assertEquals(20, mMarginLayoutParams.leftMargin);
+        assertEquals(120, mMarginLayoutParams.rightMargin);
+
+        assertEquals(true, mMarginLayoutParams.isMarginRelative());
+
+        // RTL / normal margin case
+        vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+        mMarginLayoutParams = new ViewGroup.MarginLayoutParams(320, 480);
+        mMarginLayoutParams.setMargins(20, 30, 120, 140);
+        vg.setLayoutParams(mMarginLayoutParams);
+        vg.requestLayout();
+
+        assertEquals(20, mMarginLayoutParams.leftMargin);
+        assertEquals(30, mMarginLayoutParams.topMargin);
+        assertEquals(120, mMarginLayoutParams.rightMargin);
+        assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+        assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.startMargin);
+        assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.endMargin);
+
+        assertEquals(false, mMarginLayoutParams.isMarginRelative());
+
+        // RTL / relative margin case
+        mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+        vg.setLayoutParams(mMarginLayoutParams);
+        vg.requestLayout();
+
+        assertEquals(20, mMarginLayoutParams.startMargin);
+        assertEquals(30, mMarginLayoutParams.topMargin);
+        assertEquals(120, mMarginLayoutParams.endMargin);
+        assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+        assertEquals(120, mMarginLayoutParams.leftMargin);
+        assertEquals(20, mMarginLayoutParams.rightMargin);
+
+        assertEquals(true, mMarginLayoutParams.isMarginRelative());
     }
 }
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 9065592..4387564 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -3388,11 +3388,6 @@
         public void childAccessibilityStateChanged(View child) {
 
         }
-
-        @Override
-        public View findViewToTakeAccessibilityFocusFromHover(View child, View descendant) {
-            return null;
-        }
     }
 
     private final class OnCreateContextMenuListenerImpl implements OnCreateContextMenuListener {
diff --git a/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java b/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
index 760a160..0198b10 100755
--- a/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
@@ -515,13 +515,11 @@
         // re-set 'clicked' flag to false
         listener.clearItemClickedStatus();
 
-
         runTestOnUiThread(new Runnable() {
             public void run() {
                 mAutoCompleteTextView.showDropDown();
             }
         });
-        mInstrumentation.waitForIdleSync();
         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
         assertTrue(listener.isOnItemClicked());
@@ -534,7 +532,6 @@
                 mAutoCompleteTextView.showDropDown();
             }
         });
-        mInstrumentation.waitForIdleSync();
         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
         // Test normal key code.
         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
@@ -550,7 +547,7 @@
                mAutoCompleteTextView.dismissDropDown();
             }
         });
-        mInstrumentation.waitForIdleSync();
+
         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
         assertFalse(listener.isOnItemClicked());
diff --git a/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java b/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java
new file mode 100644
index 0000000..2c4c798
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.ViewGroup;
+import android.widget.*;
+import com.android.cts.stub.R;
+
+import static android.view.View.LAYOUT_DIRECTION_LTR;
+import static android.view.View.LAYOUT_DIRECTION_RTL;
+import static android.view.View.LAYOUT_DIRECTION_INHERIT;
+import static android.view.View.LAYOUT_DIRECTION_LOCALE;
+
+public class LayoutDirectionTest extends ActivityInstrumentationTestCase2<LayoutDirectionStubActivity> {
+
+    public LayoutDirectionTest() {
+        super(LayoutDirectionStubActivity.class);
+    }
+
+    private void checkDefaultDirectionForOneLayoutWithCode(ViewGroup vg) {
+        assertEquals(LAYOUT_DIRECTION_INHERIT, vg.getLayoutDirection());
+        assertEquals(LAYOUT_DIRECTION_LTR, vg.getResolvedLayoutDirection());
+    }
+
+    @UiThreadTest
+    public void testLayoutDirectionDefaults() {
+        checkDefaultDirectionForOneLayoutWithCode(new LinearLayout(getActivity()));
+        checkDefaultDirectionForOneLayoutWithCode(new FrameLayout(getActivity()));
+        checkDefaultDirectionForOneLayoutWithCode(new TableLayout(getActivity()));
+        checkDefaultDirectionForOneLayoutWithCode(new RelativeLayout(getActivity()));
+        checkDefaultDirectionForOneLayoutWithCode(new GridLayout(getActivity()));
+    }
+
+    private void checkDirectionForOneLayoutWithCode(ViewGroup vg) {
+        vg.setLayoutDirection(LAYOUT_DIRECTION_LTR);
+        assertEquals(LAYOUT_DIRECTION_LTR, vg.getLayoutDirection());
+        assertEquals(LAYOUT_DIRECTION_LTR, vg.getResolvedLayoutDirection());
+
+        vg.setLayoutDirection(LAYOUT_DIRECTION_RTL);
+        assertEquals(LAYOUT_DIRECTION_RTL, vg.getLayoutDirection());
+        assertEquals(LAYOUT_DIRECTION_RTL, vg.getResolvedLayoutDirection());
+
+        vg.setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
+        assertEquals(LAYOUT_DIRECTION_LOCALE, vg.getLayoutDirection());
+        // running with English locale
+        assertEquals(LAYOUT_DIRECTION_LTR, vg.getResolvedLayoutDirection());
+
+        vg.setLayoutDirection(LAYOUT_DIRECTION_INHERIT);
+        assertEquals(LAYOUT_DIRECTION_INHERIT, vg.getLayoutDirection());
+        // default is LTR
+        assertEquals(LAYOUT_DIRECTION_LTR, vg.getResolvedLayoutDirection());
+    }
+
+    @UiThreadTest
+    public void testDirectionForAllLayoutsWithCode() {
+        checkDirectionForOneLayoutWithCode(new LinearLayout(getActivity()));
+        checkDirectionForOneLayoutWithCode(new FrameLayout(getActivity()));
+        checkDirectionForOneLayoutWithCode(new TableLayout(getActivity()));
+        checkDirectionForOneLayoutWithCode(new RelativeLayout(getActivity()));
+        checkDirectionForOneLayoutWithCode(new GridLayout(getActivity()));
+    }
+
+    private void checkDirectionInheritanceForOneLayoutWithCode(ViewGroup parent) {
+        LinearLayout child = new LinearLayout(getActivity());
+        child.setLayoutDirection(LAYOUT_DIRECTION_INHERIT);
+        parent.addView(child);
+
+        // Parent is LTR
+        parent.setLayoutDirection(LAYOUT_DIRECTION_LTR);
+
+        assertEquals(LAYOUT_DIRECTION_LTR, parent.getLayoutDirection());
+        assertEquals(LAYOUT_DIRECTION_LTR, parent.getResolvedLayoutDirection());
+
+        assertEquals(LAYOUT_DIRECTION_INHERIT, child.getLayoutDirection());
+        assertEquals(LAYOUT_DIRECTION_LTR, child.getResolvedLayoutDirection());
+
+        // Parent is RTL
+        parent.setLayoutDirection(LAYOUT_DIRECTION_RTL);
+
+        assertEquals(LAYOUT_DIRECTION_RTL, parent.getLayoutDirection());
+        assertEquals(LAYOUT_DIRECTION_RTL, parent.getResolvedLayoutDirection());
+
+        assertEquals(LAYOUT_DIRECTION_INHERIT, child.getLayoutDirection());
+        assertEquals(LAYOUT_DIRECTION_RTL, child.getResolvedLayoutDirection());
+    }
+
+    @UiThreadTest
+    public void testDirectionInheritanceForAllLayoutsWithCode() {
+        checkDirectionInheritanceForOneLayoutWithCode(new LinearLayout(getActivity()));
+        checkDirectionInheritanceForOneLayoutWithCode(new FrameLayout(getActivity()));
+        checkDirectionInheritanceForOneLayoutWithCode(new TableLayout(getActivity()));
+        checkDirectionInheritanceForOneLayoutWithCode(new RelativeLayout(getActivity()));
+        checkDirectionInheritanceForOneLayoutWithCode(new GridLayout(getActivity()));
+    }
+
+    private void checkDirectionForOneLayoutFromXml(int parentId, int parentDir, int parentResDir,
+                                                   int child1Id, int child1Dir, int child1ResDir,
+                                                   int child2Id, int child2Dir, int child2ResDir,
+                                                   int child3Id, int child3Dir, int child3ResDir,
+                                                   int child4Id, int child4Dir, int child4ResDir) {
+        ViewGroup ll = (ViewGroup) getActivity().findViewById(parentId);
+        assertEquals(parentDir, ll.getLayoutDirection());
+        assertEquals(parentResDir, ll.getResolvedLayoutDirection());
+
+        ViewGroup child1 = (ViewGroup) getActivity().findViewById(child1Id);
+        assertEquals(child1Dir, child1.getLayoutDirection());
+        assertEquals(child1ResDir, child1.getResolvedLayoutDirection());
+
+        ViewGroup child2 = (ViewGroup) getActivity().findViewById(child2Id);
+        assertEquals(child2Dir, child2.getLayoutDirection());
+        assertEquals(child2ResDir, child2.getResolvedLayoutDirection());
+
+        ViewGroup child3 = (ViewGroup) getActivity().findViewById(child3Id);
+        assertEquals(child3Dir, child3.getLayoutDirection());
+        assertEquals(child3ResDir, child3.getResolvedLayoutDirection());
+
+        ViewGroup child4 = (ViewGroup) getActivity().findViewById(child4Id);
+        assertEquals(child4Dir, child4.getLayoutDirection());
+        assertEquals(child4ResDir, child4.getResolvedLayoutDirection());
+    }
+
+    @UiThreadTest
+    public void testDirectionFromXml() {
+        // We only test LinearLayout as the others would be the same (they extend ViewGroup / View)
+        checkDirectionForOneLayoutFromXml(
+                R.id.layout_linearlayout_ltr, LAYOUT_DIRECTION_LTR, LAYOUT_DIRECTION_LTR,
+                R.id.layout_linearlayout_ltr_child_1, LAYOUT_DIRECTION_LTR, LAYOUT_DIRECTION_LTR,
+                R.id.layout_linearlayout_ltr_child_2, LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_RTL,
+                // parent is LTR
+                R.id.layout_linearlayout_ltr_child_3, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LTR,
+                // running with English locale
+                R.id.layout_linearlayout_ltr_child_4, LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR);
+
+        checkDirectionForOneLayoutFromXml(
+                R.id.layout_linearlayout_rtl, LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_RTL,
+                R.id.layout_linearlayout_rtl_child_1, LAYOUT_DIRECTION_LTR, LAYOUT_DIRECTION_LTR,
+                R.id.layout_linearlayout_rtl_child_2, LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_RTL,
+                // parent is RTL
+                R.id.layout_linearlayout_rtl_child_3, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_RTL,
+                // running with English locale
+                R.id.layout_linearlayout_rtl_child_4, LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR);
+
+        checkDirectionForOneLayoutFromXml(
+                // default is LTR
+                R.id.layout_linearlayout_inherit, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LTR,
+                R.id.layout_linearlayout_inherit_child_1, LAYOUT_DIRECTION_LTR, LAYOUT_DIRECTION_LTR,
+                R.id.layout_linearlayout_inherit_child_2, LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_RTL,
+                // parent is LTR
+                R.id.layout_linearlayout_inherit_child_3, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LTR,
+                // running with English locale
+                R.id.layout_linearlayout_inherit_child_4, LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR);
+
+        checkDirectionForOneLayoutFromXml(
+                // running with English locale
+                R.id.layout_linearlayout_locale, LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR,
+                R.id.layout_linearlayout_locale_child_1, LAYOUT_DIRECTION_LTR, LAYOUT_DIRECTION_LTR,
+                R.id.layout_linearlayout_locale_child_2, LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_RTL,
+                // parent is LTR
+                R.id.layout_linearlayout_locale_child_3, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LTR,
+                // running with English locale
+                R.id.layout_linearlayout_locale_child_4, LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR);
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
index 4c9d2ab..e034562 100644
--- a/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
@@ -160,6 +160,167 @@
         assertEquals(R.id.relative_view3, rules[RelativeLayout.ALIGN_BOTTOM]);
     }
 
+    public void testStartEnd() {
+        RelativeLayout.LayoutParams layoutParams;
+
+        // Test RelativeLayout.Params which generated from the xml file.
+        int rules[];
+        RelativeLayoutStubActivity activity = getActivity();
+
+        // test attributes used in RelativeLayout.
+        RelativeLayout relativeLayout = (RelativeLayout) activity.findViewById(
+                R.id.relative_sublayout_attrs_2);
+
+        // view1, centered within its parent.
+        // TEST: android:layout_centerInParent
+        View view1 = activity.findViewById(R.id.relative_view21);
+        ViewAsserts.assertHorizontalCenterAligned(relativeLayout, view1);
+        ViewAsserts.assertVerticalCenterAligned(relativeLayout, view1);
+        layoutParams = (RelativeLayout.LayoutParams) (view1.getLayoutParams());
+        rules = layoutParams.getRules();
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_IN_PARENT]);
+
+        // view2, below view1 and has same left position with view1.
+        // TEST: android:layout_below; android:layout_alignStart
+        View view2 = activity.findViewById(R.id.relative_view22);
+        ViewAsserts.assertLeftAligned(view1, view2);
+        assertEquals(view1.getBottom(), view2.getTop());
+        layoutParams = (RelativeLayout.LayoutParams) (view2.getLayoutParams());
+        rules = layoutParams.getRules();
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.BELOW]);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_START]);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_LEFT]);
+        assertEquals(0, rules[RelativeLayout.ALIGN_RIGHT]);
+        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.BELOW]);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_START]);
+        assertEquals(0, rules[RelativeLayout.ALIGN_LEFT]);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_RIGHT]);
+
+        // view3, has same top position with view1 and same bottom position with view2,
+        // and on the right of view1.1.
+        // TEST: android:layout_alignTop; android:layout_alignBottom; android:layout_toEndOf
+        View view3 = activity.findViewById(R.id.relative_view23);
+        ViewAsserts.assertTopAligned(view1, view3);
+        ViewAsserts.assertBottomAligned(view2, view3);
+        assertEquals(view1.getRight(), view3.getLeft());
+        layoutParams = (RelativeLayout.LayoutParams) (view3.getLayoutParams());
+        rules = layoutParams.getRules();
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_TOP]);
+        assertEquals(R.id.relative_view22, rules[RelativeLayout.ALIGN_BOTTOM]);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.END_OF]);
+        assertEquals(0, rules[RelativeLayout.LEFT_OF]);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.RIGHT_OF]);
+        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_TOP]);
+        assertEquals(R.id.relative_view22, rules[RelativeLayout.ALIGN_BOTTOM]);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.END_OF]);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.LEFT_OF]);
+        assertEquals(0, rules[RelativeLayout.RIGHT_OF]);
+
+        // view4, has same right position with view3 and above view3.
+        // TEST: android:layout_alignEnd; android:layout_above
+        View view4 = activity.findViewById(R.id.relative_view24);
+        ViewAsserts.assertRightAligned(view3, view4);
+        assertEquals(view3.getTop(), view4.getBottom());
+        layoutParams = (RelativeLayout.LayoutParams) (view4.getLayoutParams());
+        rules = layoutParams.getRules();
+        assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_END]);
+        assertEquals(0, rules[RelativeLayout.ALIGN_LEFT]);
+        assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_RIGHT]);
+        assertEquals(R.id.relative_view23, rules[RelativeLayout.ABOVE]);
+        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_END]);
+        assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_LEFT]);
+        assertEquals(0, rules[RelativeLayout.ALIGN_RIGHT]);
+        assertEquals(R.id.relative_view23, rules[RelativeLayout.ABOVE]);
+
+        // view5 goes on the left-bottom.
+        // TEST: android:layout_alignParentBottom; android:layout_alignParentStart
+        View view5 = activity.findViewById(R.id.relative_view25);
+        ViewAsserts.assertLeftAligned(relativeLayout, view5);
+        ViewAsserts.assertBottomAligned(relativeLayout, view5);
+        layoutParams = (RelativeLayout.LayoutParams) (view5.getLayoutParams());
+        rules = layoutParams.getRules();
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_BOTTOM]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_START]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
+        assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
+        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_BOTTOM]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_START]);
+        assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
+
+        // view6 goes on the top-right.
+        // TEST: android:layout_alignParentTop; android:layout_alignParentEnd
+        View view6 = activity.findViewById(R.id.relative_view26);
+        ViewAsserts.assertTopAligned(relativeLayout, view6);
+        ViewAsserts.assertRightAligned(relativeLayout, view6);
+        layoutParams = (RelativeLayout.LayoutParams) (view6.getLayoutParams());
+        rules = layoutParams.getRules();
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_TOP]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_END]);
+        assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
+        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_TOP]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_END]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
+        assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
+
+        // view7, has same baseline with view6 and centered horizontally within its parent.
+        // TEST: android:layout_alignBaseline; android:layout_centerHorizontal
+        View view7 = activity.findViewById(R.id.relative_view27);
+        ViewAsserts.assertBaselineAligned(view6, view7);
+        ViewAsserts.assertHorizontalCenterAligned(relativeLayout, view7);
+        layoutParams = (RelativeLayout.LayoutParams) (view7.getLayoutParams());
+        rules = layoutParams.getRules();
+        assertEquals(R.id.relative_view26, rules[RelativeLayout.ALIGN_BASELINE]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_HORIZONTAL]);
+        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        assertEquals(R.id.relative_view26, rules[RelativeLayout.ALIGN_BASELINE]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_HORIZONTAL]);
+
+        // view8, centered vertically within its parent and on the left of view1.
+        // TEST: android:layout_toStartOf; android:layout_centerVertical
+        View view8 = activity.findViewById(R.id.relative_view28);
+        ViewAsserts.assertVerticalCenterAligned(relativeLayout, view8);
+        assertEquals(view1.getLeft(), view8.getRight());
+        layoutParams = (RelativeLayout.LayoutParams) (view8.getLayoutParams());
+        rules = layoutParams.getRules();
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.START_OF]);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.LEFT_OF]);
+        assertEquals(0, rules[RelativeLayout.RIGHT_OF]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_VERTICAL]);
+        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.START_OF]);
+        assertEquals(0, rules[RelativeLayout.LEFT_OF]);
+        assertEquals(R.id.relative_view21, rules[RelativeLayout.RIGHT_OF]);
+        assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_VERTICAL]);
+
+        // view9, has same top and bottom position with view3 and same left position with its parent
+        // TEST: android:layout_alignStart; android:layout_alignTop; android:layout_alignBottom;
+        // android:layout_alignWithParentIfMissing
+        View view9 = activity.findViewById(R.id.relative_view29);
+        ViewAsserts.assertTopAligned(view3, view9);
+        ViewAsserts.assertBottomAligned(view3, view9);
+        ViewAsserts.assertLeftAligned(relativeLayout, view9);
+        layoutParams = (RelativeLayout.LayoutParams) (view9.getLayoutParams());
+        rules = layoutParams.getRules();
+        assertEquals(R.id.gravity_bottom, rules[RelativeLayout.ALIGN_START]);
+        assertEquals(R.id.gravity_bottom, rules[RelativeLayout.ALIGN_LEFT]);
+        assertEquals(0, rules[RelativeLayout.ALIGN_RIGHT]);
+        assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_TOP]);
+        assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_BOTTOM]);
+        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        assertEquals(R.id.gravity_bottom, rules[RelativeLayout.ALIGN_START]);
+        assertEquals(0, rules[RelativeLayout.ALIGN_LEFT]);
+        assertEquals(R.id.gravity_bottom, rules[RelativeLayout.ALIGN_RIGHT]);
+        assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_TOP]);
+        assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_BOTTOM]);
+    }
+
     public void testAccessRule1() {
         RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(200, 300);
         int rules[]= layoutParams.getRules();
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index e295c40..24a8440 100755
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -2984,6 +2984,299 @@
                 outText.text.toString());
     }
 
+    @UiThreadTest
+    public void testTextDirectionDefault() {
+        TextView tv = new TextView(mActivity);
+        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getTextDirection());
+    }
+
+    @UiThreadTest
+    public void testSetGetTextDirection() {
+        TextView tv = new TextView(mActivity);
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
+    }
+
+    @UiThreadTest
+    public void testGetResolvedTextDirectionLtr() {
+        TextView tv = new TextView(mActivity);
+        tv.setText("this is a test");
+
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getResolvedTextDirection());
+    }
+
+    @UiThreadTest
+    public void testGetResolvedTextDirectionLtrWithInheritance() {
+        LinearLayout ll = new LinearLayout(mActivity);
+        ll.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+
+        TextView tv = new TextView(mActivity);
+        tv.setText("this is a test");
+        ll.addView(tv);
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getResolvedTextDirection());
+    }
+
+    @UiThreadTest
+    public void testGetResolvedTextDirectionRtl() {
+        TextView tv = new TextView(mActivity);
+        tv.setText("\u05DD\u05DE"); // hebrew
+
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getResolvedTextDirection());
+    }
+
+    @UiThreadTest
+    public void testGetResolvedTextDirectionRtlWithInheritance() {
+        LinearLayout ll = new LinearLayout(mActivity);
+        ll.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+
+        TextView tv = new TextView(mActivity);
+        tv.setText("\u05DD\u05DE"); // hebrew
+        ll.addView(tv);
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getResolvedTextDirection());
+
+        // Force to RTL text direction on the layout
+        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getResolvedTextDirection());
+    }
+
+    @UiThreadTest
+    public void testResetTextDirection() {
+        LinearLayout ll = (LinearLayout) mActivity.findViewById(R.id.layout_textviewtest);
+        TextView tv = (TextView) mActivity.findViewById(R.id.textview_rtl);
+
+        ll.setTextDirection(View.TEXT_DIRECTION_RTL);
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+        ll.removeView(tv);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+    }
+
+    @UiThreadTest
+    public void testTextAlignmentDefault() {
+        TextView tv = new TextView(getActivity());
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
+        // resolved default text alignment is GRAVITY
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getResolvedTextAlignment());
+    }
+
+    @UiThreadTest
+    public void testSetGetTextAlignment() {
+        TextView tv = new TextView(getActivity());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment());
+    }
+
+    @UiThreadTest
+    public void testGetResolvedTextAlignment() {
+        TextView tv = new TextView(getActivity());
+
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getResolvedTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getResolvedTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getResolvedTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getResolvedTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getResolvedTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getResolvedTextAlignment());
+    }
+
+    @UiThreadTest
+    public void testGetResolvedTextAlignmentWithInheritance() {
+        LinearLayout ll = new LinearLayout(getActivity());
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
+
+        TextView tv = new TextView(getActivity());
+        ll.addView(tv);
+
+        // check defaults
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getResolvedTextAlignment());
+
+        // set inherit and check that child is following parent
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
+        assertEquals(View.TEXT_ALIGNMENT_INHERIT, tv.getTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getResolvedTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getResolvedTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getResolvedTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getResolvedTextAlignment());
+
+        // now get rid of the inheritance but still change the parent
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+    }
+
+    @UiThreadTest
+    public void testResetTextAlignment() {
+        TextViewStubActivity activity = getActivity();
+
+        LinearLayout ll = (LinearLayout) activity.findViewById(R.id.layout_textviewtest);
+        TextView tv = (TextView) activity.findViewById(R.id.textview_rtl);
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+        ll.removeView(tv);
+        // default text alignment is GRAVITY
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getResolvedTextAlignment());
+    }
+
     private static class MockOnEditorActionListener implements OnEditorActionListener {
         private boolean isOnEditorActionCalled;
 
diff --git a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
index 995408a..1039b17 100644
--- a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
+++ b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
@@ -65,7 +65,7 @@
         List<String> sourcePath = new ArrayList<String>();
         sourcePath.add("./frameworks/base/core/java");
         sourcePath.add("./frameworks/base/test-runner/src");
-        sourcePath.add("./libcore/junit/src/main/java");
+        sourcePath.add("./external/junit/src");
         sourcePath.add("./development/tools/hosttestlib/src");
         sourcePath.add("./libcore/dalvik/src/main/java");
         sourcePath.add("./cts/tests/src");
diff --git a/tools/device-setup/TestDeviceSetup/Android.mk b/tools/device-setup/TestDeviceSetup/Android.mk
index 413f50b..5642736 100644
--- a/tools/device-setup/TestDeviceSetup/Android.mk
+++ b/tools/device-setup/TestDeviceSetup/Android.mk
@@ -21,6 +21,8 @@
 LOCAL_MODULE_TAGS := optional
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+# and because it is in data, do not strip classes.dex
+LOCAL_DEX_PREOPT := false
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
index 5ad7e25..f53507d 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
@@ -31,7 +31,7 @@
     @Option(name="cts-install-path", description="the path to the cts installation to use")
     private String mCtsRootDirPath = System.getProperty("CTS_ROOT");
 
-    public static final String CTS_BUILD_VERSION = "4.1_r1";
+    public static final String CTS_BUILD_VERSION = "4.0_r1";
 
     /**
      * {@inheritDoc}
diff --git a/tools/utils/rerun.py b/tools/utils/rerun.py
new file mode 100644
index 0000000..86853a1
--- /dev/null
+++ b/tools/utils/rerun.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import os
+import sys
+from xml.dom import Node
+from xml.dom import minidom
+
+def getChildrenWithTag(parent, tagName):
+    children = []
+    for child in  parent.childNodes:
+        if (child.nodeType == Node.ELEMENT_NODE) and (child.tagName == tagName):
+            #print "parent " + parent.getAttribute("name") + " " + tagName +\
+            #    " " + child.getAttribute("name")
+            children.append(child)
+    return children
+
+def parseSuite(suite, parentName):
+    if parentName != "":
+        parentName += '.'
+    failedCases = []
+    childSuites = getChildrenWithTag(suite, "TestSuite")
+    for child in childSuites:
+        for failure in parseSuite(child, parentName + child.getAttribute("name")):
+            failedCases.append(failure)
+    childTestCases = getChildrenWithTag(suite, "TestCase")
+    for child in childTestCases:
+        className = parentName + child.getAttribute("name")
+        for test in getChildrenWithTag(child, "Test"):
+            if test.getAttribute("result") != "pass":
+                failureName = className + "#" + test.getAttribute("name")
+                failedCases.append(failureName)
+    #if len(failedCases) > 0:
+    #    print failedCases
+    return failedCases
+
+def getFailedCases(resultXml):
+    failedCases = []
+    doc = minidom.parse(resultXml)
+    testResult = doc.getElementsByTagName("TestResult")[0]
+    packages = getChildrenWithTag(testResult, "TestPackage")
+    for package in packages:
+        casesFromChild = parseSuite(package, "")
+        for case in casesFromChild:
+            if case not in failedCases:
+                failedCases.append(case)
+
+    return failedCases
+
+def main(argv):
+    if len(argv) < 3:
+        print "rerun.py cts_path result_xml [-s serial]"
+        print " cts_path should end with android-cts"
+        sys.exit(1)
+    ctsPath = os.path.abspath(argv[1])
+    resultXml = os.path.abspath(argv[2])
+    deviceSerial = ""
+    if len(argv) > 3:
+        if argv[3] == "-s":
+            deviceSerial = argv[4]
+
+    failedCases = getFailedCases(resultXml)
+    print "Re-run follwong cases:"
+    for failure in failedCases:
+        print " " + failure
+    for failure in failedCases:
+        [className, methodName] = failure.split('#')
+        command = ctsPath + "/tools/cts-tradefed run singleCommand cts"
+        if deviceSerial != "":
+            command += " --serial " + deviceSerial
+        command += " --class " + className + " --method " + methodName
+        print command
+        os.system(command)
+
+if __name__ == '__main__':
+    main(sys.argv)