am ceae8ba1: am b855e7f0: FileSystemPermissionTest: Add /data/vpnch

* commit 'ceae8ba11d18792f2cfda1f0a8938f7219dbcf33':
  FileSystemPermissionTest: Add /data/vpnch
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..6fcb9ca 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>
@@ -298,14 +298,15 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
 
-            <meta-data android:name="test_required_features" android:value="android.hardware.camera"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
         </activity>
-
+<!-- Experimental
         <activity android:name=".camera.analyzer.CameraAnalyzerActivity"
                  android:label="@string/camera_analyzer"
                  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" />
 
@@ -315,6 +316,19 @@
             <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
                 android:resource="@xml/accessory_filter_adk" />
         </activity>
+-->
+
+        <activity android:name=".camera.orientation.CameraOrientationActivity"
+                 android:label="@string/camera_orientation"
+                 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" />
+
+            <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
+        </activity>
 
         <activity android:name=".usb.UsbAccessoryTestActivity"
                 android:label="@string/usb_accessory_test"
diff --git a/apps/CtsVerifier/res/layout/co_format_list_item.xml b/apps/CtsVerifier/res/layout/co_format_list_item.xml
new file mode 100644
index 0000000..8196bbf
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/co_format_list_item.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:padding="10dp"
+    android:textSize="16sp"
+/>
diff --git a/apps/CtsVerifier/res/layout/co_main.xml b/apps/CtsVerifier/res/layout/co_main.xml
new file mode 100644
index 0000000..6fd18da
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/co_main.xml
@@ -0,0 +1,135 @@
+<?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="fill_parent"
+    android:layout_height="fill_parent"
+    android:gravity="bottom"
+    android:orientation="vertical" >
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:gravity="bottom"
+        android:orientation="horizontal" >
+
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="fill_parent"
+            android:layout_weight="3"
+            android:gravity="center_vertical|center_horizontal"
+            android:orientation="vertical" >
+
+            <SurfaceView
+                android:id="@+id/camera_view"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:layout_weight="4" />
+
+            <TextView
+                android:id="@+id/preview_label"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:gravity="bottom"
+                android:padding="2dp"
+                android:text="@string/co_preview_label"
+                android:textSize="16sp" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="fill_parent"
+            android:layout_weight="3"
+            android:gravity="center_vertical|center_horizontal"
+            android:orientation="vertical" >
+
+            <ImageView
+                android:id="@+id/format_view"
+                android:layout_height="fill_parent"
+                android:layout_width="fill_parent"
+                android:layout_weight="4" />
+
+            <TextView
+                android:id="@+id/format_label"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:gravity="bottom"
+                android:padding="2dp"
+                android:text="@string/co_format_label"
+                android:textSize="16sp" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="fill_parent"
+            android:layout_weight="2"
+            android:gravity="bottom"
+            android:orientation="vertical" >
+
+            <TextView
+                android:id="@+id/camera_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/co_camera_label" />
+
+            <TextView
+                android:id="@+id/orientation_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/co_orientation_label" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:gravity="bottom"
+                android:orientation="vertical" >
+
+                <TextView
+                    android:id="@+id/instruction_header"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/co_instruction_heading_label" />
+
+                <TextView
+                    android:id="@+id/instruction_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/co_instruction_text_photo_label" />
+
+                <TextView
+                    android:id="@+id/instruction_extra_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content" />
+
+                <Button
+                    android:id="@+id/take_picture_button"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:enabled="true"
+                    android:text="@string/co_photo_button_caption" />
+
+            </LinearLayout>
+
+        </LinearLayout>
+
+    </LinearLayout>
+
+    <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index ab9c244..b088465 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -296,8 +296,27 @@
     <string name="ca_focus_modes_label">Focus Modes</string>
     <string name="ca_info">This test checks the image quality of the camera of this device. It requires a MacBeth 4x6 color checker. With an ADK board and a lamp connected to it on the Relay 1 port, all tests can be run automatically. Without the ADK board, all the tests except the Auto Exposure Lock Test can be run automatically and the Auto Exposure Lock Test will require users to turn on/off a lamp according to the instruction given. </string>
 
-    <!-- Strings for Camera Formats -->
+    <!-- Strings for Camera Orientation -->
+    <string name="camera_orientation">Camera Orientation</string>
+    <string name="co_info">This test checks that the camera output is oriented
+    in the correct direction, for each camera, and for each of four
+    clockwise orientations. Choose \"Pass\" if both the preview window and the
+    still capture image are rotated clockwise by the amount specified. Otherwise,
+    choose \"Fail\". The physical orientation of the device does not matter. Read
+    the message above the \"Take Photo\" button for step-by-step instructions.
+    </string>
+    <string name="co_preview_label">Camera preview</string>
+    <string name="co_format_label">Oriented photo</string>
+    <string name="co_camera_label">Camera:</string>
+    <string name="co_orientation_label">Orientation</string>
+    <string name="co_orientation_direction_label">clockwise</string>
+    <string name="co_instruction_heading_label">Instruction:</string>
+    <string name="co_instruction_text_photo_label">Take a photo</string>
+    <string name="co_instruction_text_passfail_label">Choose pass or fail, or take another photo.</string>
+    <string name="co_instruction_text_extra_label">(mirrored along vertical axis for front-facing camera)</string>
+    <string name="co_photo_button_caption">Take Photo</string>
 
+    <!-- Strings for Camera Formats -->
     <string name="camera_format">Camera Formats</string>
     <string name="cf_info">This test checks that all the supported
     output formats for camera preview callbacks work correctly, and
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/orientation/CameraOrientationActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/orientation/CameraOrientationActivity.java
new file mode 100644
index 0000000..b90f2132
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/orientation/CameraOrientationActivity.java
@@ -0,0 +1,542 @@
+/*
+ * 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.verifier.camera.orientation;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.hardware.Camera;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout.LayoutParams;
+import android.widget.TextView;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestResult;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.TreeSet;
+
+/**
+ * Tests for manual verification of the CDD-required camera output formats
+ * for preview callbacks
+ */
+public class CameraOrientationActivity extends PassFailButtons.Activity
+implements OnClickListener, SurfaceHolder.Callback {
+
+    private static final String TAG = "CameraOrientation";
+    private static final int STATE_OFF = 0;
+    private static final int STATE_PREVIEW = 1;
+    private static final int NUM_ORIENTATIONS = 4;
+    private static final String STAGE_INDEX_EXTRA = "stageIndex";
+
+    private Button mPassButton;
+    private Button mFailButton;
+    private Button mTakePictureButton;
+
+    private SurfaceView mCameraView;
+    private ImageView mFormatView;
+    private SurfaceHolder mSurfaceHolder;
+    private Camera mCamera;
+    private List<Camera.Size> mPreviewSizes;
+    private Camera.Size mOptimalSize;
+    private List<Integer> mPreviewOrientations;
+    private int mNextPreviewOrientation;
+    private int mNumCameras;
+    private int mCurrentCameraId = -1;
+    private int mState = STATE_OFF;
+
+    private StringBuilder mReportBuilder = new StringBuilder();
+    private final TreeSet<String> mTestedCombinations = new TreeSet<String>();
+    private final TreeSet<String> mUntestedCombinations = new TreeSet<String>();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.co_main);
+        setPassFailButtonClickListeners();
+        setInfoResources(R.string.camera_orientation, R.string.co_info, -1);
+        mNumCameras = Camera.getNumberOfCameras();
+
+        mPassButton         = (Button) findViewById(R.id.pass_button);
+        mFailButton         = (Button) findViewById(R.id.fail_button);
+        mTakePictureButton  = (Button) findViewById(R.id.take_picture_button);
+        mFormatView         = (ImageView) findViewById(R.id.format_view);
+        mCameraView         = (SurfaceView) findViewById(R.id.camera_view);
+
+        mFormatView.setOnClickListener(this);
+        mCameraView.setOnClickListener(this);
+        mTakePictureButton.setOnClickListener(this);
+
+        mSurfaceHolder = mCameraView.getHolder();
+        mSurfaceHolder.addCallback(this);
+
+        mPreviewOrientations = new ArrayList<Integer>();
+        mPreviewOrientations.add(0);
+        mPreviewOrientations.add(90);
+        mPreviewOrientations.add(180);
+        mPreviewOrientations.add(270);
+
+        // This activity is reused multiple times
+        // to test each camera/orientation combination
+        final int stageIndex = getIntent().getIntExtra(STAGE_INDEX_EXTRA, 0);
+        Settings settings = getSettings(stageIndex);
+
+        // Hitting the pass button goes to the next test activity.
+        // Only the last one uses the PassFailButtons click callback function,
+        // which gracefully terminates the activity.
+        if (stageIndex + 1 < mNumCameras * NUM_ORIENTATIONS) {
+            setPassButtonGoesToNextStage(stageIndex);
+        }
+
+        String[] availableOrientations = new String[NUM_ORIENTATIONS];
+        for (int i=0; i<availableOrientations.length; i++) {
+            // append degree symbol
+            availableOrientations[i] = Integer.toString(i * 90) + "\u00b0";
+        }
+
+        resetButtons();
+
+        // Set initial values
+        mCurrentCameraId = settings.mCameraId;
+        TextView cameraLabel = (TextView) findViewById(R.id.camera_text);
+        cameraLabel.setText(
+                getString(R.string.co_camera_label)
+                + " " + (mCurrentCameraId+1) + " of " + mNumCameras);
+
+        mNextPreviewOrientation = settings.mOrientation;
+        TextView orientationLabel =
+                (TextView) findViewById(R.id.orientation_text);
+        orientationLabel.setText(
+                getString(R.string.co_orientation_label)
+                + " "
+                + Integer.toString(mNextPreviewOrientation+1)
+                + " of "
+                + Integer.toString(NUM_ORIENTATIONS)
+                + ": "
+                + mPreviewOrientations.get(mNextPreviewOrientation) + "\u00b0"
+                + " "
+                + getString(R.string.co_orientation_direction_label)
+                );
+
+        TextView instructionLabel =
+                (TextView) findViewById(R.id.instruction_text);
+        instructionLabel.setText(R.string.co_instruction_text_photo_label);
+
+        mTakePictureButton.setEnabled(true);
+        setUpCamera(mCurrentCameraId);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        setUpCamera(mCurrentCameraId);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        shutdownCamera();
+    }
+
+    @Override
+    public String getTestDetails() {
+        return mReportBuilder.toString();
+    }
+
+    private void setUpCamera(int id) {
+        shutdownCamera();
+
+        Log.v(TAG, "Setting up Camera " + id);
+        mCurrentCameraId = id;
+
+        try {
+            mCamera = Camera.open(id);
+        } catch (Exception e) {
+            Log.e(TAG, "Error opening camera");
+        }
+
+        Camera.Parameters p = mCamera.getParameters();
+
+        // Get preview resolutions
+        List<Camera.Size> unsortedSizes = p.getSupportedPreviewSizes();
+        class SizeCompare implements Comparator<Camera.Size> {
+            @Override
+            public int compare(Camera.Size lhs, Camera.Size rhs) {
+                if (lhs.width < rhs.width) return -1;
+                if (lhs.width > rhs.width) return 1;
+                if (lhs.height < rhs.height) return -1;
+                if (lhs.height > rhs.height) return 1;
+                return 0;
+            }
+        }
+        SizeCompare s = new SizeCompare();
+        TreeSet<Camera.Size> sortedResolutions = new TreeSet<Camera.Size>(s);
+        sortedResolutions.addAll(unsortedSizes);
+        mPreviewSizes = new ArrayList<Camera.Size>(sortedResolutions);
+
+        startPreview();
+    }
+
+    private void shutdownCamera() {
+        if (mCamera != null) {
+            mCamera.setPreviewCallback(null);
+            mCamera.stopPreview();
+            mCamera.release();
+            mCamera = null;
+            mState = STATE_OFF;
+        }
+    }
+
+    private void startPreview() {
+        if (mState != STATE_OFF) {
+            // Stop for a while to drain callbacks
+            mCamera.setPreviewCallback(null);
+            mCamera.stopPreview();
+            mState = STATE_OFF;
+            Handler h = new Handler();
+            Runnable mDelayedPreview = new Runnable() {
+                @Override
+                public void run() {
+                    startPreview();
+                }
+            };
+            h.postDelayed(mDelayedPreview, 300);
+            return;
+        }
+
+        mState = STATE_PREVIEW;
+        mCamera.setPreviewCallback(mPreviewCallback);
+
+        try {
+            mCamera.setPreviewDisplay(mCameraView.getHolder());
+        } catch (IOException ioe) {
+            Log.e(TAG, "Unable to connect camera to display");
+        }
+
+        Camera.Parameters p = mCamera.getParameters();
+        Log.v(TAG, "Initializing picture format");
+        p.setPictureFormat(ImageFormat.JPEG);
+        mOptimalSize = getOptimalPreviewSize(mPreviewSizes, 640, 480);
+        Log.v(TAG, "Initializing picture size to "
+                + mOptimalSize.width + "x" + mOptimalSize.height);
+        p.setPictureSize(mOptimalSize.width, mOptimalSize.height);
+        Log.v(TAG, "Initializing preview size to "
+                + mOptimalSize.width + "x" + mOptimalSize.height);
+        p.setPreviewSize(mOptimalSize.width, mOptimalSize.height);
+
+        Log.v(TAG, "Setting camera parameters");
+        mCamera.setParameters(p);
+        Log.v(TAG, "Setting color filter");
+        mFormatView.setColorFilter(null);
+        Log.v(TAG, "Starting preview");
+        try {
+            mCamera.startPreview();
+        } catch (Exception e) {
+            Log.d(TAG, "Cannot start preview", e);
+        }
+
+        // set preview orientation
+        int degrees = mPreviewOrientations.get(mNextPreviewOrientation);
+        mCamera.setDisplayOrientation(degrees);
+
+        android.hardware.Camera.CameraInfo info =
+                new android.hardware.Camera.CameraInfo();
+        android.hardware.Camera.getCameraInfo(mCurrentCameraId, info);
+        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+            TextView cameraExtraLabel =
+                    (TextView) findViewById(R.id.instruction_extra_text);
+            cameraExtraLabel.setText(
+                    getString(R.string.co_instruction_text_extra_label));
+        }
+    }
+
+    @Override
+    public void onClick(View view) {
+        Log.v(TAG, "Click detected");
+
+        if (view == mFormatView || view == mTakePictureButton) {
+            Log.v(TAG, "Taking picture");
+            mCamera.takePicture(null, null, null, mCameraCallback);
+        }
+
+        if(view == mPassButton || view == mFailButton) {
+            final int stageIndex =
+                    getIntent().getIntExtra(STAGE_INDEX_EXTRA, 0);
+            String[] cameraNames = new String[mNumCameras];
+            int counter = 0;
+            for (int i = 0; i < mNumCameras; i++) {
+                cameraNames[i] = "Camera " + i;
+
+                for(int j = 0; j < mPreviewOrientations.size(); j++) {
+                    String combination = cameraNames[i] + ", "
+                            + mPreviewOrientations.get(j)
+                            + "\u00b0"
+                            + "\n";
+
+                    if(counter < stageIndex) {
+                        // test already passed, or else wouldn't have made
+                        // it to current stageIndex
+                        mTestedCombinations.add(combination);
+                    }
+
+                    if(counter == stageIndex) {
+                        // current test configuration
+                        if(view == mPassButton) {
+                            mTestedCombinations.add(combination);
+                        }
+                        else if(view == mFailButton) {
+                            mUntestedCombinations.add(combination);
+                        }
+                    }
+
+                    if(counter > stageIndex) {
+                        // test not passed yet, since haven't made it to
+                        // stageIndex
+                        mUntestedCombinations.add(combination);
+                    }
+
+                    counter++;
+                }
+            }
+
+            mReportBuilder = new StringBuilder();
+            mReportBuilder.append("Passed combinations:\n");
+            for (String combination : mTestedCombinations) {
+                mReportBuilder.append(combination);
+            }
+            mReportBuilder.append("Failed/untested combinations:\n");
+            for (String combination : mUntestedCombinations) {
+                mReportBuilder.append(combination);
+            }
+
+            if(view == mPassButton) {
+                TestResult.setPassedResult(this, "CameraOrientationActivity",
+                        getTestDetails());
+            }
+            if(view == mFailButton) {
+                TestResult.setFailedResult(this, "CameraOrientationActivity",
+                        getTestDetails());
+            }
+
+            // restart activity to test next orientation
+            Intent intent = new Intent(CameraOrientationActivity.this,
+                    CameraOrientationActivity.class);
+            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
+                    | Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+            intent.putExtra(STAGE_INDEX_EXTRA, stageIndex + 1);
+            startActivity(intent);
+        }
+    }
+
+    private void resetButtons() {
+        enablePassFailButtons(false);
+    }
+
+    private void enablePassFailButtons(boolean enable) {
+        mPassButton.setEnabled(enable);
+        mFailButton.setEnabled(enable);
+    }
+
+    // find a supported size with ratio less than tolerance threshold, and
+    // which is closest to height and width of given dimensions without
+    // being larger than either of given dimensions
+    private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w,
+            int h) {
+        final double ASPECT_TOLERANCE = 0.1;
+        double targetRatio = (double) 640 / (double) 480;
+        if (sizes == null) return null;
+
+        Camera.Size optimalSize = null;
+        int minDiff = Integer.MAX_VALUE;
+        int curDiff;
+
+        int targetHeight = h;
+        int targetWidth = w;
+
+        boolean aspectRatio = true;
+        while(true) {
+            for (Camera.Size size : sizes) {
+                if(aspectRatio) {
+                    double ratio = (double) size.width / size.height;
+                    if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) {
+                        continue;
+                    }
+                }
+                curDiff = Math.abs(size.height - targetHeight) +
+                        Math.abs(size.width - targetWidth);
+                if (curDiff < minDiff
+                        && size.height <= targetHeight
+                        && size.width <= targetWidth) {
+                    optimalSize = size;
+                    minDiff = curDiff;
+                }
+            }
+            if (optimalSize == null) {
+                // Cannot find a match, so repeat search and
+                // ignore aspect ratio requirement
+                aspectRatio = false;
+                continue;
+            }
+            else {
+                break;
+            }
+        }
+
+        return optimalSize;
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width,
+            int height) {
+        startPreview();
+    }
+
+    private void setTestedConfiguration(int cameraId, int orientation) {
+        String combination = "Camera " + cameraId + ", "
+                + orientation
+                + "\u00b0"
+                + "\n";
+        if (!mTestedCombinations.contains(combination)) {
+            mTestedCombinations.add(combination);
+            mUntestedCombinations.remove(combination);
+        }
+    }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+        // Auto-generated method stub
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // Auto-generated method stub
+    }
+
+    private final Camera.PreviewCallback mPreviewCallback =
+            new Camera.PreviewCallback() {
+        @Override
+        public void onPreviewFrame(byte[] data, Camera camera) {
+            // adjust camera preview to match output image's aspect ratio
+
+            int viewWidth = mFormatView.getWidth();
+            int viewHeight = mFormatView.getHeight();
+            int newWidth, newHeight;
+
+            if (mPreviewOrientations.get(mNextPreviewOrientation) == 0
+                || mPreviewOrientations.get(mNextPreviewOrientation) == 180) {
+                // make preview width same as output image width,
+                // then calculate height using output image's height/width ratio
+                newWidth = viewWidth;
+                newHeight = (int) (viewWidth * ((double) mOptimalSize.height /
+                        (double) mOptimalSize.width));
+            }
+            else {
+                newHeight = viewHeight;
+                newWidth = (int) (viewHeight * ((double) mOptimalSize.height /
+                        (double) mOptimalSize.width));
+            }
+
+            LayoutParams layoutParams = new LayoutParams(newWidth, newHeight);
+            mCameraView.setLayoutParams(layoutParams);
+        }
+    };
+
+    private final Camera.PictureCallback mCameraCallback =
+            new Camera.PictureCallback() {
+        @Override
+        public void onPictureTaken(byte[] data, Camera mCamera) {
+            if (data != null) {
+                Bitmap inputImage;
+                inputImage = BitmapFactory.decodeByteArray(data, 0, data.length);
+
+                int degrees = mPreviewOrientations.get(mNextPreviewOrientation);
+                android.hardware.Camera.CameraInfo info =
+                        new android.hardware.Camera.CameraInfo();
+                android.hardware.Camera.getCameraInfo(mCurrentCameraId, info);
+                float mirrorX[];
+                if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+                    // mirror the image along vertical axis
+                    mirrorX = new float[] {-1, 0, 0, 0, 1, 1, 0, 0, 1};
+                    degrees = (360 - degrees) % 360; // compensate the mirror
+                } else {
+                    // leave image the same via identity matrix
+                    mirrorX = new float[] {1, 0, 0, 0, 1, 0, 0, 0, 1};
+                }
+
+                // use matrix to transform the image
+                Matrix matrixMirrorX = new Matrix();
+                matrixMirrorX.setValues(mirrorX);
+                Matrix mat = new Matrix();
+                mat.postRotate(degrees);
+                mat.postConcat(matrixMirrorX);
+
+                Bitmap inputImageAdjusted = Bitmap.createBitmap(inputImage,
+                        0,
+                        0,
+                        inputImage.getWidth(),
+                        inputImage.getHeight(),
+                        mat,
+                        true);
+                mFormatView.setImageBitmap(inputImageAdjusted);
+
+                Log.v(TAG, "Output image set");
+                enablePassFailButtons(true);
+
+                TextView instructionLabel =
+                        (TextView) findViewById(R.id.instruction_text);
+                instructionLabel.setText(
+                        R.string.co_instruction_text_passfail_label);
+            }
+
+            startPreview();
+        }
+    };
+
+    private void setPassButtonGoesToNextStage(final int stageIndex) {
+        findViewById(R.id.pass_button).setOnClickListener(this);
+    }
+
+    private Settings getSettings(int stageIndex) {
+        int curCameraId = stageIndex / NUM_ORIENTATIONS;
+        int curOrientation = stageIndex % NUM_ORIENTATIONS;
+        return new Settings(stageIndex, curCameraId, curOrientation);
+    }
+
+    // Bundle of settings for testing a particular
+    // camera/orientation combination
+    class Settings {
+        int mCameraId;
+        int mOrientation;
+
+        Settings(int stageIndex, int cameraId, int orientation) {
+            mCameraId = cameraId;
+            mOrientation = orientation;
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
index fd226a6..56a3b44 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
@@ -58,6 +58,14 @@
             long delta = timestamp - mLastActiveTimestamp;
             mLastActiveTimestamp = timestamp;
 
+            if (location.getAccuracy() <= 0.0) {
+                fail(mProvider + " location has invalid accuracy: " + location.getAccuracy());
+            }
+            if (location.getElapsedRealtimeNanos() <= 0) {
+                fail(mProvider + " location has invalid elapsed realtime: " +
+                        location.getElapsedRealtimeNanos());
+            }
+
             if (mNumActiveUpdates != 1 && delta < mMinActiveInterval) {
                 fail(mProvider + " location updated too fast: " + delta + "ms < " +
                         mMinActiveInterval + "ms");
@@ -100,6 +108,14 @@
             long delta = timestamp - mLastPassiveTimestamp;
             mLastPassiveTimestamp = timestamp;
 
+            if (location.getAccuracy() <= 0.0) {
+                fail(mProvider + " location has invalid accuracy: " + location.getAccuracy());
+            }
+            if (location.getElapsedRealtimeNanos() <= 0) {
+                fail(mProvider + " location has invalid elapsed realtime: " +
+                        location.getElapsedRealtimeNanos());
+            }
+
             if (mNumPassiveUpdates != 1 && delta < mMinPassiveInterval) {
                 fail("passive " + mProvider + " location updated too fast: " + delta + "ms < " +
                         mMinPassiveInterval + "ms");
@@ -186,4 +202,4 @@
                 mProvider + " location change");
         return true;
     }
-}
\ No newline at end of file
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/tech/MifareUltralightTagTester.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/tech/MifareUltralightTagTester.java
index 23f4762..038d276 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/tech/MifareUltralightTagTester.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/tech/MifareUltralightTagTester.java
@@ -29,7 +29,7 @@
  */
 public class MifareUltralightTagTester implements TagTester {
 
-    private static final int USER_PAGE_OFFSET = 4;
+    private static final int USER_PAGE_OFFSET = 5;
 
     private static final int NUM_PAGES = 4;
 
@@ -77,4 +77,4 @@
             }
         };
     }
-}
\ No newline at end of file
+}
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..5c28a4f4 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
@@ -17,6 +17,7 @@
 package com.android.cts.appsecurity;
 
 import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
 import com.android.ddmlib.testrunner.TestIdentifier;
@@ -84,6 +85,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";
@@ -206,7 +210,8 @@
             getDevice().uninstallPackage(WRITE_EXTERNAL_STORAGE_APP_PKG);
 
             // stage test file on external storage
-            getDevice().pushString("CAEK", "/sdcard/meow");
+            getDevice().pushString("CAEK",
+                    getDevice().getMountPoint(IDevice.MNT_EXTERNAL_STORAGE) + "/meow");
 
             // mark permission as not enforced
             setPermissionEnforced(getDevice(), READ_EXTERNAL_STORAGE, false);
@@ -311,6 +316,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 +324,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 +340,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/libs/util/src/android/cts/util/TimeoutReq.java b/libs/util/src/android/cts/util/TimeoutReq.java
new file mode 100644
index 0000000..943c3ce
--- /dev/null
+++ b/libs/util/src/android/cts/util/TimeoutReq.java
@@ -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.
+ */
+
+package android.cts.util;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Annotation to specify necessary timeout for the test
+ * timeout is specified in minutes and 0 value means no timeout ( = infinite waiting).
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TimeoutReq {
+    int  minutes() default -1;
+}
diff --git a/suite/pts/Android.mk b/suite/pts/Android.mk
new file mode 100644
index 0000000..07b30e3
--- /dev/null
+++ b/suite/pts/Android.mk
@@ -0,0 +1,18 @@
+#
+# 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 cts/suite/pts/PtsBuild.mk
+include $(call all-subdir-makefiles)
diff --git a/suite/pts/PtsBuild.mk b/suite/pts/PtsBuild.mk
new file mode 100644
index 0000000..4c3d4b2
--- /dev/null
+++ b/suite/pts/PtsBuild.mk
@@ -0,0 +1,129 @@
+#
+# 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.
+#
+
+# several makefiles for CTS merged for PTS
+
+LOCAL_PATH:= $(call my-dir)
+
+# New packages should be added here
+PTS_TEST_PACKAGES = \
+    PtsDeviceFilePerf \
+    PtsDeviceUi \
+    PtsDeviceDram
+
+PTS_SUPPORT_PACKAGES := \
+	TestDeviceSetup
+
+BUILD_PTS_PACKAGE := cts/suite/pts/build/test_package.mk
+
+PTS_JAVA_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-java-scanner
+PTS_JAVA_TEST_SCANNER_DOCLET := $(HOST_OUT_JAVA_LIBRARIES)/cts-java-scanner-doclet.jar
+
+# Generator of test XMLs from scanner output.
+PTS_XML_GENERATOR := $(HOST_OUT_EXECUTABLES)/cts-xml-generator
+
+# File indicating which tests should be blacklisted due to problems.
+PTS_EXPECTATIONS := cts/suite/pts/expectations/knownfailures.txt
+
+PTS_TESTCASES_OUT := $(HOST_OUT)/pts-testcases
+
+define pts-get-package-paths
+	$(foreach pkg,$(1),$(PTS_TESTCASES_OUT)/$(pkg).apk)
+endef
+
+define pts-get-test-xmls
+	$(foreach name,$(1),$(PTS_TESTCASES_OUT)/$(name).xml)
+endef
+
+PTS_TEST_CASE_LIST := \
+	$(PTS_SUPPORT_PACKAGES)
+
+PTS_TEST_CASES := \
+		$(call pts-get-package-paths,$(PTS_TEST_PACKAGES))
+
+PTS_TEST_XMLS := $(call pts-get-test-xmls,$(PTS_TEST_PACKAGES))
+
+pts_dir := $(HOST_OUT)/pts
+pts_tools_src_dir := cts/tools
+
+pts_name := android-pts
+
+DDMLIB_JAR := $(HOST_OUT_JAVA_LIBRARIES)/ddmlib-prebuilt.jar
+junit_host_jar := $(HOST_OUT_JAVA_LIBRARIES)/junit.jar
+HOSTTESTLIB_JAR := $(HOST_OUT_JAVA_LIBRARIES)/hosttestlib.jar
+TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+PTS_TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/cts-tradefed.jar
+PTS_TF_EXEC := $(HOST_OUT_EXECUTABLES)/pts-tradefed
+PTS_TF_README := $(pts_tools_src_dir)/tradefed-host/README
+
+
+DEFAULT_TEST_PLAN := $(pts_dir)/$(pts_name)/resource/plans/PTS.xml
+
+$(pts_dir)/all_pts_files_stamp: PRIVATE_JUNIT_HOST_JAR := $(junit_host_jar)
+
+$(pts_dir)/all_pts_files_stamp: $(PTS_TEST_CASES) $(PTS_TEST_CASE_LIST) $(junit_host_jar) $(HOSTTESTLIB_JAR) $(PTS_HOST_LIBRARY_JARS) $(TF_JAR) $(VMTESTSTF_JAR) $(PTS_TF_JAR) $(PTS_TF_EXEC) $(PTS_TF_README) $(ACP)
+# Make necessary directory for PTS
+	$(hide) rm -rf $(PRIVATE_PTS_DIR)
+	$(hide) mkdir -p $(TMP_DIR)
+	$(hide) mkdir -p $(PRIVATE_DIR)/docs
+	$(hide) mkdir -p $(PRIVATE_DIR)/tools
+	$(hide) mkdir -p $(PRIVATE_DIR)/repository/testcases
+	$(hide) mkdir -p $(PRIVATE_DIR)/repository/plans
+# Copy executable and JARs to PTS directory
+	$(hide) $(ACP) -fp $(DDMLIB_JAR) $(PRIVATE_JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(PTS_HOST_LIBRARY_JARS) $(TF_JAR) $(PTS_TF_JAR) $(PTS_TF_EXEC) $(PTS_TF_README) $(PRIVATE_DIR)/tools
+# Change mode of the executables
+	$(foreach apk,$(PTS_TEST_CASE_LIST),$(call copy-testcase-apk,$(apk)))
+	$(foreach testcase,$(PTS_TEST_CASES),$(call copy-testcase,$(testcase)))
+	$(hide) touch $@
+
+# Generate the default test plan for User.
+# Usage: buildCts.py <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath>
+
+$(DEFAULT_TEST_PLAN): $(pts_dir)/all_pts_files_stamp $(pts_tools_src_dir)/utils/buildCts.py $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(PTS_TEST_XMLS) | $(ACP)
+	$(hide) $(ACP) -fp $(PTS_TEST_XMLS) $(PRIVATE_DIR)/repository/testcases
+	$(hide) $(pts_tools_src_dir)/utils/buildCts.py cts/suite/pts $(PRIVATE_DIR) $(TMP_DIR) \
+		$(TOP) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar -pts
+
+# Package PTS and clean up.
+INTERNAL_PTS_TARGET := $(pts_dir)/$(pts_name).zip
+$(INTERNAL_PTS_TARGET): PRIVATE_NAME := $(pts_name)
+$(INTERNAL_PTS_TARGET): PRIVATE_PTS_DIR := $(pts_dir)
+$(INTERNAL_PTS_TARGET): PRIVATE_DIR := $(pts_dir)/$(pts_name)
+$(INTERNAL_PTS_TARGET): TMP_DIR := $(pts_dir)/temp
+$(INTERNAL_PTS_TARGET): $(pts_dir)/all_pts_files_stamp $(DEFAULT_TEST_PLAN)
+	$(hide) echo "Package PTS: $@"
+	$(hide) cd $(dir $@) && zip -rq $(notdir $@) $(PRIVATE_NAME)
+
+.PHONY: pts
+pts: $(INTERNAL_PTS_TARGET)
+cts: pts
+# generate PTS during CTS build
+ifneq ($(filter cts, $(MAKECMDGOALS)),)
+$(call dist-for-goals,cts,$(INTERNAL_PTS_TARGET))
+endif
+
+define copy-testcase-apk
+
+$(hide) $(ACP) -fp $(call intermediates-dir-for,APPS,$(1))/package.apk \
+	$(PRIVATE_DIR)/repository/testcases/$(1).apk
+
+endef
+
+define copy-testcase
+
+$(hide) $(ACP) -fp $(1) $(PRIVATE_DIR)/repository/testcases/$(notdir $1)
+
+endef
diff --git a/suite/pts/build/test_package.mk b/suite/pts/build/test_package.mk
new file mode 100644
index 0000000..f677c3b
--- /dev/null
+++ b/suite/pts/build/test_package.mk
@@ -0,0 +1,49 @@
+# 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.
+
+# copied from cts/build. modified for PTS
+
+# Disable by default so "m pts" will work in emulator builds
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
+
+pts_package_apk := $(PTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).apk
+pts_package_xml := $(PTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).xml
+
+$(pts_package_apk): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
+$(pts_package_apk): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk | $(ACP)
+	$(hide) mkdir -p $(PTS_TESTCASES_OUT)
+	$(hide) $(ACP) -fp $< $@
+
+$(pts_package_xml): PRIVATE_PATH := $(LOCAL_PATH)
+$(pts_package_xml): PRIVATE_INSTRUMENTATION := $(LOCAL_INSTRUMENTATION_FOR)
+$(pts_package_xml): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
+$(pts_package_xml): PRIVATE_TEST_PACKAGE := com.android.pts.$(notdir $(LOCAL_PATH))
+$(pts_package_xml): PRIVATE_MANIFEST := $(LOCAL_PATH)/AndroidManifest.xml
+$(pts_package_xml): PRIVATE_TEST_TYPE := $(if $(LOCAL_PTS_TEST_RUNNER),$(LOCAL_PTS_TEST_RUNNER),'')
+$(pts_package_xml): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk $(PTS_EXPECTATIONS) $(PTS_JAVA_TEST_SCANNER_DOCLET) $(PTS_JAVA_TEST_SCANNER) $(PTS_XML_GENERATOR)
+	$(hide) echo Generating test description for java package $(PRIVATE_PACKAGE)
+	$(hide) mkdir -p $(PTS_TESTCASES_OUT)
+	$(hide) $(PTS_JAVA_TEST_SCANNER) \
+						-s $(PRIVATE_PATH) \
+						-d $(PTS_JAVA_TEST_SCANNER_DOCLET) | \
+			$(PTS_XML_GENERATOR) \
+						-t $(PRIVATE_TEST_TYPE) \
+						-m $(PRIVATE_MANIFEST) \
+						-i "$(PRIVATE_INSTRUMENTATION)" \
+						-n $(PRIVATE_PACKAGE) \
+						-p $(PRIVATE_TEST_PACKAGE) \
+						-e $(PTS_EXPECTATIONS) \
+						-o $@
diff --git a/suite/pts/deviceTests/Android.mk b/suite/pts/deviceTests/Android.mk
new file mode 100644
index 0000000..c141484
--- /dev/null
+++ b/suite/pts/deviceTests/Android.mk
@@ -0,0 +1,17 @@
+#
+# 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 $(call all-subdir-makefiles)
diff --git a/suite/pts/deviceTests/dram/Android.mk b/suite/pts/deviceTests/dram/Android.mk
new file mode 100644
index 0000000..dbe0ad3
--- /dev/null
+++ b/suite/pts/deviceTests/dram/Android.mk
@@ -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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ptsutil ctsutil ctstestrunner
+
+LOCAL_JNI_SHARED_LIBRARIES := libptsdram_jni
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PtsDeviceDram
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_PTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/suite/pts/deviceTests/dram/AndroidManifest.xml b/suite/pts/deviceTests/dram/AndroidManifest.xml
new file mode 100644
index 0000000..b3ee2f0
--- /dev/null
+++ b/suite/pts/deviceTests/dram/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.pts.dram">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+            android:targetPackage="com.android.pts.dram"
+            android:label="DRAM bandwidth measurement" />
+</manifest>
diff --git a/suite/pts/deviceTests/dram/jni/Android.mk b/suite/pts/deviceTests/dram/jni/Android.mk
new file mode 100644
index 0000000..a3dc698
--- /dev/null
+++ b/suite/pts/deviceTests/dram/jni/Android.mk
@@ -0,0 +1,31 @@
+# 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    := libptsdram_jni
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := MemoryNativeJni.cpp
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+
+LOCAL_SHARED_LIBRARIES := libnativehelper
+
+LOCAL_SDK_VERSION := 14
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/suite/pts/deviceTests/dram/jni/MemoryNativeJni.cpp b/suite/pts/deviceTests/dram/jni/MemoryNativeJni.cpp
new file mode 100644
index 0000000..4680eab
--- /dev/null
+++ b/suite/pts/deviceTests/dram/jni/MemoryNativeJni.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 <jni.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+long currentTimeMillis()
+{
+    struct timeval tv;
+    gettimeofday(&tv, (struct timezone *) NULL);
+    return (long)tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+extern "C" JNIEXPORT jlong JNICALL Java_com_android_pts_dram_MemoryNative_runMemcpy(JNIEnv* env, jclass clazz, jint bufferSize,
+        jint repetition)
+{
+    char* src = (char*)malloc(bufferSize);
+    char* dst = (char*)malloc(bufferSize);
+    if ((src == NULL) || (dst == NULL)) {
+        env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), "No memory");
+    }
+    memset(src, 0, bufferSize);
+    memset(dst, 0, bufferSize);
+    long start = currentTimeMillis();
+    for (int i = 0; i < repetition; i++) {
+        memcpy(dst, src, bufferSize);
+        src[bufferSize - 1] = i & 0xff;
+    }
+    long end = currentTimeMillis();
+    return end - start;
+}
diff --git a/suite/pts/deviceTests/dram/src/com/android/pts/dram/BandwidthTest.java b/suite/pts/deviceTests/dram/src/com/android/pts/dram/BandwidthTest.java
new file mode 100644
index 0000000..9c23f22
--- /dev/null
+++ b/suite/pts/deviceTests/dram/src/com/android/pts/dram/BandwidthTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.pts.dram;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.util.Log;
+import android.view.WindowManager;
+
+import com.android.pts.util.PtsAndroidTestCase;
+import com.android.pts.util.ReportLog;
+import com.android.pts.util.Stat;
+
+public class BandwidthTest extends PtsAndroidTestCase {
+    private static final String TAG = "BandwidthTest";
+    private static final int BUFFER_SIZE = 4 * 1024 * 1024;
+
+
+    /* check how many screens the memcpy function can copy in a sec.
+     * Note that this does not represent the total memory bandwidth available in the system
+     * as typically CPU cannot use the whole bandwidth.
+     */
+    public void testMemcpy() {
+        final int REPETITION = 10;
+        final int REPEAT_IN_EACH_CALL = 100;
+        double[] result = new double[REPETITION];
+        for (int i = 0; i < REPETITION; i++) {
+            result[i] = MemoryNative.runMemcpy(BUFFER_SIZE, REPEAT_IN_EACH_CALL);
+        }
+        getReportLog().printArray("ms", result, false);
+        double[] mbps = ReportLog.calcRatePerSecArray(
+                (double)BUFFER_SIZE * REPEAT_IN_EACH_CALL / 1024.0 / 1024.0, result);
+        getReportLog().printArray("MB/s", mbps, true);
+        Stat.StatResult stat = Stat.getStat(mbps);
+        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+        Point size = new Point();
+        wm.getDefaultDisplay().getSize(size);
+        Log.i(TAG, " x " + size.x + " y " + size.y);
+        double pixels = size.x * size.y;
+        // now this represents how many times the whole screen can be copied in a sec.
+        double screensPerSecMin = stat.mMin / pixels * 1024.0 * 1024.0 / 4.0;
+        double screensPerSecAverage = stat.mAverage / pixels * 1024.0 * 1024.0 / 4.0;
+        getReportLog().printSummary("screen copies per sec", screensPerSecMin, screensPerSecAverage);
+    }
+}
diff --git a/suite/pts/deviceTests/dram/src/com/android/pts/dram/MemoryNative.java b/suite/pts/deviceTests/dram/src/com/android/pts/dram/MemoryNative.java
new file mode 100644
index 0000000..991de1e
--- /dev/null
+++ b/suite/pts/deviceTests/dram/src/com/android/pts/dram/MemoryNative.java
@@ -0,0 +1,31 @@
+/*
+ * 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.pts.dram;
+
+public class MemoryNative {
+    static {
+        System.loadLibrary("ptsdram_jni");
+    }
+    /**
+     * run memcpy for given number of repetition from a source to a destination buffers
+     * with each having the size of bufferSize.
+     * @param bufferSize
+     * @param repeatition
+     * @return time spent in copying in ms.
+     */
+    public static native long runMemcpy(int bufferSize, int repetition);
+}
diff --git a/suite/pts/deviceTests/filesystemperf/Android.mk b/suite/pts/deviceTests/filesystemperf/Android.mk
new file mode 100644
index 0000000..b42d48e
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/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)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ptsutil ctsutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PtsDeviceFilePerf
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_PTS_PACKAGE)
+
diff --git a/suite/pts/deviceTests/filesystemperf/AndroidManifest.xml b/suite/pts/deviceTests/filesystemperf/AndroidManifest.xml
new file mode 100644
index 0000000..8cdeb45
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.pts.filesystemperf">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+            android:targetPackage="com.android.pts.filesystemperf"
+            android:label="UI Latency measurement" />
+</manifest>
diff --git a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FileUtil.java b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FileUtil.java
new file mode 100644
index 0000000..906d831
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FileUtil.java
@@ -0,0 +1,246 @@
+/*
+ * 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.pts.filesystemperf;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Random;
+
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.SystemUtil;
+
+import android.content.Context;
+import android.util.Log;
+
+public class FileUtil {
+    private static final String TAG = "FileUtil";
+    private static final Random mRandom = new Random(0);
+    private static long mFileId = 0;
+    /**
+     * create array with different data per each call
+     *
+     * @param length
+     * @param randomSeed
+     * @return
+     */
+    public static byte[] generateRandomData(int length) {
+        byte[] buffer = new byte[length];
+        int val = mRandom.nextInt();
+        for (int i = 0; i < length / 4; i++) {
+            // in little-endian
+            buffer[i * 4] = (byte)(val & 0x000000ff);
+            buffer[i * 4 + 1] = (byte)((val & 0x0000ff00) >> 8);
+            buffer[i * 4 + 2] = (byte)((val & 0x00ff0000) >> 16);
+            buffer[i * 4 + 3] = (byte)((val & 0xff000000) >> 24);
+            val++;
+        }
+        for (int i = (length / 4) * 4; i < length; i++) {
+            buffer[i] = 0;
+        }
+        return buffer;
+    }
+
+    /**
+     * create a new file under the given dirName.
+     * Existing files will not be affected.
+     * @param context
+     * @param dirName
+     * @return
+     */
+    public static File createNewFile(Context context, String dirName) {
+        File topDir = new File(context.getFilesDir(), dirName);
+        topDir.mkdir();
+        String[] list = topDir.list();
+
+        String newFileName;
+        while (true) {
+            newFileName = Long.toString(mFileId);
+            boolean fileExist = false;
+            for (String child : list) {
+                if (child.equals(newFileName)) {
+                    fileExist = true;
+                    break;
+                }
+            }
+            if (!fileExist) {
+                break;
+            }
+            mFileId++;
+        }
+        mFileId++;
+        //Log.i(TAG, "filename" + Long.toString(mFileId));
+        return new File(topDir, newFileName);
+    }
+
+    /**
+     * create multiple new files
+     * @param context
+     * @param dirName
+     * @param count number of files to create
+     * @return
+     */
+    public static File[] createNewFiles(Context context, String dirName, int count) {
+        File[] files = new File[count];
+        for (int i = 0; i < count; i++) {
+            files[i] = createNewFile(context, dirName);
+        }
+        return files;
+    }
+
+    /**
+     * write file with given byte array
+     * @param file
+     * @param data
+     * @param append will append if set true. Otherwise, write from beginning
+     * @throws IOException
+     */
+    public static void writeFile(File file, byte[] data, boolean append) throws IOException {
+        FileOutputStream out = new FileOutputStream(file, append);
+        out.write(data);
+        out.flush();
+        out.close();
+    }
+
+    /**
+     * create a new file with given length.
+     * @param context
+     * @param dirName
+     * @param length
+     * @return
+     * @throws IOException
+     */
+    public static File createNewFilledFile(Context context, String dirName, long length)
+            throws IOException {
+        final int BUFFER_SIZE = 10 * 1024 * 1024;
+        File file = createNewFile(context, dirName);
+        FileOutputStream out = new FileOutputStream(file);
+        byte[] data = generateRandomData(BUFFER_SIZE);
+        long written = 0;
+        while (written < length) {
+            out.write(data);
+            written += BUFFER_SIZE;
+        }
+        out.flush();
+        out.close();
+        return file;
+    }
+
+    /**
+     * remove given file or directory under the current app's files dir.
+     * @param context
+     * @param name
+     */
+    public static void removeFileOrDir(Context context, String name) {
+        File entry = new File(context.getFilesDir(), name);
+        if (entry.exists()) {
+            removeEntry(entry);
+        }
+    }
+
+    private static void removeEntry(File entry) {
+        if (entry.isDirectory()) {
+            String[] children = entry.list();
+            for (String child : children) {
+                removeEntry(new File(entry, child));
+            }
+        }
+        entry.delete();
+    }
+
+    /**
+     * measure time taken for each IO run with amount R/W
+     * @param count
+     * @param run
+     * @param readAmount returns amount of read in bytes for each interval.
+     *        Value will not be written if /proc/self/io does not exist.
+     * @param writeAmount returns amount of write in bytes for each interval.
+     * @return time per each interval
+     * @throws IOException
+     */
+    public static double[] measureIO(int count, double[] readAmount, double[] writeAmount,
+            MeasureRun run)  throws IOException {
+        double[] result = new double[count];
+        File procIo = new File("/proc/self/io");
+        boolean measureIo = procIo.exists();
+        long prev = System.currentTimeMillis();
+        RWAmount prevAmount = new RWAmount();
+        if (measureIo) {
+            prevAmount = getRWAmount(procIo);
+        }
+        for (int i = 0; i < count; i++) {
+            run.run(i);
+            long current =  System.currentTimeMillis();
+            result[i] = current - prev;
+            prev = current;
+            if (measureIo) {
+                RWAmount currentAmount = getRWAmount(procIo);
+                readAmount[i] = currentAmount.mRd - prevAmount.mRd;
+                writeAmount[i] = currentAmount.mWr - prevAmount.mWr;
+                prevAmount = currentAmount;
+            }
+        }
+        return result;
+    }
+
+    private static class RWAmount {
+        public double mRd = 0.0;
+        public double mWr = 0.0;
+    };
+
+    private static RWAmount getRWAmount(File file) throws IOException {
+        RWAmount amount = new RWAmount();
+
+        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
+        String line;
+        while((line = br.readLine())!= null) {
+            if (line.startsWith("read_bytes")) {
+                amount.mRd = Double.parseDouble(line.split(" ")[1]);
+            } else if (line.startsWith("write_bytes")) {
+                amount.mWr = Double.parseDouble(line.split(" ")[1]);
+            }
+        }
+        br.close();
+        return amount;
+    }
+
+    /**
+     * get file size exceeding total memory size ( 2x total memory).
+     * The size is rounded in bufferSize. And the size will be bigger than 400MB.
+     * @param context
+     * @param bufferSize
+     * @return
+     * @throws IOException
+     */
+    public static long getFileSizeExceedingMemory(Context context, int bufferSize)
+            throws IOException {
+        long freeDisk = SystemUtil.getFreeDiskSize(context);
+        long memSize = SystemUtil.getTotalMemory(context);
+        long diskSizeTarget = (2 * memSize / bufferSize) * bufferSize;
+        final long minimumDiskSize = (512L * 1024L * 1024L / bufferSize) * bufferSize;
+        if ( diskSizeTarget < minimumDiskSize ) {
+            diskSizeTarget = minimumDiskSize;
+        }
+        if (diskSizeTarget > freeDisk) {
+            throw new IOException("Free disk size " + freeDisk + " too small");
+        }
+        return diskSizeTarget;
+    }
+}
diff --git a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FullUpdateTest.java b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FullUpdateTest.java
new file mode 100644
index 0000000..b6da646
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FullUpdateTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.pts.filesystemperf;
+
+import android.cts.util.TimeoutReq;
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.MeasureTime;
+import com.android.pts.util.PtsAndroidTestCase;
+import com.android.pts.util.ReportLog;
+import com.android.pts.util.Stat;
+import com.android.pts.util.SystemUtil;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class FullUpdateTest extends PtsAndroidTestCase {
+    private static final String DIR_INITIAL_FILL = "INITIAL_FILL";
+    private static final String DIR_WORK = "WORK";
+    private static final String TAG = "FullUpdateTest";
+
+    @Override
+    protected void tearDown() throws Exception {
+        FileUtil.removeFileOrDir(getContext(), DIR_INITIAL_FILL);
+        FileUtil.removeFileOrDir(getContext(), DIR_WORK);
+        super.tearDown();
+    }
+
+    // fill disk almost, update exceeding free space, then update some amount
+    // idea is to drain all free blocks and measure update performance
+    @TimeoutReq(minutes = 30)
+    public void testAlmostFilledUpdate() throws IOException {
+        long freeDisk = SystemUtil.getFreeDiskSize(getContext());
+        final long FREE_SPACE_TO_LEAVE = 400L * 1024L * 1024L; // leave this much
+        long diskToFill = freeDisk - FREE_SPACE_TO_LEAVE;
+        Log.i(TAG, "free disk " + freeDisk + ", to fill " + diskToFill);
+        final long MAX_FILE_SIZE_TO_FILL = 1024L * 1024L * 1024L;
+        long filled = 0;
+        while (filled < diskToFill) {
+            long toFill = diskToFill - filled;
+            if (toFill > MAX_FILE_SIZE_TO_FILL) {
+                toFill = MAX_FILE_SIZE_TO_FILL;
+            }
+            Log.i(TAG, "Generating file " + toFill);
+            FileUtil.createNewFilledFile(getContext(),
+                    DIR_INITIAL_FILL, toFill);
+            filled += toFill;
+        }
+
+        // now about freeSpaceToLeave should be left
+        // and try updating exceeding the free space size
+        final long FILE_SIZE = 300L * 1024L * 1024L;
+        File file = FileUtil.createNewFilledFile(getContext(),
+                DIR_WORK, FILE_SIZE);
+        final int BUFFER_SIZE = 10 * 1024 * 1024;
+        final byte[] data = FileUtil.generateRandomData(BUFFER_SIZE);
+        final int NUMBER_REPETITION = 10;
+        double[] worsts = new double[NUMBER_REPETITION];
+        double[] averages = new double[NUMBER_REPETITION];
+        for (int i = 0; i < NUMBER_REPETITION; i++) {
+            final FileOutputStream out = new FileOutputStream(file);
+            int numberRepeat = (int)(FILE_SIZE / BUFFER_SIZE);
+            double[] times = MeasureTime.measure(numberRepeat, new MeasureRun() {
+
+                @Override
+                public void run(int i) throws IOException {
+                    out.write(data);
+                    out.flush();
+                }
+            });
+            out.close();
+            double[] mbps = ReportLog.calcRatePerSecArray((double)BUFFER_SIZE / 1024 / 1024,
+                    times);
+            getReportLog().printArray(i + "-th round MB/s",
+                    mbps, true);
+            Stat.StatResult stat = Stat.getStat(mbps);
+            worsts[i] = stat.mMin;
+            averages[i] = stat.mAverage;
+        }
+        Stat.StatResult statWorsts = Stat.getStat(worsts);
+        Stat.StatResult statAverages = Stat.getStat(averages);
+        getReportLog().printSummary("MB/s", statWorsts.mMin, statAverages.mAverage);
+    }
+}
diff --git a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/RandomRWTest.java b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/RandomRWTest.java
new file mode 100644
index 0000000..4f8aad4
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/RandomRWTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.pts.filesystemperf;
+
+import android.cts.util.TimeoutReq;
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.PtsAndroidTestCase;
+import com.android.pts.util.ReportLog;
+import com.android.pts.util.Stat;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Random;
+
+
+public class RandomRWTest extends PtsAndroidTestCase {
+    private static final String DIR_RANDOM_WR = "RANDOM_WR";
+    private static final String DIR_RANDOM_RD = "RANDOM_RD";
+
+    @Override
+    protected void tearDown() throws Exception {
+        FileUtil.removeFileOrDir(getContext(), DIR_RANDOM_WR);
+        super.tearDown();
+    }
+
+
+    @TimeoutReq(minutes = 60)
+    public void testRandomRead() throws IOException {
+        final int READ_BUFFER_SIZE = 4 * 1024;
+        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), READ_BUFFER_SIZE);
+        File file = FileUtil.createNewFilledFile(getContext(),
+                DIR_RANDOM_RD, fileSize);
+
+        final byte[] data = FileUtil.generateRandomData(READ_BUFFER_SIZE);
+        Random random = new Random(0);
+        final int totalReadCount = (int)(fileSize / READ_BUFFER_SIZE);
+        final int[] readOffsets = new int[totalReadCount];
+        for (int i = 0; i < totalReadCount; i++) {
+            // align in buffer size
+            readOffsets[i] = (int)(random.nextFloat() * (fileSize - READ_BUFFER_SIZE)) &
+                    ~(READ_BUFFER_SIZE - 1);
+        }
+        final int runsInOneGo = 16;
+        final int readsInOneMeasure = totalReadCount / runsInOneGo;
+
+
+        final RandomAccessFile randomFile = new RandomAccessFile(file, "rw");
+        double[] rdAmount = new double[runsInOneGo];
+        double[] wrAmount = new double[runsInOneGo];
+        double[] times = FileUtil.measureIO(runsInOneGo, rdAmount, wrAmount, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws IOException {
+                int start = i * readsInOneMeasure;
+                int end = (i + 1) * readsInOneMeasure;
+                for (int j = start; j < end; j++) {
+                    randomFile.seek(readOffsets[j]);
+                    randomFile.read(data);
+                }
+            }
+        });
+        randomFile.close();
+        double[] mbps = ReportLog.calcRatePerSecArray((double)fileSize / runsInOneGo / 1024 / 1024,
+                times);
+        getReportLog().printArray("MB/s",
+                mbps, true);
+        getReportLog().printArray("Rd amount", rdAmount, true);
+        Stat.StatResult stat = Stat.getStat(mbps);
+
+        getReportLog().printSummary("MB/s", stat.mMin, stat.mAverage);
+    }
+
+    // It is taking too long in tuna, and thus cannot run multiple times
+    @TimeoutReq(minutes = 60)
+    public void testRandomUpdate() throws IOException {
+        final int fileSize = 512 * 1024 * 1024;
+        File file = FileUtil.createNewFilledFile(getContext(),
+                DIR_RANDOM_WR, fileSize);
+        final int WRITE_BUFFER_SIZE = 4 * 1024;
+        final byte[] data = FileUtil.generateRandomData(WRITE_BUFFER_SIZE);
+        Random random = new Random(0);
+        final int totalWriteCount = fileSize / WRITE_BUFFER_SIZE;
+        final int[] writeOffsets = new int[totalWriteCount];
+        for (int i = 0; i < totalWriteCount; i++) {
+            writeOffsets[i] = (int)(random.nextFloat() * (fileSize - WRITE_BUFFER_SIZE)) &
+                    ~(WRITE_BUFFER_SIZE - 1);
+        }
+        final int runsInOneGo = 16;
+        final int writesInOneMeasure = totalWriteCount / runsInOneGo; // 32MB at a time
+
+
+        final RandomAccessFile randomFile = new RandomAccessFile(file, "rw");
+        double[] rdAmount = new double[runsInOneGo];
+        double[] wrAmount = new double[runsInOneGo];
+        double[] times = FileUtil.measureIO(runsInOneGo, rdAmount, wrAmount, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws IOException {
+                int start = i * writesInOneMeasure;
+                int end = (i + 1) * writesInOneMeasure;
+                for (int j = start; j < end; j++) {
+                    randomFile.seek(writeOffsets[j]);
+                    randomFile.write(data);
+                }
+            }
+        });
+        randomFile.close();
+        double[] mbps = ReportLog.calcRatePerSecArray((double)fileSize / runsInOneGo / 1024 / 1024,
+                times);
+        getReportLog().printArray("MB/s",
+                mbps, true);
+        getReportLog().printArray("Wr amount", wrAmount, true);
+        Stat.StatResult stat = Stat.getStat(mbps);
+
+        getReportLog().printSummary("MB/s", stat.mMin, stat.mAverage);
+    }
+}
diff --git a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/SequentialRWTest.java b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/SequentialRWTest.java
new file mode 100644
index 0000000..2a750b1
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/SequentialRWTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.pts.filesystemperf;
+
+import android.cts.util.TimeoutReq;
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.MeasureTime;
+import com.android.pts.util.PtsAndroidTestCase;
+import com.android.pts.util.ReportLog;
+import com.android.pts.util.Stat;
+import com.android.pts.util.SystemUtil;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class SequentialRWTest extends PtsAndroidTestCase {
+    private static final String DIR_SEQ_WR = "SEQ_WR";
+    private static final String DIR_SEQ_UPD = "SEQ_UPD";
+    private static final String DIR_SEQ_RD = "SEQ_RD";
+    private static final int BUFFER_SIZE = 10 * 1024 * 1024;
+
+    @Override
+    protected void tearDown() throws Exception {
+        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_WR);
+        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_UPD);
+        FileUtil.removeFileOrDir(getContext(), DIR_SEQ_RD);
+        super.tearDown();
+    }
+
+    @TimeoutReq(minutes = 30)
+    public void testSingleSequentialWrite() throws IOException {
+        final int numberOfFiles =(int)(FileUtil.getFileSizeExceedingMemory(
+                getContext(), BUFFER_SIZE) / BUFFER_SIZE);
+        getReportLog().printValue("files", numberOfFiles);
+        final byte[] data = FileUtil.generateRandomData(BUFFER_SIZE);
+        final File[] files = FileUtil.createNewFiles(getContext(), DIR_SEQ_WR,
+                numberOfFiles);
+        double[] rdAmount = new double[numberOfFiles];
+        double[] wrAmount = new double[numberOfFiles];
+        double[] times = FileUtil.measureIO(numberOfFiles, rdAmount, wrAmount, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws IOException {
+                FileUtil.writeFile(files[i], data, false);
+            }
+        });
+        double[] mbps = ReportLog.calcRatePerSecArray((double)BUFFER_SIZE / 1024 / 1024, times);
+        getReportLog().printArray("try " + numberOfFiles + " files, result MB/s",
+                mbps, true);
+        getReportLog().printArray("Wr amount", wrAmount, true);
+        Stat.StatResult stat = Stat.getStat(mbps);
+        getReportLog().printSummary("MB/s", stat.mMin, stat.mAverage);
+    }
+
+    @TimeoutReq(minutes = 60)
+    public void testSingleSequentialUpdate() throws IOException {
+        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
+        File file = FileUtil.createNewFilledFile(getContext(),
+                DIR_SEQ_UPD, fileSize);
+        final byte[] data = FileUtil.generateRandomData(BUFFER_SIZE);
+        final int NUMBER_REPETITION = 6;
+        double[] worsts = new double[NUMBER_REPETITION];
+        double[] averages = new double[NUMBER_REPETITION];
+        for (int i = 0; i < NUMBER_REPETITION; i++) {
+            final FileOutputStream out = new FileOutputStream(file);
+            int numberRepeat = (int)(fileSize / BUFFER_SIZE);
+            double[] rdAmount = new double[numberRepeat];
+            double[] wrAmount = new double[numberRepeat];
+            double[] times = FileUtil.measureIO(numberRepeat, rdAmount, wrAmount,
+                    new MeasureRun() {
+
+                @Override
+                public void run(int i) throws IOException {
+                    out.write(data);
+                    out.flush();
+                }
+            });
+            out.close();
+            double[] mbps = ReportLog.calcRatePerSecArray((double)BUFFER_SIZE / 1024 / 1024,
+                    times);
+            getReportLog().printArray(i + "-th round MB/s",
+                    mbps, true);
+            getReportLog().printArray("Wr amount", wrAmount, true);
+            Stat.StatResult stat = Stat.getStat(mbps);
+            worsts[i] = stat.mMin;
+            averages[i] = stat.mAverage;
+        }
+        Stat.StatResult statWorsts = Stat.getStat(worsts);
+        Stat.StatResult statAverages = Stat.getStat(averages);
+        getReportLog().printSummary("MB/s", statWorsts.mMin, statAverages.mAverage);
+    }
+
+    @TimeoutReq(minutes = 30)
+    public void testSingleSequentialRead() throws IOException {
+        final long fileSize = FileUtil.getFileSizeExceedingMemory(getContext(), BUFFER_SIZE);
+        long start = System.currentTimeMillis();
+        final File file = FileUtil.createNewFilledFile(getContext(),
+                DIR_SEQ_RD, fileSize);
+        long finish = System.currentTimeMillis();
+        getReportLog().printValue("write size " + fileSize + " result MB/s",
+                ReportLog.calcRatePerSec((double)fileSize / 1024 / 1024, finish - start));
+
+        final int NUMBER_READ = 10;
+
+        final byte[] data = new byte[BUFFER_SIZE];
+        double[] times = MeasureTime.measure(NUMBER_READ, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws IOException {
+                final FileInputStream in = new FileInputStream(file);
+                long read = 0;
+                while (read < fileSize) {
+                    in.read(data);
+                    read += BUFFER_SIZE;
+                }
+                in.close();
+            }
+        });
+        double[] mbps = ReportLog.calcRatePerSecArray((double)fileSize / 1024 / 1024, times);
+        getReportLog().printArray("read MB/s",
+                mbps, true);
+        Stat.StatResult stat = Stat.getStat(mbps);
+        getReportLog().printSummary("MB/s", stat.mMin, stat.mAverage);
+    }
+}
diff --git a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/TestTest.java b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/TestTest.java
new file mode 100644
index 0000000..6800d6f
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/TestTest.java
@@ -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.
+ */
+
+
+// code for testing, will be removed / moved before release
+
+package com.android.pts.filesystemperf;
+
+import android.cts.util.TimeoutReq;
+import com.android.pts.util.PtsAndroidTestCase;
+
+/**
+ * This class is for testing PTS itself. Will be disabled in release.
+ *
+ */
+public class TestTest extends PtsAndroidTestCase {
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @TimeoutReq(minutes = 15)
+    public void testPass() {
+        double[] array = new double[] {1.0, 2.0, 3.0};
+        getReportLog().printArray(" ", array, true);
+        getReportLog().printArray(" ", array, false);
+        getReportLog().printValue(" ", 1.0);
+        getReportLog().printValue(" ", 2.0);
+        getReportLog().printSummary("This should be shown", 0, 0);
+    }
+
+    @TimeoutReq(minutes = 10)
+    public void testFail() throws Exception {
+        getReportLog().printValue(" ", 1.0);
+        getReportLog().printValue(" ", 2.0);
+        getReportLog().printSummary("This should not be shown", 0, 0);
+        throw new Exception("failed");
+    }
+}
diff --git a/suite/pts/deviceTests/ptsutil/Android.mk b/suite/pts/deviceTests/ptsutil/Android.mk
new file mode 100644
index 0000000..d097036
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/Android.mk
@@ -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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_MODULE := ptsutil
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/core/libcore/src/Dummy.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureRun.java
similarity index 60%
rename from tests/core/libcore/src/Dummy.java
rename to suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureRun.java
index 64b67de..1f6f6ed 100644
--- a/tests/core/libcore/src/Dummy.java
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureRun.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * 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.
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
+package com.android.pts.util;
+
+import java.io.IOException;
+
 /**
- * We really just want the core-tests classes from the static java
- * library, but the build system currently needs at least one input
- * file, not just because its a sanity check, but because the static
- * class files and resources are included in the output of the local
- * java compilation.
+ * interface for measuring time for each run.
  */
-public final class Dummy {}
+public interface MeasureRun {
+
+    abstract public void run(int i) throws IOException;
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureTime.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureTime.java
new file mode 100644
index 0000000..337a472
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureTime.java
@@ -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.
+ */
+
+package com.android.pts.util;
+
+import java.io.IOException;
+
+public class MeasureTime {
+    /**
+     * measure time taken for each run for given count
+     * @param count
+     * @param run
+     * @return array of time taken in each run in msec.
+     * @throws IOException
+     */
+    public static double[] measure(int count, MeasureRun run)  throws IOException {
+        double[] result = new double[count];
+        long prev = System.currentTimeMillis();
+        for (int i = 0; i < count; i++) {
+            run.run(i);
+            long current =  System.currentTimeMillis();
+            result[i] = current - prev;
+            prev = current;
+        }
+        return result;
+    }
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsActivityInstrumentationTestCase2.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsActivityInstrumentationTestCase2.java
new file mode 100644
index 0000000..84c1718
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsActivityInstrumentationTestCase2.java
@@ -0,0 +1,42 @@
+/*
+ * 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.pts.util;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase2;
+
+
+public class PtsActivityInstrumentationTestCase2<T extends Activity> extends
+        ActivityInstrumentationTestCase2<T> {
+
+    private ReportLog mReportLog = new ReportLog();
+
+    public PtsActivityInstrumentationTestCase2(Class<T> activityClass) {
+        super(activityClass);
+    }
+
+    public ReportLog getReportLog() {
+        return mReportLog;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mReportLog.throwReportToHost();
+    }
+
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsAndroidTestCase.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsAndroidTestCase.java
new file mode 100644
index 0000000..bf17956
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsAndroidTestCase.java
@@ -0,0 +1,34 @@
+/*
+ * 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.pts.util;
+
+import android.test.AndroidTestCase;
+
+public class PtsAndroidTestCase extends AndroidTestCase {
+
+    private ReportLog mReportLog = new ReportLog();
+
+    public ReportLog getReportLog() {
+        return mReportLog;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mReportLog.throwReportToHost();
+    }
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsException.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsException.java
new file mode 100644
index 0000000..e8ec5be
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsException.java
@@ -0,0 +1,28 @@
+/*
+ * 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.pts.util;
+
+/**
+ * Exception throw by PTS test to pass the result to host
+ * This should not be thrown by test app unless the result is complete.
+ */
+@SuppressWarnings("serial")
+public class PtsException extends Exception {
+    public PtsException(String message) {
+        super(message);
+    }
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/ReportLog.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/ReportLog.java
new file mode 100644
index 0000000..531d2f5
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/ReportLog.java
@@ -0,0 +1,149 @@
+/*
+ * 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.pts.util;
+
+import android.util.Log;
+
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ * Utility class to print performance measurement result back to host.
+ * For now, throws know exception with message.
+ *
+ * Format:
+ * LOG_SEPARATOR : separates each log
+ * Message = log [LOG_SEPARATOR log]*
+ * log for single value = classMethodName:line_number|header|d|value
+ * log for array = classMethodName:line_number|header|da|values|
+ *                     average average_value min|max value stddev value
+ */
+public class ReportLog {
+    private static final String TAG = "PtsReport";
+    private static final String LOG_SEPARATOR = "+++";
+    private static final String SUMMARY_SEPARATOR = "++++";
+    private static final String LOG_ELEM_SEPARATOR = "|";
+
+    private List<String> mMessages = new LinkedList<String> ();
+    private String mSummary = null;
+    /**
+     * print given value to the report
+     * @param header string to explain the contents. It can be unit for the value.
+     * @param val
+     */
+    public void printValue(String header, double val) {
+        String message = getClassMethodNames(4, true) + LOG_ELEM_SEPARATOR + header +
+                LOG_ELEM_SEPARATOR + "d" + LOG_ELEM_SEPARATOR + val;
+        mMessages.add(message);
+        Log.i(TAG, message);
+    }
+
+    /**
+     * array version of printValue
+     * @param header
+     * @param val
+     * @param addMin add minimum to the result. If false, add maximum to the result
+     */
+    public void printArray(String header, double[] val, boolean addMin) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(getClassMethodNames(4, true) + LOG_ELEM_SEPARATOR + header +
+                LOG_ELEM_SEPARATOR + "da" + LOG_ELEM_SEPARATOR);
+        for (double v : val) {
+            builder.append(v);
+            builder.append(" ");
+        }
+        Stat.StatResult stat = Stat.getStat(val);
+        builder.append(LOG_ELEM_SEPARATOR + "average " + stat.mAverage +
+                (addMin ? (" min " + stat.mMin) : (" max " + stat.mMax)) + " stddev " + stat.mStddev);
+        mMessages.add(builder.toString());
+        Log.i(TAG, builder.toString());
+    }
+
+    public void printSummary(String header, double worst, double average) {
+        mSummary = header + LOG_ELEM_SEPARATOR + "worst " + worst + LOG_ELEM_SEPARATOR +
+                "average " + average;
+    }
+
+    public void throwReportToHost() throws PtsException {
+        if ((mSummary == null) && mMessages.isEmpty()) {
+            return;
+        }
+        StringBuilder builder = new StringBuilder();
+        builder.append(mSummary);
+        builder.append(SUMMARY_SEPARATOR);
+        for (String entry : mMessages) {
+            builder.append(entry);
+            builder.append(LOG_SEPARATOR);
+        }
+        // delete the last separator
+        if (builder.length() >= LOG_SEPARATOR.length()) {
+            builder.delete(builder.length() - LOG_SEPARATOR.length(), builder.length());
+        }
+        throw new PtsException(builder.toString());
+    }
+
+    /**
+     * calculate rate per sec for given change happened during given timeInMSec.
+     * timeInSec with 0 value will be changed to small value to prevent divide by zero.
+     * @param change total change of quality for the given duration timeInMSec.
+     * @param timeInMSec
+     * @return
+     */
+    public static double calcRatePerSec(double change, double timeInMSec) {
+        if (timeInMSec == 0) {
+            return change * 1000.0 / 0.001; // do not allow zero
+        } else {
+            return change * 1000.0 / timeInMSec;
+        }
+    }
+
+    /**
+     * array version of calcRatePerSecArray
+     * @param change
+     * @param timeInMSec
+     * @return
+     */
+    public static double[] calcRatePerSecArray(double change, double[] timeInMSec) {
+        double[] result = new double[timeInMSec.length];
+        change *= 1000.0;
+        for (int i = 0; i < timeInMSec.length; i++) {
+            if (timeInMSec[i] == 0) {
+                result[i] = change / 0.001;
+            } else {
+                result[i] = change / timeInMSec[i];
+            }
+        }
+        return result;
+    }
+
+    /**
+     * get classname.methodname from call stack of the current thread
+     *
+     * @return
+     */
+    public static String getClassMethodNames() {
+        return getClassMethodNames(4, false);
+    }
+
+    private static String getClassMethodNames(int depth, boolean addLineNumber) {
+        StackTraceElement[] elements = Thread.currentThread().getStackTrace();
+        String names = elements[depth].getClassName() + "." + elements[depth].getMethodName() +
+                (addLineNumber ? ":" + elements[depth].getLineNumber() : "");
+        return names;
+    }
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/Stat.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/Stat.java
new file mode 100644
index 0000000..aae51ec
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/Stat.java
@@ -0,0 +1,79 @@
+/*
+ * 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.pts.util;
+
+/**
+ * Utilities for doing statistics
+ *
+ */
+public class Stat {
+
+    public static class StatResult {
+        public double mAverage;
+        public double mMin;
+        public double mMax;
+        public double mStddev;
+        public StatResult(double average, double min, double max, double stddev) {
+            mAverage = average;
+            mMin = min;
+            mMax = max;
+            mStddev = stddev;
+        }
+    }
+
+    public static StatResult getStat(double[] data) {
+        double average = data[0];
+        double min = data[0];
+        double max = data[0];
+        double eX2 = data[0] * data[0]; // will become E[X^2]
+        for (int i = 1; i < data.length; i++) {
+            average += data[i];
+            eX2 += data[i] * data[i];
+            if (data[i] > max) {
+                max = data[i];
+            }
+            if (data[i] < min) {
+                min = data[i];
+            }
+        }
+        average /= data.length;
+        eX2 /= data.length;
+        // stddev = sqrt(E[X^2] - (E[X])^2)
+        double stddev = Math.sqrt(eX2 - average * average);
+        return new StatResult(average, min, max, stddev);
+    }
+
+    public static double getMin(double[] data) {
+        double min = data[0];
+        for (int i = 1; i < data.length; i++) {
+            if (data[i] < min) {
+                min = data[i];
+            }
+        }
+        return min;
+    }
+
+    public static double getMax(double[] data) {
+        double max = data[0];
+        for (int i = 1; i < data.length; i++) {
+            if (data[i] > max) {
+                max = data[i];
+            }
+        }
+        return max;
+    }
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/SystemUtil.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/SystemUtil.java
new file mode 100644
index 0000000..7975463
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/SystemUtil.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 com.android.pts.util;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.MemoryInfo;
+import android.content.Context;
+import android.os.StatFs;
+
+public class SystemUtil {
+    public static long getFreeDiskSize(Context context) {
+        StatFs statFs = new StatFs(context.getFilesDir().getAbsolutePath());
+        return (long)statFs.getAvailableBlocks() * statFs.getBlockSize();
+    }
+
+    public static long getFreeMemory(Context context) {
+        MemoryInfo info = new MemoryInfo();
+        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+        activityManager.getMemoryInfo(info);
+        return info.availMem;
+    }
+
+    public static long getTotalMemory(Context context) {
+        MemoryInfo info = new MemoryInfo();
+        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+        activityManager.getMemoryInfo(info);
+        return info.totalMem; // TODO totalMem N/A in ICS.
+    }
+}
diff --git a/suite/pts/deviceTests/ui/Android.mk b/suite/pts/deviceTests/ui/Android.mk
new file mode 100644
index 0000000..28db8a1
--- /dev/null
+++ b/suite/pts/deviceTests/ui/Android.mk
@@ -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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ptsutil ctsutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PtsDeviceUi
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_PTS_PACKAGE)
+
+
diff --git a/suite/pts/deviceTests/ui/AndroidManifest.xml b/suite/pts/deviceTests/ui/AndroidManifest.xml
new file mode 100644
index 0000000..b5e4937b
--- /dev/null
+++ b/suite/pts/deviceTests/ui/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?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.pts.ui">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity
+                android:name=".ScrollingActivity"
+                android:screenOrientation="portrait"
+                android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+            android:targetPackage="com.android.pts.ui"
+            android:label="UI Latency measurement" />
+</manifest>
diff --git a/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingActivity.java b/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingActivity.java
new file mode 100644
index 0000000..7bdfff9
--- /dev/null
+++ b/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingActivity.java
@@ -0,0 +1,104 @@
+/*
+ * 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.pts.ui;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class ScrollingActivity extends ListActivity implements OnScrollListener
+{
+    static final String TAG = "ScrollingActivity";
+    private static final int NUMBER_ELEMENTS = 10000;
+    private static final int SCROLL_TIME_IN_MS = 1;
+    private static final int WAIT_TIMEOUT_IN_SECS = 5 * 60;
+    private String[] mItems = new String[NUMBER_ELEMENTS];
+    private CountDownLatch mLatchStop = null;
+    private int mTargetLoc;
+
+    public void onCreate(Bundle icicle)
+    {
+        super.onCreate(icicle);
+        for (int i = 0; i < NUMBER_ELEMENTS; i++) {
+            mItems[i] = Integer.toString(i);
+        }
+        setListAdapter(new ArrayAdapter<String>(this,
+                android.R.layout.simple_list_item_1, mItems));
+        ListView view = getListView();
+        view.setOnScrollListener(this);
+        //view.setVelocityScale(100.0f);
+    }
+
+    public boolean scrollToTop() {
+        return doScroll(0);
+    }
+    public boolean scrollToBottom() {
+        return doScroll(NUMBER_ELEMENTS - 1);
+    }
+
+    private boolean doScroll(final int loc) {
+        mLatchStop = new CountDownLatch(1);
+        mTargetLoc = loc;
+        final ListView view = getListView();
+        runOnUiThread( new Runnable() {
+            @Override
+            public void run() {
+                view.smoothScrollToPositionFromTop(loc, 0, SCROLL_TIME_IN_MS);
+            }
+        });
+        boolean result = false;
+        try {
+            result = mLatchStop.await(WAIT_TIMEOUT_IN_SECS, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            // ignore
+        }
+        mLatchStop = null;
+        return result;
+    }
+    public void onStop()
+    {
+        super.onStop();
+    }
+
+    public void onResume()
+    {
+        super.onResume();
+    }
+
+    @Override
+    public void onScrollStateChanged(AbsListView view, int scrollState) {
+
+    }
+
+    @Override
+    public void onScroll(AbsListView view, int firstVisibleItem,
+            int visibleItemCount, int totalItemCount) {
+        //Log.i(TAG, "onScroll " + firstVisibleItem + " " + visibleItemCount);
+        if ((mTargetLoc >= firstVisibleItem) &&
+                (mTargetLoc <= (firstVisibleItem + visibleItemCount))) {
+            if (mLatchStop != null) {
+                mLatchStop.countDown();
+            }
+        }
+    }
+}
diff --git a/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingTest.java b/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingTest.java
new file mode 100644
index 0000000..c19055c
--- /dev/null
+++ b/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.pts.ui;
+
+import android.cts.util.TimeoutReq;
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.MeasureTime;
+import com.android.pts.util.PtsActivityInstrumentationTestCase2;
+import com.android.pts.util.ReportLog;
+import com.android.pts.util.Stat;
+
+import java.io.IOException;
+
+public class ScrollingTest extends PtsActivityInstrumentationTestCase2<ScrollingActivity> {
+    private ScrollingActivity mActivity;
+
+    public ScrollingTest() {
+        super(ScrollingActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        getInstrumentation().waitForIdleSync();
+        try {
+            runTestOnUiThread(new Runnable() {
+                public void run() {
+                }
+            });
+        } catch (Throwable e) {
+            e.printStackTrace();
+            fail();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mActivity = null;
+        super.tearDown();
+    }
+
+    @TimeoutReq(minutes = 30)
+    public void testFullScrolling() throws IOException {
+        final int NUMBER_REPEAT = 10;
+        final ScrollingActivity activity = mActivity;
+        double[] results = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
+
+            @Override
+            public void run(int i) throws IOException {
+                assertTrue(activity.scrollToBottom());
+                assertTrue(activity.scrollToTop());
+            }
+        });
+        getReportLog().printArray("ms", results, false);
+        Stat.StatResult stat = Stat.getStat(results);
+        getReportLog().printSummary("Time ms", stat.mMax, stat.mAverage);
+    }
+}
diff --git a/suite/pts/expectations/knownfailures.txt b/suite/pts/expectations/knownfailures.txt
new file mode 100644
index 0000000..0d4f101
--- /dev/null
+++ b/suite/pts/expectations/knownfailures.txt
@@ -0,0 +1,2 @@
+[
+]
diff --git a/suite/pts/tools/Android.mk b/suite/pts/tools/Android.mk
new file mode 100644
index 0000000..c141484
--- /dev/null
+++ b/suite/pts/tools/Android.mk
@@ -0,0 +1,17 @@
+#
+# 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 $(call all-subdir-makefiles)
diff --git a/suite/pts/tools/tradefed/Android.mk b/suite/pts/tools/tradefed/Android.mk
new file mode 100644
index 0000000..09e49b1
--- /dev/null
+++ b/suite/pts/tools/tradefed/Android.mk
@@ -0,0 +1,22 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PREBUILT_EXECUTABLES := pts-tradefed
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/suite/pts/tools/tradefed/pts-tradefed b/suite/pts/tools/tradefed/pts-tradefed
new file mode 100755
index 0000000..fedbfaf
--- /dev/null
+++ b/suite/pts/tools/tradefed/pts-tradefed
@@ -0,0 +1,86 @@
+#!/bin/bash
+
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# launcher script for cts-tradefed harness for PTS
+# can be used from an Android build environment, or a standalone pts zip
+
+checkFile() {
+    if [ ! -f "$1" ]; then
+        echo "Unable to locate $1"
+        exit
+    fi;
+}
+
+checkPath() {
+    if ! type -P $1 &> /dev/null; then
+        echo "Unable to find $1 in path."
+        exit
+    fi;
+}
+
+checkPath adb
+checkPath java
+
+# check java version
+JAVA_VERSION=$(java -version 2>&1 | head -n 1 | grep '[ "]1\.6[\. "$$]')
+if [ "${JAVA_VERSION}" == "" ]; then
+    echo "Wrong java version. 1.6 is required."
+    exit
+fi
+
+# check debug flag and set up remote debugging
+if [ -n "${TF_DEBUG}" ]; then
+  if [ -z "${TF_DEBUG_PORT}" ]; then
+    TF_DEBUG_PORT=10088
+  fi
+  RDBG_FLAG=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${TF_DEBUG_PORT}
+fi
+
+
+# check if in Android build env
+if [ ! -z ${ANDROID_BUILD_TOP} ]; then
+    HOST=`uname`
+    if [ "$HOST" == "Linux" ]; then
+        OS="linux-x86"
+    elif [ "$HOST" == "Darwin" ]; then
+        OS="darwin-x86"
+    else
+        echo "Unrecognized OS"
+        exit
+    fi;
+    PTS_ROOT=${ANDROID_BUILD_TOP}/out/host/${OS}/pts
+    if [ ! -d ${PTS_ROOT} ]; then
+        echo "Could not find $PTS_ROOT in Android build environment. Try 'make pts'"
+        exit
+    fi;
+fi;
+
+if [ -z ${PTS_ROOT} ]; then
+    # assume we're in an extracted pts install
+    PTS_ROOT="$(dirname $0)/../.."
+fi;
+
+JAR_DIR=${PTS_ROOT}/android-pts/tools
+JARS="ddmlib-prebuilt.jar tradefed-prebuilt.jar hosttestlib.jar cts-tradefed.jar"
+
+for JAR in $JARS; do
+    checkFile ${JAR_DIR}/${JAR}
+    JAR_PATH=${JAR_PATH}:${JAR_DIR}/${JAR}
+done
+
+java $RDBG_FLAG \
+  -cp ${JAR_PATH} -DCTS_ROOT=${PTS_ROOT} -DPTS=1 com.android.cts.tradefed.command.CtsConsole "$@"
+
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/ctscore.mk b/tests/core/ctscore.mk
index 049a58e..27ff881 100644
--- a/tests/core/ctscore.mk
+++ b/tests/core/ctscore.mk
@@ -12,60 +12,14 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# First we build an apk without the core-tests resource
-cts_ORIGINAL_PACKAGE_NAME := $(LOCAL_PACKAGE_NAME)
-
-LOCAL_PACKAGE_NAME := $(LOCAL_PACKAGE_NAME).no-core-tests-res
-# Make sure this apk won't get installed
-LOCAL_UNINSTALLABLE_MODULE := true
-
 LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
-# Vars set by $(BUILD_PACKAGE) and needed by the below module definition.
-cts_no-core-tests-res_BUILT_MODULE := $(LOCAL_BUILT_MODULE)
-cts_no-core-tests-res_private_key := $(private_key)
-cts_no-core-tests-res_certificate := $(certificate)
-
-##################################
-# Now the rules to build the apk with core-tests resource
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := $(cts_ORIGINAL_PACKAGE_NAME)
-LOCAL_MODULE_CLASS := APPS
 # don't include these packages in any target
 LOCAL_MODULE_TAGS := optional
-# and when built explicitly put them in the data partition
+# and when installed explicitly put them in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
-LOCAL_BUILT_MODULE_STEM := package.apk
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-CORETESTS_INTERMEDIATES := $(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)
-
-$(LOCAL_BUILT_MODULE): PRIVATE_INTERMEDIATES_COMMON := $(intermediates.COMMON)
-$(LOCAL_BUILT_MODULE): PRIVATE_CORETESTS_INTERMEDIATES_COMMON := $(CORETESTS_INTERMEDIATES)
-$(LOCAL_BUILT_MODULE): PRIVATE_PRIVATE_KEY := $(cts_no-core-tests-res_private_key)
-$(LOCAL_BUILT_MODULE): PRIVATE_CERTIFICATE := $(cts_no-core-tests-res_certificate)
-$(LOCAL_BUILT_MODULE): $(cts_no-core-tests-res_BUILT_MODULE) $(CORETESTS_INTERMEDIATES)/javalib.jar
-	@echo "Add resources to package ($@)"
-	$(hide) mkdir -p $(dir $@) $(PRIVATE_INTERMEDIATES_COMMON)
-	$(hide) rm -rf $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses
-	# javalib.jar should only contain .dex files, but the harmony tests also include
-	# some .class files, so get rid of them
-	$(hide) unzip -qo $(PRIVATE_CORETESTS_INTERMEDIATES_COMMON)/javalib.jar \
-		-d $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses
-	$(hide) find $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses -type f -name "*.class" -delete
-	$(hide) rm -f $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses/classes.dex
-	$(hide) cp $< $@
-	$(hide) jar uf $@ -C $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses .
-	$(sign-package)
-	$(align-package)
-
-# some global vars set in $(BUILD_PACKAGE), not sure if we really need here
-PACKAGES.$(cts_ORIGINAL_PACKAGE_NAME).PRIVATE_KEY := $(cts_no-core-tests-res_private_key)
-PACKAGES.$(cts_ORIGINAL_PACKAGE_NAME).CERTIFICATE := $(cts_no-core-tests-res_certificate)
-PACKAGES := $(PACKAGES) $(cts_ORIGINAL_PACKAGE_NAME)
+# Don't delete META-INF from the core-tests jar
+LOCAL_DONT_DELETE_JAR_META_INF := true
+include $(BUILD_PACKAGE)
diff --git a/tests/core/libcore/com/Android.mk b/tests/core/libcore/com/Android.mk
index 91a5da0..02dc3de 100644
--- a/tests/core/libcore/com/Android.mk
+++ b/tests/core/libcore/com/Android.mk
@@ -19,7 +19,6 @@
 endif
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.com
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/dalvik/Android.mk b/tests/core/libcore/dalvik/Android.mk
index 45f6e7e..7b77a75 100644
--- a/tests/core/libcore/dalvik/Android.mk
+++ b/tests/core/libcore/dalvik/Android.mk
@@ -19,7 +19,6 @@
 endif
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.dalvik
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/libcore/Android.mk b/tests/core/libcore/libcore/Android.mk
index 97e32bc..382b386 100644
--- a/tests/core/libcore/libcore/Android.mk
+++ b/tests/core/libcore/libcore/Android.mk
@@ -19,7 +19,6 @@
 endif
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.libcore
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/org/Android.mk b/tests/core/libcore/org/Android.mk
index 8fad8de..d7a96b3 100644
--- a/tests/core/libcore/org/Android.mk
+++ b/tests/core/libcore/org/Android.mk
@@ -19,7 +19,6 @@
 endif
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.org
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/sun/Android.mk b/tests/core/libcore/sun/Android.mk
index 5fc0c48..44d3d70 100644
--- a/tests/core/libcore/sun/Android.mk
+++ b/tests/core/libcore/sun/Android.mk
@@ -19,7 +19,6 @@
 endif
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.sun
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/tests/Android.mk b/tests/core/libcore/tests/Android.mk
index bcb6628..bfd235f 100644
--- a/tests/core/libcore/tests/Android.mk
+++ b/tests/core/libcore/tests/Android.mk
@@ -19,7 +19,6 @@
 endif
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
 LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.tests
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests
 include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/runner/Android.mk b/tests/core/runner/Android.mk
index 7658b7a..fb548fc 100644
--- a/tests/core/runner/Android.mk
+++ b/tests/core/runner/Android.mk
@@ -27,4 +27,6 @@
 
 LOCAL_PACKAGE_NAME := android.core.tests.runner
 
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+
 include $(BUILD_CTSCORE_PACKAGE)
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/renderscript/cts/kernel_all.rs b/tests/src/android/renderscript/cts/kernel_all.rs
new file mode 100644
index 0000000..c3e4888
--- /dev/null
+++ b/tests/src/android/renderscript/cts/kernel_all.rs
@@ -0,0 +1,187 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+uchar __attribute__((kernel)) test_i8(char ain) {
+    return ain + 1;
+}
+
+uchar2 __attribute__((kernel)) test_i8_2(char2 ain) {
+    uchar2 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    return r;
+}
+
+uchar3 __attribute__((kernel)) test_i8_3(char3 ain) {
+    uchar3 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    r.z = ain.z + 1;
+    return r;
+}
+
+uchar4 __attribute__((kernel)) test_i8_4(char4 ain) {
+    uchar4 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    r.z = ain.z + 1;
+    r.w = ain.w + 1;
+    return r;
+}
+
+ushort __attribute__((kernel)) test_i16(short ain) {
+    return ain + 1;
+}
+
+ushort2 __attribute__((kernel)) test_i16_2(short2 ain) {
+    ushort2 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    return r;
+}
+
+ushort3 __attribute__((kernel)) test_i16_3(short3 ain) {
+    ushort3 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    r.z = ain.z + 1;
+    return r;
+}
+
+ushort4 __attribute__((kernel)) test_i16_4(short4 ain) {
+    ushort4 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    r.z = ain.z + 1;
+    r.w = ain.w + 1;
+    return r;
+}
+
+uint __attribute__((kernel)) test_i32(int ain) {
+    return ain + 1;
+}
+
+uint2 __attribute__((kernel)) test_i32_2(int2 ain) {
+    uint2 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    return r;
+}
+
+uint3 __attribute__((kernel)) test_i32_3(int3 ain) {
+    uint3 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    r.z = ain.z + 1;
+    return r;
+}
+
+uint4 __attribute__((kernel)) test_i32_4(int4 ain) {
+    uint4 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    r.z = ain.z + 1;
+    r.w = ain.w + 1;
+    return r;
+}
+
+ulong __attribute__((kernel)) test_i64(long ain) {
+    return ain + 1;
+}
+
+ulong2 __attribute__((kernel)) test_i64_2(long2 ain) {
+    ulong2 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    return r;
+}
+
+ulong3 __attribute__((kernel)) test_i64_3(long3 ain) {
+    ulong3 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    r.z = ain.z + 1;
+    return r;
+}
+
+ulong4 __attribute__((kernel)) test_i64_4(long4 ain) {
+    ulong4 r;
+    r.x = ain.x + 1;
+    r.y = ain.y + 1;
+    r.z = ain.z + 1;
+    r.w = ain.w + 1;
+    return r;
+}
+
+float __attribute__((kernel)) test_f32(float ain) {
+    return ain + 1.0f;
+}
+
+float2 __attribute__((kernel)) test_f32_2(float2 ain) {
+    float2 r;
+    r.x = ain.x + 1.0f;
+    r.y = ain.y + 1.0f;
+    return r;
+}
+
+float3 __attribute__((kernel)) test_f32_3(float3 ain) {
+    float3 r;
+    r.x = ain.x + 1.0f;
+    r.y = ain.y + 1.0f;
+    r.z = ain.z + 1.0f;
+    return r;
+}
+
+float4 __attribute__((kernel)) test_f32_4(float4 ain) {
+    float4 r;
+    r.x = ain.x + 1.0f;
+    r.y = ain.y + 1.0f;
+    r.z = ain.z + 1.0f;
+    r.w = ain.w + 1.0f;
+    return r;
+}
+
+double __attribute__((kernel)) test_f64(double ain) {
+    return ain + 1.0;
+}
+
+double2 __attribute__((kernel)) test_f64_2(double2 ain) {
+    double2 r;
+    r.x = ain.x + 1.0;
+    r.y = ain.y + 1.0;
+    return r;
+}
+
+double3 __attribute__((kernel)) test_f64_3(double3 ain) {
+    double3 r;
+    r.x = ain.x + 1.0;
+    r.y = ain.y + 1.0;
+    r.z = ain.z + 1.0;
+    return r;
+}
+
+double4 __attribute__((kernel)) test_f64_4(double4 ain) {
+    double4 r;
+    r.x = ain.x + 1.0;
+    r.y = ain.y + 1.0;
+    r.z = ain.z + 1.0;
+    r.w = ain.w + 1.0;
+    return r;
+}
+
+struct kernel_test {
+    int i;
+    char ignored1;
+    float f;
+};
+
+struct kernel_test __attribute__((kernel)) test_struct(struct kernel_test ain) {
+    struct kernel_test r;
+    r.i = ain.i + 1;
+    r.f = ain.f + 1.0f;
+    return r;
+}
+
+bool __attribute__((kernel)) test_bool(bool ain) {
+    return !ain;
+}
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/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
index 5cac9f9..e0ffaf7 100644
--- a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
+++ b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
@@ -122,6 +122,8 @@
         info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
         info.setAccessibilityFocused(true);
         info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
+        info.setLabeledBy(new View(getContext()));
+        info.setLabelFor(new View(getContext()));
     }
 
     /**
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_text_traversal_test.xml b/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
index 1c15f8e..5b3d2e6 100644
--- a/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
+++ b/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
@@ -40,6 +40,7 @@
        android:layout_height="200dip"
        android:maxLines="1000"
        android:scrollbars="vertical"
+       android:focusable="false"
        />
 
 </LinearLayout>
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/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
index 80ddd87..0f687d0 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
@@ -77,8 +77,11 @@
                 AccessibilityServiceInfo.FEEDBACK_SPOKEN));
         assertEquals("[FEEDBACK_VISUAL]", AccessibilityServiceInfo.feedbackTypeToString(
                 AccessibilityServiceInfo.FEEDBACK_VISUAL));
+        assertEquals("[FEEDBACK_BRAILLE]", AccessibilityServiceInfo.feedbackTypeToString(
+                AccessibilityServiceInfo.FEEDBACK_BRAILLE));
         assertEquals("[FEEDBACK_SPOKEN, FEEDBACK_HAPTIC, FEEDBACK_AUDIBLE, FEEDBACK_VISUAL,"
-                + " FEEDBACK_GENERIC]", AccessibilityServiceInfo.feedbackTypeToString(
+                + " FEEDBACK_GENERIC, FEEDBACK_BRAILLE]",
+                AccessibilityServiceInfo.feedbackTypeToString(
                         AccessibilityServiceInfo.FEEDBACK_ALL_MASK));
     }
 
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
index f65627c..2b6dab4 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -372,6 +372,23 @@
     }
 
     @MediumTest
+    public void testPerformGlobalActionQuickSettings() throws Exception {
+        // Check whether the action succeeded.
+        assertTrue(getInteractionBridge().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_QUICK_SETTINGS));
+
+        // Sleep a bit so the UI is settles.
+        SystemClock.sleep(3000);
+
+        // Clean up.
+        getInteractionBridge().performGlobalAction(
+                AccessibilityService.GLOBAL_ACTION_BACK);
+
+        // Sleep a bit so the UI is settles.
+        SystemClock.sleep(3000);
+    }
+
+    @MediumTest
     public void testObjectContract() throws Exception {
         try {
             getInteractionBridge().setRegardViewsNotImportantForAccessibility(true);
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/app/src/android/app/cts/SystemFeaturesTest.java b/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
index a68cfb8..0dfd504 100644
--- a/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -113,7 +113,9 @@
             assertNotAvailable(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
             assertNotAvailable(PackageManager.FEATURE_CAMERA_FLASH);
             assertNotAvailable(PackageManager.FEATURE_CAMERA_FRONT);
+            assertNotAvailable(PackageManager.FEATURE_CAMERA_ANY);
         } else {
+            assertAvailable(PackageManager.FEATURE_CAMERA_ANY);
             checkFrontCamera();
             checkRearCamera();
         }
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/content/src/android/content/res/cts/ConfigurationTest.java b/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
index 70443b0..30c78a8 100644
--- a/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
@@ -22,6 +22,7 @@
 import android.content.res.Configuration;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
+import android.view.View;
 
 public class ConfigurationTest extends AndroidTestCase {
 
@@ -154,24 +155,29 @@
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC, mConfigDefault, config);
         config.locale = Locale.getDefault();
+        config.setLayoutDirection(config.locale);
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
-                | ActivityInfo.CONFIG_LOCALE, mConfigDefault, config);
+                | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION, mConfigDefault, config);
         config.screenLayout = 1;
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT, mConfigDefault, config);
         config.touchscreen = 1;
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
                 | ActivityInfo.CONFIG_TOUCHSCREEN, mConfigDefault, config);
         config.keyboard = 1;
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
                 | ActivityInfo.CONFIG_TOUCHSCREEN
                 | ActivityInfo.CONFIG_KEYBOARD, mConfigDefault, config);
@@ -179,6 +185,7 @@
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
                 | ActivityInfo.CONFIG_TOUCHSCREEN
                 | ActivityInfo.CONFIG_KEYBOARD
@@ -188,6 +195,7 @@
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
                 | ActivityInfo.CONFIG_TOUCHSCREEN
                 | ActivityInfo.CONFIG_KEYBOARD
@@ -197,6 +205,7 @@
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
                 | ActivityInfo.CONFIG_TOUCHSCREEN
                 | ActivityInfo.CONFIG_KEYBOARD
@@ -205,6 +214,7 @@
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
                 | ActivityInfo.CONFIG_TOUCHSCREEN
                 | ActivityInfo.CONFIG_KEYBOARD
@@ -214,6 +224,7 @@
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
                 | ActivityInfo.CONFIG_TOUCHSCREEN
                 | ActivityInfo.CONFIG_KEYBOARD
@@ -224,6 +235,7 @@
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
                 | ActivityInfo.CONFIG_TOUCHSCREEN
                 | ActivityInfo.CONFIG_KEYBOARD
@@ -235,6 +247,7 @@
         doConfigCompare(ActivityInfo.CONFIG_MCC
                 | ActivityInfo.CONFIG_MNC
                 | ActivityInfo.CONFIG_LOCALE
+                | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                 | ActivityInfo.CONFIG_SCREEN_LAYOUT
                 | ActivityInfo.CONFIG_TOUCHSCREEN
                 | ActivityInfo.CONFIG_KEYBOARD
@@ -280,6 +293,62 @@
         assertWriteToParcel(createConfig(Locale.JAPAN), Parcel.obtain());
     }
 
+    public void testSetLocale() {
+        Configuration config = new Configuration();
+
+        config.setLocale(Locale.getDefault());
+        assertEquals(Locale.getDefault(), config.locale);
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+        config.setLocale(Locale.ENGLISH);
+        assertEquals(Locale.ENGLISH, config.locale);
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+        config.setLocale(Locale.US);
+        assertEquals(Locale.US, config.locale);
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+        final Locale arEGLocale = new Locale("ar", "EG");
+        config.setLocale(arEGLocale);
+        assertEquals(arEGLocale, config.locale);
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+        final Locale faFALocale = new Locale("fa", "FA");
+        config.setLocale(faFALocale);
+        assertEquals(faFALocale, config.locale);
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+        final Locale iwILLocale = new Locale("iw", "IL");
+        config.setLocale(iwILLocale);
+        assertEquals(iwILLocale, config.locale);
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
+    public void testSetGetLayoutDirection() {
+        Configuration config = new Configuration();
+
+        config.setLayoutDirection(Locale.getDefault());
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+        config.setLayoutDirection(Locale.ENGLISH);
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+        config.setLayoutDirection(Locale.US);
+        assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+        final Locale arEGLocale = new Locale("ar", "EG");
+        config.setLayoutDirection(arEGLocale);
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+        final Locale faFALocale = new Locale("fa", "FA");
+        config.setLayoutDirection(faFALocale);
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+        final Locale iwILLocale = new Locale("iw", "IL");
+        config.setLayoutDirection(iwILLocale);
+        assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+    }
+
     private Configuration createConfig(Locale locale) {
         Configuration config = new Configuration();
         config.fontScale = 13.37f;
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/StateListDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
index 0bda619..891ce5e 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/StateListDrawableTest.java
@@ -231,10 +231,11 @@
         StateListDrawable d3 =
             (StateListDrawable) mResources.getDrawable(R.drawable.statelistdrawable);
 
+        // StateListDrawable mutates its children when jumping to a new drawable
         d1.getCurrent().setAlpha(100);
         assertEquals(100, ((BitmapDrawable) d1.getCurrent()).getPaint().getAlpha());
-        assertEquals(100, ((BitmapDrawable) d2.getCurrent()).getPaint().getAlpha());
-        assertEquals(100, ((BitmapDrawable) d3.getCurrent()).getPaint().getAlpha());
+        assertEquals(255, ((BitmapDrawable) d2.getCurrent()).getPaint().getAlpha());
+        assertEquals(255, ((BitmapDrawable) d3.getCurrent()).getPaint().getAlpha());
 
         d1.mutate();
 
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 3958672..0e0def4 100755
--- a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
@@ -2758,4 +2758,90 @@
         }
         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();
+    }
+
+    public void testEnableShutterSound() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testEnableShutterSoundByCamera(id);
+        }
+    }
+
+    private void testEnableShutterSoundByCamera(int id) throws Exception {
+        CameraInfo info = new CameraInfo();
+
+        Camera.getCameraInfo(id, info);
+
+        initializeMessageLooper(id);
+
+        boolean result;
+        Log.v(TAG, "testEnableShutterSoundByCamera: canDisableShutterSound: " +
+                info.canDisableShutterSound);
+        result = mCamera.enableShutterSound(false);
+        assertTrue(result == info.canDisableShutterSound);
+        result = mCamera.enableShutterSound(true);
+        assertTrue(result);
+
+        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-hdpi/holo_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view.png
index ca76241..8b19f68 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view_feb.png
index fdab8d3..658dd00 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view.png
index bb81362..79a3b76 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
index 52822a1..26b7163 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
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-mdpi/holo_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_calendar_view.png
index 75c5f49..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_calendar_view_feb.png
index f4e805c..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view.png
index 75c5f49..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view_feb.png
index f4e805c..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view.png
index 75c5f49..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view_feb.png
index f4e805c..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view.png
index e7ed15b..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view_feb.png
index 2888816..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
index e7ed15b..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
index 2888816..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view.png
index 75c5f49..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view_feb.png
index f4e805c..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
index e7ed15b..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
index 2888816..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view.png
index 5ffe8b7..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view_feb.png
index 76ec605..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view.png
index f88d630..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view_feb.png
index f8402ad..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view.png
index f88d630..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view_feb.png
index f8402ad..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view.png
index f88d630..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view_feb.png
index f8402ad..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view.png
index f88d630..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view_feb.png
index f8402ad..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view.png
index 5ffe8b7..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
index 76ec605..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
index 5ffe8b7..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
index 76ec605..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view.png
index f88d630..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
index f8402ad..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
index 5ffe8b7..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
index 76ec605..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view.png
index 5ffe8b7..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view_feb.png
index 76ec605..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view.png
index 5ffe8b7..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
index 76ec605..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view.png
index 5ffe8b7..0263f1e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view_feb.png
index 76ec605..27040b6 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view.png
index e7ed15b..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view_feb.png
index 2888816..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view.png
index e7ed15b..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
index 2888816..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view.png
index e7ed15b..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view_feb.png
index 2888816..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view.png
index 75c5f49..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view_feb.png
index f4e805c..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view.png
index e7ed15b..914744f 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
index 2888816..4656c20 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
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..4b489a9 100755
--- a/tests/tests/location/src/android/location/cts/LocationManagerTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
@@ -33,10 +33,10 @@
 import android.os.Bundle;
 import android.os.HandlerThread;
 import android.os.Looper;
+import android.os.SystemClock;
 import android.provider.Settings;
 import android.test.InstrumentationTestCase;
 
-import java.lang.Thread;
 import java.util.List;
 import java.lang.Thread;
 
@@ -54,6 +54,8 @@
 
     private static final String UNKNOWN_PROVIDER_NAME = "unknown_provider";
 
+    private static final String FUSED_PROVIDER_NAME = "fused";
+
     private LocationManager mManager;
 
     private Context mContext;
@@ -454,7 +456,7 @@
         i.setAction("android.location.cts.TEST_GET_GPS_STATUS_ACTION");
         PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_ONE_SHOT);
 
-        mManager.addProximityAlert(0, 0, 0, 5000, pi);
+        mManager.addProximityAlert(0, 0, 1.0f, 5000, pi);
         mManager.removeProximityAlert(pi);
     }
 
@@ -608,9 +610,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);
@@ -623,12 +622,17 @@
      * @param expiration - expiration of proximity alert
      */
     private void doTestEnterProximity(long expiration) throws Exception {
+        // need to mock the fused location provider for proximity tests
+        mockFusedLocation();
+
         // update location to outside proximity range
-        updateLocation(30, 30);
+        updateLocation(FUSED_PROVIDER_NAME, 30, 30);
         registerProximityListener(0, 0, 1000, expiration);
-        updateLocation(0, 0);
+        updateLocation(FUSED_PROVIDER_NAME, 0, 0);
         waitForReceiveBroadcast();
         assertProximityType(true);
+
+        unmockFusedLocation();
     }
 
     private void registerIntentReceiver() {
@@ -679,8 +683,9 @@
         Location location = new Location(providerName);
         location.setLatitude(latitude);
         location.setLongitude(longitude);
-
+        location.setAccuracy(1.0f);
         location.setTime(java.lang.System.currentTimeMillis());
+        location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
         mManager.setTestProviderLocation(providerName, location);
     }
 
@@ -688,6 +693,14 @@
         updateLocation(TEST_MOCK_PROVIDER_NAME, latitude, longitude);
     }
 
+    private void mockFusedLocation() {
+        addTestProvider(FUSED_PROVIDER_NAME);
+    }
+
+    private void unmockFusedLocation() {
+        mManager.removeTestProvider(FUSED_PROVIDER_NAME);
+    }
+
     /**
      * Helper class that receives a proximity intent and notifies the main class
      * when received
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/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index dccfcaf..9500606 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -305,6 +305,7 @@
         mAudioManager.adjustVolume(ADJUST_RAISE, 0);
         mAudioManager.adjustSuggestedStreamVolume(
                 ADJUST_LOWER, USE_DEFAULT_STREAM_TYPE, 0);
+        int maxMusicVolume = mAudioManager.getStreamMaxVolume(STREAM_MUSIC);
 
         for (int i = 0; i < streams.length; i++) {
             // set ringer mode to back normal to not interfere with volume tests
@@ -315,6 +316,21 @@
             mAudioManager.setStreamVolume(streams[i], 1, 0);
             assertEquals(1, mAudioManager.getStreamVolume(streams[i]));
 
+            if (streams[i] == AudioManager.STREAM_MUSIC && mAudioManager.isWiredHeadsetOn()) {
+                // due to new regulations, music sent over a wired headset may be volume limited
+                // until the user explicitly increases the limit, so we can't rely on being able
+                // to set the volume to getStreamMaxVolume(). Instead, determine the current limit
+                // by increasing the volume until it won't go any higher, then use that volume as
+                // the maximum for the purposes of this test
+                int curvol = 0;
+                int prevvol = 0;
+                do {
+                    prevvol = curvol;
+                    mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
+                    curvol = mAudioManager.getStreamVolume(streams[i]);
+                } while (curvol != prevvol);
+                maxVolume = maxMusicVolume = curvol;
+            }
             mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
             mAudioManager.adjustStreamVolume(streams[i], ADJUST_RAISE, 0);
             assertEquals(maxVolume, mAudioManager.getStreamVolume(streams[i]));
@@ -348,7 +364,6 @@
         }
 
         // adjust volume
-        int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_MUSIC);
         mAudioManager.adjustVolume(ADJUST_RAISE, 0);
 
         MediaPlayer mp = MediaPlayer.create(mContext, MP3_TO_PLAY);
@@ -359,24 +374,24 @@
         assertTrue(mAudioManager.isMusicActive());
 
         // adjust volume as ADJUST_SAME
-        for (int k = 0; k < maxVolume; k++) {
+        for (int k = 0; k < maxMusicVolume; k++) {
             mAudioManager.adjustVolume(ADJUST_SAME, 0);
-            assertEquals(maxVolume, mAudioManager.getStreamVolume(STREAM_MUSIC));
+            assertEquals(maxMusicVolume, mAudioManager.getStreamVolume(STREAM_MUSIC));
         }
 
         // adjust volume as ADJUST_RAISE
         mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0);
-        for (int k = 0; k < maxVolume - 1; k++) {
+        for (int k = 0; k < maxMusicVolume - 1; k++) {
             mAudioManager.adjustVolume(ADJUST_RAISE, 0);
             assertEquals(2 + k, mAudioManager.getStreamVolume(STREAM_MUSIC));
         }
 
         // adjust volume as ADJUST_LOWER
-        mAudioManager.setStreamVolume(STREAM_MUSIC, maxVolume, 0);
-        maxVolume = mAudioManager.getStreamVolume(STREAM_MUSIC);
+        mAudioManager.setStreamVolume(STREAM_MUSIC, maxMusicVolume, 0);
+        maxMusicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC);
 
         mAudioManager.adjustVolume(ADJUST_LOWER, 0);
-        assertEquals(maxVolume - 1, mAudioManager.getStreamVolume(STREAM_MUSIC));
+        assertEquals(maxMusicVolume - 1, mAudioManager.getStreamVolume(STREAM_MUSIC));
         mp.stop();
         mp.release();
         Thread.sleep(TIME_TO_PLAY);
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/CamcorderProfileTest.java b/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
index 3f28218..1df5011 100644
--- a/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
+++ b/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
@@ -266,6 +266,7 @@
                 return true;
             }
         }
+        Log.e(TAG, "Size (" + width + "x" + height + ") is not supported");
         return false;
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 0c39531..97bd731 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,14 @@
 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>();
+    private int mSelectedTimedTextIndex;
+    private Monitor mOnTimedTextCalled = new Monitor();
 
     private File mOutFile;
 
@@ -412,6 +421,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 +463,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 +660,170 @@
                 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);
+        mSelectedTimedTextIndex = index;
+    }
+
+    private void deselectSubtitleTrack(int index) throws Exception {
+        int trackIndex = mTimedTextTrackIndex.get(index);
+        mMediaPlayer.deselectTrack(trackIndex);
+        if (mSelectedTimedTextIndex == index) {
+            mSelectedTimedTextIndex = -1;
+        }
+    }
+
+    public void testDeselectTrack() throws Exception {
+        loadResource(R.raw.testvideo_with_2_subtitles);
+        loadSubtitleSource(R.raw.test_subtitle1_srt);
+        readTimedTextTracks();
+        assertEquals(getTimedTextTrackCount(), 3);
+
+        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) {
+                if (text != null) {
+                    String plainText = text.getText();
+                    if (plainText != null) {
+                        mOnTimedTextCalled.signal();
+                        Log.d(LOG_TAG, "text: " + plainText.trim());
+                    }
+                }
+            }
+        });
+        mMediaPlayer.prepare();
+        mMediaPlayer.start();
+        assertTrue(mMediaPlayer.isPlaying());
+
+        // Run twice to check if repeated selection-deselection on the same track works well.
+        for (int i = 0; i < 2; i++) {
+            // Waits until at least one subtitle is fired. Timeout is 1 sec.
+            selectSubtitleTrack(0);
+            mOnTimedTextCalled.reset();
+            assertTrue(mOnTimedTextCalled.waitForSignal(1000));
+
+            // Try deselecting track.
+            deselectSubtitleTrack(0);
+            mOnTimedTextCalled.reset();
+            assertFalse(mOnTimedTextCalled.waitForSignal(1000));
+        }
+
+        // Run the same test for external subtitle track.
+        for (int i = 0; i < 2; i++) {
+            selectSubtitleTrack(2);
+            mOnTimedTextCalled.reset();
+            assertTrue(mOnTimedTextCalled.waitForSignal(1000));
+
+            // Try deselecting track.
+            deselectSubtitleTrack(2);
+            mOnTimedTextCalled.reset();
+            assertFalse(mOnTimedTextCalled.waitForSignal(1000));
+        }
+
+        try {
+            deselectSubtitleTrack(0);
+            fail("Deselecting unselected track: expected RuntimeException, " +
+                 "but no exception has been triggered.");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        mMediaPlayer.stop();
+    }
+
+    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.d(LOG_TAG, "text: " + plainText.trim() +
+                              ", trackId: " + subtitleTrackIndex + ", posMs: " + posMs);
+                        assertTrue("The diff between subtitle's start time " + startMs +
+                                   " and current time " + posMs +
+                                   " is over tolerance " + toleranceMs,
+                                   (posMs >= startMs - toleranceMs) &&
+                                   (posMs < startMs + durationMs + toleranceMs) );
+                        assertEquals("Expected track: " + mSelectedTimedTextIndex +
+                                     ", actual track: " + subtitleTrackIndex,
+                                     mSelectedTimedTextIndex, subtitleTrackIndex);
+                        mOnTimedTextCalled.signal();
+                    }
+                }
+            }
+        });
+
+        mMediaPlayer.prepare();
+        assertFalse(mMediaPlayer.isPlaying());
+
+        selectSubtitleTrack(0);
+        mOnTimedTextCalled.reset();
+
+        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
+        assertTrue(mOnTimedTextCalled.waitForCountedSignals(2, 2000) >= 2);
+
+        selectSubtitleTrack(1);
+        mOnTimedTextCalled.reset();
+        assertTrue(mOnTimedTextCalled.waitForCountedSignals(2, 2000) >= 2);
+
+        selectSubtitleTrack(2);
+        mOnTimedTextCalled.reset();
+        assertTrue(mOnTimedTextCalled.waitForCountedSignals(2, 2000) >= 2);
+
+        selectSubtitleTrack(3);
+        mOnTimedTextCalled.reset();
+        assertTrue(mOnTimedTextCalled.waitForCountedSignals(2, 2000) >= 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..61d8792 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
@@ -33,47 +33,62 @@
     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;
+        private int numSignal;
 
         public synchronized void reset() {
-            signalled = false;
+            numSignal = 0;
         }
 
         public synchronized void signal() {
-            signalled = true;
+            numSignal++;
             notifyAll();
         }
 
-        public synchronized void waitForSignal() throws InterruptedException {
-            while (!signalled) {
-                wait();
-            }
+        public synchronized boolean waitForSignal() throws InterruptedException {
+            return waitForCountedSignals(1) > 0;
         }
 
-        public synchronized void waitForSignal(long millis) throws InterruptedException {
-            if (millis == 0) {
-                waitForSignal();
-                return;
+        public synchronized int waitForCountedSignals(int targetCount) throws InterruptedException {
+            while (numSignal < targetCount) {
+                wait();
             }
+            return numSignal;
+        }
 
-            long deadline = System.currentTimeMillis() + millis;
-            while (!signalled) {
+        public synchronized boolean waitForSignal(long timeoutMs) throws InterruptedException {
+            return waitForCountedSignals(1, timeoutMs) > 0;
+        }
+
+        public synchronized int waitForCountedSignals(int targetCount, long timeoutMs)
+                throws InterruptedException {
+            if (timeoutMs == 0) {
+                return waitForCountedSignals(targetCount);
+            }
+            long deadline = System.currentTimeMillis() + timeoutMs;
+            while (numSignal < targetCount) {
                 long delay = deadline - System.currentTimeMillis();
                 if (delay <= 0) {
                     break;
                 }
                 wait(delay);
             }
+            return numSignal;
         }
 
         public synchronized boolean isSignalled() {
-            return signalled;
+            return numSignal >= 1;
+        }
+
+        public synchronized int getNumSignal() {
+            return numSignal;
         }
     }
 
     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 +147,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();
         }
@@ -190,7 +224,7 @@
             public void onVideoSizeChanged(MediaPlayer mp, int w, int h) {
                 if (w == 0 && h == 0) {
                     // A size of 0x0 can be sent initially one time when using NuPlayer.
-                    assertFalse(mOnVideoSizeChangedCalled.signalled);
+                    assertFalse(mOnVideoSizeChangedCalled.isSignalled());
                     return;
                 }
                 mOnVideoSizeChangedCalled.signal();
@@ -209,6 +243,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 +261,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..adee09d
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
@@ -0,0 +1,347 @@
+/*
+ * 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 com.android.cts.media.R;
+
+import android.media.MediaRecorder;
+import android.media.MediaPlayer;
+import android.view.SurfaceHolder;
+import android.test.ActivityInstrumentationTestCase2;
+import android.os.Environment;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.util.Log;
+
+import java.util.Random;
+
+/**
+ * Tests for the MediaPlayer.java and MediaRecorder.java APIs
+ *
+ * These testcases make randomized calls to the public APIs available, and
+ * the focus is on whether the randomized calls can lead to crash in
+ * mediaserver process and/or ANRs.
+ *
+ * The files in res/raw used by testLocalVideo* are (c) copyright 2008,
+ * Blender Foundation / www.bigbuckbunny.org, and are licensed under the Creative Commons
+ * Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
+ */
+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 static final int NUMBER_OF_PLAYER_RANDOM_ACTIONS   = 100000;
+
+    private MediaRecorder mRecorder;
+    private MediaPlayer mPlayer;
+    private SurfaceHolder mSurfaceHolder;
+    private Resources mResources;
+
+    // Modified across multiple threads
+    private volatile boolean mMediaServerDied;
+    private volatile int mAction;
+    private volatile int mParam;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        getInstrumentation().waitForIdleSync();
+        mMediaServerDied = false;
+        mSurfaceHolder = getActivity().getSurfaceHolder();
+        mResources = getInstrumentation().getTargetContext().getResources();
+        try {
+            // Running this on UI thread make sure that
+            // onError callback can be received.
+            runTestOnUiThread(new Runnable() {
+                public void run() {
+                    mRecorder = new MediaRecorder();
+                    mPlayer = new MediaPlayer();
+                }
+            });
+        } catch (Throwable e) {
+            e.printStackTrace();
+            fail();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mRecorder != null) {
+            mRecorder.release();
+            mRecorder = null;
+        }
+        if (mPlayer != null) {
+            mPlayer.release();
+            mPlayer = 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);
+    }
+
+    private void loadSource(int resid) throws Exception {
+        AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
+        try {
+            mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
+                    afd.getLength());
+        } finally {
+            afd.close();
+        }
+    }
+
+    public void testPlayerRandomAction() throws Exception {
+        try {
+            mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+                @Override
+                public boolean onError(MediaPlayer mp, int what, int extra) {
+                    if (mPlayer == mp &&
+                        what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
+                        Log.e(TAG, "mediaserver process died");
+                        mMediaServerDied = true;
+                    }
+                    return true;
+                }
+            });
+            loadSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
+            mPlayer.setDisplay(mSurfaceHolder);
+            mPlayer.prepare();
+            mPlayer.start();
+
+            long seed = System.currentTimeMillis();
+            Log.v(TAG, "seed = " + seed);
+            Random r = new Random(seed);
+
+            Watchdog watchdog = new Watchdog(5000);
+            watchdog.start();
+            for (int i = 0; i < NUMBER_OF_PLAYER_RANDOM_ACTIONS; i++){
+                watchdog.ping();
+                assertTrue(!mMediaServerDied);
+
+                mAction = (int)(r.nextInt() % 12);
+                mParam = (int)(r.nextInt() % 1000000);
+                try {
+                    switch (mAction) {
+                    case 0:
+                        mPlayer.getCurrentPosition();
+                        break;
+                    case 1:
+                        mPlayer.getDuration();
+                        break;
+                    case 2:
+                        mPlayer.getVideoHeight();
+                        break;
+                    case 3:
+                        mPlayer.getVideoWidth();
+                       break;
+                    case 4:
+                        mPlayer.isPlaying();
+                        break;
+                    case 5:
+                        mPlayer.pause();
+                        break;
+                    case 6:
+                        // Don't add mPlayer.prepare() call here for two reasons:
+                        // 1. calling prepare() is a bad idea since it is a blocking call, and
+                        // 2. when prepare() is in progress, mediaserver died message will not be sent to apps
+                        mPlayer.prepareAsync();
+                        break;
+                    case 7:
+                        mPlayer.seekTo((int)(mParam));
+                        break;
+                    case 8:
+                        mPlayer.setLooping(mParam % 2 == 0);
+                        break;
+                    case 9:
+                        mPlayer.setVolume((mParam % 1000) / 500.0f,
+                                     (mParam / 1000) / 500.0f);
+                        break;
+                    case 10:
+                        mPlayer.start();
+                        break;
+                    case 11:
+                        Thread.sleep(mParam % 20);
+                        break;
+                    }
+                } catch (Exception e) {
+                }
+            }
+            mPlayer.stop();
+            watchdog.end();
+            watchdog.join();
+        } catch (Exception e) {
+            Log.v(TAG, e.toString());
+        }
+    }
+
+    public void testRecorderRandomAction() 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) {
+                    if (mRecorder == recorder &&
+                        what == MediaRecorder.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};
+
+            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(mSurfaceHolder.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/mediastress/jni/native-media-jni.cpp b/tests/tests/mediastress/jni/native-media-jni.cpp
index 8df937f..4a105e1 100644
--- a/tests/tests/mediastress/jni/native-media-jni.cpp
+++ b/tests/tests/mediastress/jni/native-media-jni.cpp
@@ -16,7 +16,7 @@
 
 /* Original code copied from NDK Native-media sample code */
 
-
+#undef NDEBUG
 #include <assert.h>
 #include <jni.h>
 #include <pthread.h>
@@ -26,8 +26,9 @@
 // for __android_log_print(ANDROID_LOG_INFO, "YourApp", "formatted message");
 #include <android/log.h>
 #define TAG "NativeMedia"
-#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
-#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
+#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
+#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
 // for native media
 #include <OMXAL/OpenMAXAL.h>
 #include <OMXAL/OpenMAXAL_Android.h>
@@ -60,11 +61,139 @@
  */
 #define RETURN_ON_ASSERTION_FAILURE(cond, env, clazz)                                   \
         if (!(cond)) {                                                                  \
-            LOGE("assertion failure at file %s line %d", __FILE__, __LINE__);           \
+            ALOGE("assertion failure at file %s line %d", __FILE__, __LINE__);           \
             Java_android_mediastress_cts_NativeMediaActivity_shutdown((env), (clazz));  \
             return JNI_FALSE;                                                           \
         }
 
+// number of buffers in our buffer queue, an arbitrary number
+#define NB_BUFFERS 16
+
+// we're streaming MPEG-2 transport stream data, operate on transport stream block size
+#define MPEG2_TS_BLOCK_SIZE 188
+
+// number of MPEG-2 transport stream blocks per buffer, an arbitrary number
+#define BLOCKS_PER_BUFFER 20
+
+// determines how much memory we're dedicating to memory caching
+#define BUFFER_SIZE (BLOCKS_PER_BUFFER*MPEG2_TS_BLOCK_SIZE)
+
+// where we cache in memory the data to play
+// note this memory is re-used by the buffer queue callback
+char dataCache[BUFFER_SIZE * NB_BUFFERS];
+
+// handle of the file to play
+static FILE *file = NULL;
+
+// has the app reached the end of the file
+static jboolean reachedEof = JNI_FALSE;
+
+// constant to identify a buffer context which is the end of the stream to decode
+static const int kEosBufferCntxt = 1980; // a magic value we can compare against
+
+// for mutual exclusion between callback thread and application thread(s)
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+
+static jboolean enqueueInitialBuffers() {
+
+    /* Fill our cache */
+    size_t nbRead;
+    nbRead = fread(dataCache, BUFFER_SIZE, NB_BUFFERS, file);
+    if (nbRead <= 0) {
+        // could be premature EOF or I/O error
+        ALOGE("Error filling cache, exiting\n");
+        return JNI_FALSE;
+    }
+    assert(1 <= nbRead && nbRead <= NB_BUFFERS);
+    ALOGV("Initially queueing %u buffers of %u bytes each", nbRead, BUFFER_SIZE);
+
+    /* Enqueue the content of our cache before starting to play,
+       we don't want to starve the player */
+    size_t i;
+    for (i = 0; i < nbRead; i++) {
+        XAresult res = (*playerBQItf)->Enqueue(playerBQItf, NULL /*pBufferContext*/,
+                    dataCache + i*BUFFER_SIZE, BUFFER_SIZE, NULL, 0);
+        assert(XA_RESULT_SUCCESS == res);
+    }
+
+    return JNI_TRUE;
+}
+// AndroidBufferQueueItf callback for an audio player
+extern "C" XAresult AndroidBufferQueueCallback(
+        XAAndroidBufferQueueItf caller,
+        void *pCallbackContext,        /* input */
+        void *pBufferContext,          /* input */
+        void *pBufferData,             /* input */
+        XAuint32 dataSize,             /* input */
+        XAuint32 dataUsed,             /* input */
+        const XAAndroidBufferItem *pItems,/* input */
+        XAuint32 itemsLength           /* input */)
+{
+    XAresult res;
+    int ok;
+
+    // pCallbackContext was specified as NULL at RegisterCallback and is unused here
+    assert(NULL == pCallbackContext);
+
+    // note there is never any contention on this mutex unless a discontinuity request is active
+    ok = pthread_mutex_lock(&mutex);
+    assert(0 == ok);
+
+    if ((pBufferData == NULL) && (pBufferContext != NULL)) {
+        const int processedCommand = *(int *)pBufferContext;
+        if (kEosBufferCntxt == processedCommand) {
+            ALOGV("EOS was processed\n");
+            // our buffer with the EOS message has been consumed
+            assert(0 == dataSize);
+            goto exit;
+        }
+    }
+
+    // pBufferData is a pointer to a buffer that we previously Enqueued
+    assert(BUFFER_SIZE == dataSize);
+    assert(dataCache <= (char *) pBufferData && (char *) pBufferData <
+            &dataCache[BUFFER_SIZE * NB_BUFFERS]);
+    assert(0 == (((char *) pBufferData - dataCache) % BUFFER_SIZE));
+
+    // don't bother trying to read more data once we've hit EOF
+    if (reachedEof) {
+        goto exit;
+    }
+
+    size_t nbRead;
+    // note we do call fread from multiple threads, but never concurrently
+    nbRead = fread(pBufferData, BUFFER_SIZE, 1, file);
+    if (nbRead > 0) {
+        assert(1 == nbRead);
+        res = (*caller)->Enqueue(caller, NULL /*pBufferContext*/,
+                pBufferData /*pData*/,
+                nbRead * BUFFER_SIZE /*dataLength*/,
+                NULL /*pMsg*/,
+                0 /*msgLength*/);
+        assert(XA_RESULT_SUCCESS == res);
+    } else {
+        // signal EOS
+        XAAndroidBufferItem msgEos[1];
+        msgEos[0].itemKey = XA_ANDROID_ITEMKEY_EOS;
+        msgEos[0].itemSize = 0;
+        // EOS message has no parameters, so the total size of the message is the size of the key
+        //   plus the size if itemSize, both XAuint32
+        res = (*caller)->Enqueue(caller, (void *)&kEosBufferCntxt /*pBufferContext*/,
+                NULL /*pData*/, 0 /*dataLength*/,
+                msgEos /*pMsg*/,
+                // FIXME == sizeof(BufferItem)? */
+                sizeof(XAuint32)*2 /*msgLength*/);
+        assert(XA_RESULT_SUCCESS == res);
+        reachedEof = JNI_TRUE;
+    }
+
+exit:
+    ok = pthread_mutex_unlock(&mutex);
+    assert(0 == ok);
+    return XA_RESULT_SUCCESS;
+}
+
 // callback invoked whenever there is new or changed stream information
 static void StreamChangeCallback(XAStreamInformationItf caller,
         XAuint32 eventId,
@@ -72,7 +201,7 @@
         void * pEventData,
         void * pContext )
 {
-    LOGV("StreamChangeCallback called for stream %u", streamIndex);
+    ALOGV("StreamChangeCallback called for stream %u", streamIndex);
     // pContext was specified as NULL at RegisterStreamChangeCallback and is unused here
     assert(NULL == pContext);
     switch (eventId) {
@@ -91,18 +220,18 @@
             XAVideoStreamInformation videoInfo;
             res = (*caller)->QueryStreamInformation(caller, streamIndex, &videoInfo);
             assert(XA_RESULT_SUCCESS == res);
-            LOGV("Found video size %u x %u, codec ID=%u, frameRate=%u, bitRate=%u, duration=%u ms",
+            ALOGV("Found video size %u x %u, codec ID=%u, frameRate=%u, bitRate=%u, duration=%u ms",
                         videoInfo.width, videoInfo.height, videoInfo.codecId, videoInfo.frameRate,
                         videoInfo.bitRate, videoInfo.duration);
           } break;
           default:
-              LOGE("Unexpected domain %u\n", domain);
+              ALOGE("Unexpected domain %u\n", domain);
             break;
         }
       } break;
       default:
-          LOGE("Unexpected stream event ID %u\n", eventId);
-        break;
+          ALOGE("Unexpected stream event ID %u\n", eventId);
+          break;
     }
 }
 
@@ -142,6 +271,13 @@
         ANativeWindow_release(theNativeWindow);
         theNativeWindow = NULL;
     }
+
+    // close the file
+    if (file != NULL) {
+        fclose(file);
+        file = NULL;
+    }
+
 }
 
 // create the engine and output mix objects
@@ -184,10 +320,17 @@
     const char *utf8 = env->GetStringUTFChars(fileUri, NULL);
     RETURN_ON_ASSERTION_FAILURE((NULL != utf8), env, clazz);
 
-    XADataLocator_URI uri = {XA_DATALOCATOR_URI, (XAchar*) utf8};
+    RETURN_ON_ASSERTION_FAILURE(strstr(utf8, "file:///") == utf8, env, clazz);
+
+    file = fopen(utf8 + 7, "rb");
+    RETURN_ON_ASSERTION_FAILURE(file != NULL, env, clazz);
+
+
+    // configure data source
+    XADataLocator_AndroidBufferQueue loc_abq = { XA_DATALOCATOR_ANDROIDBUFFERQUEUE, NB_BUFFERS };
     XADataFormat_MIME format_mime = {
             XA_DATAFORMAT_MIME, XA_ANDROID_MIME_MP2TS, XA_CONTAINERTYPE_MPEG_TS };
-    XADataSource dataSrc = {&uri, &format_mime};
+    XADataSource dataSrc = {&loc_abq, &format_mime};
 
     // configure audio sink
     XADataLocator_OutputMix loc_outmix = { XA_DATALOCATOR_OUTPUTMIX, outputMixObject };
@@ -238,6 +381,22 @@
     res = (*playerObj)->GetInterface(playerObj, XA_IID_VOLUME, &playerVolItf);
     RETURN_ON_ASSERTION_FAILURE((XA_RESULT_SUCCESS == res), env, clazz);
 
+    // get the Android buffer queue interface
+    res = (*playerObj)->GetInterface(playerObj, XA_IID_ANDROIDBUFFERQUEUESOURCE, &playerBQItf);
+    assert(XA_RESULT_SUCCESS == res);
+
+    // specify which events we want to be notified of
+    res = (*playerBQItf)->SetCallbackEventsMask(playerBQItf, XA_ANDROIDBUFFERQUEUEEVENT_PROCESSED);
+
+    // register the callback from which OpenMAX AL can retrieve the data to play
+    res = (*playerBQItf)->RegisterCallback(playerBQItf, AndroidBufferQueueCallback, NULL);
+    assert(XA_RESULT_SUCCESS == res);
+
+    // enqueue the initial buffers
+    if (!enqueueInitialBuffers()) {
+        return JNI_FALSE;
+    }
+
     // we want to be notified of the video size once it's found, so we register a callback for that
     res = (*playerStreamInfoItf)->RegisterStreamChangeCallback(playerStreamInfoItf,
             StreamChangeCallback, NULL);
@@ -282,3 +441,5 @@
     theNativeWindow = ANativeWindow_fromSurface(env, surface);
     return JNI_TRUE;
 }
+
+
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaActivity.java b/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaActivity.java
index 4232fbf..db3657f 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaActivity.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/NativeMediaActivity.java
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 import android.util.Log;
 import android.view.Surface;
+import android.view.WindowManager;
 
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -57,6 +58,8 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
+                WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
         mVideoQuality = getIntent().getIntExtra(EXTRA_VIDEO_QUALITY, mVideoQuality);
         mGLView = new SurfaceTextureGLSurfaceView(this, this);
         setContentView(mGLView);
@@ -82,7 +85,7 @@
                 Assert.assertTrue(setSurfaceForNative());
                 String fileName = getMediaString();
                 Log.i(TAG, "start playing " + fileName);
-                Assert.assertTrue(createMediaPlayer("file:///" + fileName));
+                Assert.assertTrue(createMediaPlayer("file://" + fileName));
                 mNativeCreated = true;
                 mNativeWaitQ.add(mNativeCreated);
             }
diff --git a/tests/tests/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/tests/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java
index b8d0ea4..590ce89 100644
--- a/tests/tests/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java
+++ b/tests/tests/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java
@@ -37,7 +37,7 @@
 
     public void testValues() {
         DetailedState[] expected = DetailedState.values();
-        assertEquals(12, expected.length);
+        assertEquals(13, expected.length);
         assertEquals(DetailedState.IDLE, expected[0]);
         assertEquals(DetailedState.SCANNING, expected[1]);
         assertEquals(DetailedState.CONNECTING, expected[2]);
@@ -50,6 +50,7 @@
         assertEquals(DetailedState.FAILED, expected[9]);
         assertEquals(DetailedState.BLOCKED, expected[10]);
         assertEquals(DetailedState.VERIFYING_POOR_LINK, expected[11]);
+        assertEquals(DetailedState.CAPTIVE_PORTAL_CHECK, expected[12]);
     }
 
 }
diff --git a/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java
index 26cfff83..c9b82ee 100644
--- a/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java
@@ -26,6 +26,7 @@
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.WifiLock;
 import android.test.AndroidTestCase;
+import android.util.Log;
 
 public class ScanResultTest extends AndroidTestCase {
     private static class MySync {
@@ -39,11 +40,14 @@
     private static final int STATE_NULL = 0;
     private static final int STATE_WIFI_CHANGING = 1;
     private static final int STATE_WIFI_CHANGED = 2;
+    private static final int STATE_START_SCAN = 3;
+    private static final int STATE_SCAN_RESULTS_AVAILABLE = 4;
 
     private static final String TAG = "WifiInfoTest";
     private static final int TIMEOUT_MSEC = 6000;
     private static final int WAIT_MSEC = 60;
-    private static final int DURATION = 10000;
+    private static final int ENABLE_WAIT_MSEC = 10000;
+    private static final int SCAN_WAIT_MSEC = 10000;
     private IntentFilter mIntentFilter;
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
@@ -54,6 +58,11 @@
                     mMySync.expectedState = STATE_WIFI_CHANGED;
                     mMySync.notify();
                 }
+            } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+                synchronized (mMySync) {
+                    mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE;
+                    mMySync.notify();
+                }
             }
         }
     };
@@ -83,7 +92,7 @@
         mWifiLock.acquire();
         if (!mWifiManager.isWifiEnabled())
             setWifiEnabled(true);
-        Thread.sleep(DURATION);
+        Thread.sleep(ENABLE_WAIT_MSEC);
         assertTrue(mWifiManager.isWifiEnabled());
         mMySync.expectedState = STATE_NULL;
     }
@@ -99,7 +108,7 @@
         mContext.unregisterReceiver(mReceiver);
         if (!mWifiManager.isWifiEnabled())
             setWifiEnabled(true);
-        Thread.sleep(DURATION);
+        Thread.sleep(ENABLE_WAIT_MSEC);
         super.tearDown();
     }
 
@@ -107,11 +116,15 @@
         synchronized (mMySync) {
             mMySync.expectedState = STATE_WIFI_CHANGING;
             assertTrue(mWifiManager.setWifiEnabled(enable));
-            long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-            while (System.currentTimeMillis() < timeout
-                    && mMySync.expectedState == STATE_WIFI_CHANGING)
-                mMySync.wait(WAIT_MSEC);
-        }
+            waitForBroadcast(TIMEOUT_MSEC, STATE_WIFI_CHANGED);
+       }
+    }
+
+    private void waitForBroadcast(long timeout, int expectedState) throws Exception {
+        long waitTime = System.currentTimeMillis() + timeout;
+        while (System.currentTimeMillis() < waitTime
+                && mMySync.expectedState != expectedState)
+            mMySync.wait(WAIT_MSEC);
     }
 
     public void testScanResultProperties() {
@@ -127,4 +140,49 @@
         }
     }
 
+    private void scanAndWait() throws Exception {
+        synchronized (mMySync) {
+            mMySync.expectedState = STATE_START_SCAN;
+            mWifiManager.startScan();
+            waitForBroadcast(SCAN_WAIT_MSEC, STATE_SCAN_RESULTS_AVAILABLE);
+        }
+   }
+
+    public void testScanResultTimeStamp() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+
+        long timestamp = 0;
+        String BSSID = null;
+
+        /* Multiple scans to ensure bssid is updated */
+        scanAndWait();
+        scanAndWait();
+        scanAndWait();
+
+        List<ScanResult> scanResults = mWifiManager.getScanResults();
+        for (ScanResult result : scanResults) {
+            BSSID = result.BSSID;
+            timestamp = result.timestamp;
+            assertTrue(timestamp != 0);
+            break;
+        }
+
+        scanAndWait();
+        scanAndWait();
+        scanAndWait();
+
+        scanResults = mWifiManager.getScanResults();
+        for (ScanResult result : scanResults) {
+            if (result.BSSID.equals(BSSID)) {
+                long timeDiff = (result.timestamp - timestamp) / 1000;
+                assertTrue (timeDiff > 0);
+                assertTrue (timeDiff < 6 * SCAN_WAIT_MSEC);
+            }
+        }
+
+    }
+
 }
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 5fc23e7..a64477d 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -21,17 +21,22 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.NetworkInfo;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
 import android.net.wifi.WifiConfiguration.Status;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.TxPacketCountListener;
 import android.net.wifi.WifiManager.WifiLock;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import java.net.HttpURLConnection;
+import java.net.URL;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class WifiManagerTest extends AndroidTestCase {
     private static class MySync {
@@ -42,6 +47,7 @@
     private WifiLock mWifiLock;
     private static MySync mMySync;
     private List<ScanResult> mScanResult = null;
+    private NetworkInfo mNetworkInfo;
 
     // Please refer to WifiManager
     private static final int MIN_RSSI = -100;
@@ -78,6 +84,13 @@
                     mMySync.expectedState = STATE_WIFI_CHANGED;
                     mMySync.notify();
                 }
+            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+                synchronized (mMySync) {
+                    mNetworkInfo =
+                            (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+                    if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED)
+                        mMySync.notify();
+                }
             }
         }
     };
@@ -148,6 +161,18 @@
         }
     }
 
+    private void connectWifi() throws Exception {
+        synchronized (mMySync) {
+            if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) return;
+            assertTrue(mWifiManager.reconnect());
+            long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+            while (System.currentTimeMillis() < timeout
+                    && mNetworkInfo.getState() != NetworkInfo.State.CONNECTED)
+                mMySync.wait(WAIT_MSEC);
+            assertTrue(mNetworkInfo.getState() == NetworkInfo.State.CONNECTED);
+        }
+    }
+
     private boolean existSSID(String ssid) {
         for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) {
             if (w.SSID.equals(ssid))
@@ -339,4 +364,65 @@
         rssiB = 4;
         assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) > 0);
     }
+
+    private int getTxPacketCount() throws Exception {
+        final AtomicInteger ret = new AtomicInteger(-1);
+
+        mWifiManager.getTxPacketCount(new TxPacketCountListener() {
+            @Override
+            public void onSuccess(int count) {
+                ret.set(count);
+            }
+            @Override
+            public void onFailure(int reason) {
+                ret.set(0);
+            }
+        });
+
+        long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+        while (ret.get() < 0 && System.currentTimeMillis() < timeout)
+            Thread.sleep(WAIT_MSEC);
+        assertTrue(ret.get() >= 0);
+        return ret.get();
+    }
+
+    /**
+     * The new WiFi watchdog requires kernel/driver to export some packet loss
+     * counters. This CTS tests whether those counters are correctly exported.
+     * To pass this CTS test, a connected WiFi link is required.
+     */
+    public void testWifiWatchdog() throws Exception {
+        // Make sure WiFi is enabled
+        if (!mWifiManager.isWifiEnabled()) {
+            setWifiEnabled(true);
+            Thread.sleep(DURATION);
+        }
+        assertTrue(mWifiManager.isWifiEnabled());
+
+        // Wait for a WiFi connection
+        connectWifi();
+
+        // Read TX packet counter
+        int txcount1 = getTxPacketCount();
+
+        // Do some network operations
+        HttpURLConnection connection = null;
+        try {
+            URL url = new URL("http://www.google.com/");
+            connection = (HttpURLConnection) url.openConnection();
+            connection.setInstanceFollowRedirects(false);
+            connection.setConnectTimeout(TIMEOUT_MSEC);
+            connection.setReadTimeout(TIMEOUT_MSEC);
+            connection.setUseCaches(false);
+            connection.getInputStream();
+        } catch (Exception e) {
+            // ignore
+        } finally {
+            if (connection != null) connection.disconnect();
+        }
+
+        // Read TX packet counter again and make sure it increases
+        int txcount2 = getTxPacketCount();
+        assertTrue(txcount2 > txcount1);
+    }
 }
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/os/src/android/os/cts/PowerManagerTest.java b/tests/tests/os/src/android/os/cts/PowerManagerTest.java
index 9c248a6..50a3a4f 100644
--- a/tests/tests/os/src/android/os/cts/PowerManagerTest.java
+++ b/tests/tests/os/src/android/os/cts/PowerManagerTest.java
@@ -42,17 +42,36 @@
         Thread.sleep(TIME + MORE_TIME);
         assertFalse(wl.isHeld());
 
-        long baseTime = SystemClock.uptimeMillis();
         try {
-            pm.goToSleep(baseTime + 1);
+            pm.goToSleep(SystemClock.uptimeMillis());
             fail("goToSleep should throw SecurityException");
         } catch (SecurityException e) {
             // expected
         }
-        Thread.sleep(TIME);
 
-        baseTime = SystemClock.uptimeMillis();
-        pm.userActivity(baseTime + 1, false);
-        Thread.sleep(MORE_TIME);
+        try {
+            pm.wakeUp(SystemClock.uptimeMillis());
+            fail("wakeUp should throw SecurityException");
+        } catch (SecurityException e) {
+            // expected
+        }
+
+        try {
+            pm.nap(SystemClock.uptimeMillis());
+            fail("nap should throw SecurityException");
+        } catch (SecurityException e) {
+            // expected
+        }
+
+        try {
+            pm.reboot("Testing");
+            fail("reboot should throw SecurityException");
+        } catch (SecurityException e) {
+            // expected
+        }
+
+        // This method requires DEVICE_POWER but does not throw a SecurityException
+        // for historical reasons.  So this call should be a no-op.
+        pm.userActivity(SystemClock.uptimeMillis(), false);
     }
 }
diff --git a/tests/tests/permission/src/android/permission/cts/NoWakeLockPermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoWakeLockPermissionTest.java
index 6a8f5d0..ec11a0c 100644
--- a/tests/tests/permission/src/android/permission/cts/NoWakeLockPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoWakeLockPermissionTest.java
@@ -86,7 +86,7 @@
     public void testPowerManagerWakeLockAcquire() {
         try {
             mWakeLock.acquire();
-            fail("MediaPlayer.setWakeMode() did not throw SecurityException as expected");
+            fail("WakeLock.acquire() did not throw SecurityException as expected");
         } catch (SecurityException e) {
             // expected
         }
@@ -102,23 +102,7 @@
         // Tset acquire(long)
         try {
             mWakeLock.acquire(1);
-            fail("MediaPlayer.setWakeMode(long) did not throw SecurityException as expected");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
-    /**
-     * Verify that PowerManager.WakeLock.release() requires permissions.
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#WAKE_LOCK}.
-     */
-    @SmallTest
-    public void testPowerManagerWakeLockRelease() {
-        mWakeLock.setReferenceCounted(false);
-        try {
-            mWakeLock.release();
-            fail("MediaPlayer.setWakeMode(long) did not throw SecurityException as expected");
+            fail("WakeLock.acquire(long) did not throw SecurityException as expected");
         } catch (SecurityException e) {
             // expected
         }
diff --git a/tests/tests/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java b/tests/tests/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java
index dca2bde..7ff67eb 100644
--- a/tests/tests/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java
+++ b/tests/tests/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java
@@ -81,4 +81,34 @@
             // expected
         }
     }
+
+    /**
+     * Verify that PackageManager.verifyPendingInstall requires permission.
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#PACKAGE_VERIFICATION_AGENT}
+     */
+    public void testVerifyPendingInstall() {
+        try {
+            mPackageManager.verifyPendingInstall(1, 1);
+            fail("PackageManager.verifyPendingInstall did not throw SecurityException"
+                    + " as expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    /**
+     * Verify that PackageManager.extendVerificationTimeout requires permission.
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#PACKAGE_VERIFICATION_AGENT}.
+     */
+    public void testExtendVerificationTimeout() {
+        try {
+            mPackageManager.extendVerificationTimeout(1, 1, 10000);
+            fail("PackageManager.extendVerificationTimeout did not throw SecurityException"
+                    + " as expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/CalendarTest.java b/tests/tests/provider/src/android/provider/cts/CalendarTest.java
index 8ea408f..edffc13 100644
--- a/tests/tests/provider/src/android/provider/cts/CalendarTest.java
+++ b/tests/tests/provider/src/android/provider/cts/CalendarTest.java
@@ -50,6 +50,10 @@
 
     private static final String TAG = "CalCTS";
     private static final String CTS_TEST_TYPE = "LOCAL";
+
+    // an arbitrary int used by some tests
+    private static final int SOME_ARBITRARY_INT = 143234;
+
     // @formatter:off
     private static final String[] TIME_ZONES = new String[] {
             "UTC",
@@ -2940,6 +2944,139 @@
     }
 
     /**
+     * Tests correct behavior of Calendars.isPrimary column
+     */
+    @MediumTest
+    public void testCalendarIsPrimary() {
+        String account = "ec_account";
+        int seed = 0;
+
+        // Clean up just in case
+        CalendarHelper.deleteCalendarByAccount(mContentResolver, account);
+
+        int isPrimary;
+        Cursor cursor;
+        ContentValues values = new ContentValues();
+
+        final long calendarId = createAndVerifyCalendar(account, seed++, null);
+        final Uri uri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calendarId);
+
+        // verify when ownerAccount != account_name && isPrimary IS NULL
+        cursor = mContentResolver.query(uri, new String[]{Calendars.IS_PRIMARY}, null, null, null);
+        cursor.moveToFirst();
+        isPrimary = cursor.getInt(0);
+        cursor.close();
+        assertEquals("isPrimary should be 0 if ownerAccount != account_name", 0, isPrimary);
+
+        // verify when ownerAccount == account_name && isPrimary IS NULL
+        values.clear();
+        values.put(Calendars.OWNER_ACCOUNT, account);
+        mContentResolver.update(asSyncAdapter(uri, account, CTS_TEST_TYPE), values, null, null);
+        cursor = mContentResolver.query(uri, new String[]{Calendars.IS_PRIMARY}, null, null, null);
+        cursor.moveToFirst();
+        isPrimary = cursor.getInt(0);
+        cursor.close();
+        assertEquals("isPrimary should be 1 if ownerAccount == account_name", 1, isPrimary);
+
+        // verify isPrimary IS NOT NULL
+        values.clear();
+        values.put(Calendars.IS_PRIMARY, SOME_ARBITRARY_INT);
+        mContentResolver.update(uri, values, null, null);
+        cursor = mContentResolver.query(uri, new String[]{Calendars.IS_PRIMARY}, null, null, null);
+        cursor.moveToFirst();
+        isPrimary = cursor.getInt(0);
+        cursor.close();
+        assertEquals("isPrimary should be the value it was set to", SOME_ARBITRARY_INT, isPrimary);
+
+        CalendarHelper.deleteCalendarByAccount(mContentResolver, account);
+    }
+
+    /**
+     * Tests correct behavior of Events.isOrganizer column
+     */
+    @MediumTest
+    public void testEventsIsOrganizer() {
+        String account = "ec_account";
+        int seed = 0;
+
+        // Clean up just in case
+        CalendarHelper.deleteCalendarByAccount(mContentResolver, account);
+
+        int isOrganizer;
+        Cursor cursor;
+        ContentValues values = new ContentValues();
+
+        final long calendarId = createAndVerifyCalendar(account, seed++, null);
+        final long eventId = createAndVerifyEvent(account, seed, calendarId, true, null);
+        final Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
+
+        // verify when ownerAccount != organizer && isOrganizer IS NULL
+        cursor = mContentResolver.query(uri, new String[]{Events.IS_ORGANIZER}, null, null, null);
+        cursor.moveToFirst();
+        isOrganizer = cursor.getInt(0);
+        cursor.close();
+        assertEquals("isOrganizer should be 0 if ownerAccount != organizer", 0, isOrganizer);
+
+        // verify when ownerAccount == account_name && isOrganizer IS NULL
+        values.clear();
+        values.put(Events.ORGANIZER, CalendarHelper.generateCalendarOwnerEmail(account));
+        mContentResolver.update(asSyncAdapter(uri, account, CTS_TEST_TYPE), values, null, null);
+        cursor = mContentResolver.query(uri, new String[]{Events.IS_ORGANIZER}, null, null, null);
+        cursor.moveToFirst();
+        isOrganizer = cursor.getInt(0);
+        cursor.close();
+        assertEquals("isOrganizer should be 1 if ownerAccount == organizer", 1, isOrganizer);
+
+        // verify isOrganizer IS NOT NULL
+        values.clear();
+        values.put(Events.IS_ORGANIZER, SOME_ARBITRARY_INT);
+        mContentResolver.update(uri, values, null, null);
+        cursor = mContentResolver.query(uri, new String[]{Events.IS_ORGANIZER}, null, null, null);
+        cursor.moveToFirst();
+        isOrganizer = cursor.getInt(0);
+        cursor.close();
+        assertEquals(
+                "isPrimary should be the value it was set to", SOME_ARBITRARY_INT, isOrganizer);
+        CalendarHelper.deleteCalendarByAccount(mContentResolver, account);
+    }
+
+    /**
+     * Tests correct behavior of Events.uid2445 column
+     */
+    @MediumTest
+    public void testEventsUid2445() {
+        String account = "ec_account";
+        int seed = 0;
+
+        // Clean up just in case
+        CalendarHelper.deleteCalendarByAccount(mContentResolver, account);
+
+        final String uid = "uid_123";
+        Cursor cursor;
+        ContentValues values = new ContentValues();
+        final long calendarId = createAndVerifyCalendar(account, seed++, null);
+        final long eventId = createAndVerifyEvent(account, seed, calendarId, true, null);
+        final Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
+
+        // Verify default is null
+        cursor = mContentResolver.query(uri, new String[] {Events.UID_2445}, null, null, null);
+        cursor.moveToFirst();
+        assertTrue(cursor.isNull(0));
+        cursor.close();
+
+        // Write column value and read back
+        values.clear();
+        values.put(Events.UID_2445, uid);
+        mContentResolver.update(asSyncAdapter(uri, account, CTS_TEST_TYPE), values, null, null);
+        cursor = mContentResolver.query(uri, new String[] {Events.UID_2445}, null, null, null);
+        cursor.moveToFirst();
+        assertFalse(cursor.isNull(0));
+        assertEquals("Column uid_2445 has unexpected value.", uid, cursor.getString(0));
+
+        CalendarHelper.deleteCalendarByAccount(mContentResolver, account);
+    }
+
+    /**
      * Acquires the set of instances that appear between the specified start and end points.
      *
      * @param timeZone Time zone to use when parsing startWhen and endWhen
diff --git a/tests/tests/provider/src/android/provider/cts/Settings_SecureTest.java b/tests/tests/provider/src/android/provider/cts/Settings_SecureTest.java
index 7166211..2a12243 100644
--- a/tests/tests/provider/src/android/provider/cts/Settings_SecureTest.java
+++ b/tests/tests/provider/src/android/provider/cts/Settings_SecureTest.java
@@ -154,6 +154,6 @@
 
     public void testUnknownSourcesOffByDefault() throws SettingNotFoundException {
         assertEquals("Device should not ship with 'Unknown Sources' enabled by default.",
-                0, Secure.getInt(cr, Settings.Secure.INSTALL_NON_MARKET_APPS));
+                0, Settings.Global.getInt(cr, Settings.Global.INSTALL_NON_MARKET_APPS));
     }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java b/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java
index dc87fad..2052e2e 100644
--- a/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java
+++ b/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java
@@ -28,6 +28,11 @@
 public class Settings_SystemTest extends AndroidTestCase {
     private ContentResolver cr;
 
+    private static final String INT_FIELD = "IntField";
+    private static final String LONG_FIELD = "LongField";
+    private static final String FLOAT_FIELD = "FloatField";
+    private static final String STRING_FIELD = "StringField";
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -36,13 +41,32 @@
         assertNotNull(cr);
     }
 
+    private void deleteTestedRows() {
+        String selection = System.NAME + "=\"" + INT_FIELD + "\"";
+        cr.delete(System.CONTENT_URI, selection, null);
+
+        selection = System.NAME + "=\"" + LONG_FIELD + "\"";
+        cr.delete(System.CONTENT_URI, selection, null);
+
+        selection = System.NAME + "=\"" + FLOAT_FIELD + "\"";
+        cr.delete(System.CONTENT_URI, selection, null);
+
+        selection = System.NAME + "=\"" + STRING_FIELD + "\"";
+        cr.delete(System.CONTENT_URI, selection, null);
+
+        selection = System.NAME + "=\"" + System.SHOW_GTALK_SERVICE_STATUS + "\"";
+        cr.delete(System.CONTENT_URI, selection, null);
+    }
+
     public void testSystemSettings() throws SettingNotFoundException {
         /**
-         * first query the exist settings in System table, and then insert six
-         * rows: an int, a long, a float, a String, a configuration and a
-         * ShowGTalkServiceStatus. Get these six rows to check whether insert
-         * success and then delete them.
+         * first query the exist settings in System table, and then insert five
+         * rows: an int, a long, a float, a String, and a ShowGTalkServiceStatus.
+         * Get these six rows to check whether insert succeeded and then delete them.
          */
+        // Precondition: these rows must not exist in the db when we begin
+        deleteTestedRows();
+
         // first query exist rows
         Cursor c = cr.query(System.CONTENT_URI, null, null, null, null);
         try {
@@ -50,17 +74,13 @@
             int origCount = c.getCount();
             c.close();
 
-            String intField = "IntField";
-            String longField = "LongField";
-            String floatField = "FloatField";
-            String stringField = "StringField";
             String stringValue = "cts";
 
             // insert 5 rows, and update 1 rows
-            assertTrue(System.putInt(cr, intField, 10));
-            assertTrue(System.putLong(cr, longField, 20l));
-            assertTrue(System.putFloat(cr, floatField, 30.0f));
-            assertTrue(System.putString(cr, stringField, stringValue));
+            assertTrue(System.putInt(cr, INT_FIELD, 10));
+            assertTrue(System.putLong(cr, LONG_FIELD, 20l));
+            assertTrue(System.putFloat(cr, FLOAT_FIELD, 30.0f));
+            assertTrue(System.putString(cr, STRING_FIELD, stringValue));
             System.setShowGTalkServiceStatus(cr, true);
 
             c = cr.query(System.CONTENT_URI, null, null, null, null);
@@ -69,28 +89,15 @@
             c.close();
 
             // get these rows to assert
-            assertEquals(10, System.getInt(cr, intField));
-            assertEquals(20l, System.getLong(cr, longField));
-            assertEquals(30.0f, System.getFloat(cr, floatField), 0.001);
+            assertEquals(10, System.getInt(cr, INT_FIELD));
+            assertEquals(20l, System.getLong(cr, LONG_FIELD));
+            assertEquals(30.0f, System.getFloat(cr, FLOAT_FIELD), 0.001);
 
-            assertEquals(stringValue, System.getString(cr, stringField));
+            assertEquals(stringValue, System.getString(cr, STRING_FIELD));
             assertTrue(System.getShowGTalkServiceStatus(cr));
 
-            // delete these rows
-            String selection = System.NAME + "=\"" + intField + "\"";
-            cr.delete(System.CONTENT_URI, selection, null);
-
-            selection = System.NAME + "=\"" + longField + "\"";
-            cr.delete(System.CONTENT_URI, selection, null);
-
-            selection = System.NAME + "=\"" + floatField + "\"";
-            cr.delete(System.CONTENT_URI, selection, null);
-
-            selection = System.NAME + "=\"" + stringField + "\"";
-            cr.delete(System.CONTENT_URI, selection, null);
-
-            selection = System.NAME + "=\"" + System.SHOW_GTALK_SERVICE_STATUS + "\"";
-            cr.delete(System.CONTENT_URI, selection, null);
+            // delete the tested rows again
+            deleteTestedRows();
 
             c = cr.query(System.CONTENT_URI, null, null, null, null);
             assertNotNull(c);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java b/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java
new file mode 100644
index 0000000..7caacfc
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 2011-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.renderscript.cts;
+
+import android.renderscript.Allocation;
+
+import android.renderscript.Byte2;
+import android.renderscript.Byte3;
+import android.renderscript.Byte4;
+
+import android.renderscript.Double2;
+import android.renderscript.Double3;
+import android.renderscript.Double4;
+
+import android.renderscript.Element;
+
+import android.renderscript.Float2;
+import android.renderscript.Float3;
+import android.renderscript.Float4;
+
+import android.renderscript.Int2;
+import android.renderscript.Int3;
+import android.renderscript.Int4;
+
+import android.renderscript.Long2;
+import android.renderscript.Long3;
+import android.renderscript.Long4;
+
+import android.renderscript.RSRuntimeException;
+
+import android.renderscript.Short2;
+import android.renderscript.Short3;
+import android.renderscript.Short4;
+
+import android.renderscript.Type;
+
+import com.android.cts.stub.R;
+
+public class KernelTest extends RSBaseCompute {
+    /**
+     * Test support for reflected forEach() as well as validation of parameters.
+     */
+    public void testForEach() {
+        int x = 7;
+
+        // badOut is always I8, so it is always an invalid type
+        Type t = new Type.Builder(mRS, Element.I8(mRS)).setX(x).create();
+        Allocation badOut = Allocation.createTyped(mRS, t);
+
+        ScriptC_kernel_all kernel_all = new ScriptC_kernel_all(mRS);
+
+        // I8
+        Allocation in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U8(mRS)).setX(x).create();
+        Allocation out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i8(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i8(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I8_2
+        t = new Type.Builder(mRS, Element.I8_2(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U8_2(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i8_2(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i8_2(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I8_3
+        t = new Type.Builder(mRS, Element.I8_3(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U8_3(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i8_3(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i8_3(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I8_4
+        t = new Type.Builder(mRS, Element.I8_4(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U8_4(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i8_4(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i8_4(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I16
+        t = new Type.Builder(mRS, Element.I16(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U16(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i16(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i16(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I16_2
+        t = new Type.Builder(mRS, Element.I16_2(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U16_2(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i16_2(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i16_2(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I16_3
+        t = new Type.Builder(mRS, Element.I16_3(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U16_3(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i16_3(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i16_3(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I16_4
+        t = new Type.Builder(mRS, Element.I16_4(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U16_4(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i16_4(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i16_4(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I32
+        t = new Type.Builder(mRS, Element.I32(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U32(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i32(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i32(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I32_2
+        t = new Type.Builder(mRS, Element.I32_2(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U32_2(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i32_2(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i32_2(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I32_3
+        t = new Type.Builder(mRS, Element.I32_3(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U32_3(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i32_3(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i32_3(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I32_4
+        t = new Type.Builder(mRS, Element.I32_4(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U32_4(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i32_4(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i32_4(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I64
+        t = new Type.Builder(mRS, Element.I64(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U64(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i64(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i64(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I64_2
+        t = new Type.Builder(mRS, Element.I64_2(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U64_2(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i64_2(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i64_2(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I64_3
+        t = new Type.Builder(mRS, Element.I64_3(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U64_3(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i64_3(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i64_3(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // I64_4
+        t = new Type.Builder(mRS, Element.I64_4(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.U64_4(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i64_4(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i64_4(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // F32
+        t = new Type.Builder(mRS, Element.F32(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_f32(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_f32(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // F32_2
+        t = new Type.Builder(mRS, Element.F32_2(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.F32_2(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_f32_2(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_f32_2(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // F32_3
+        t = new Type.Builder(mRS, Element.F32_3(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_f32_3(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_f32_3(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // F32_4
+        t = new Type.Builder(mRS, Element.F32_4(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_f32_4(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_f32_4(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // F64
+        t = new Type.Builder(mRS, Element.F64(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_f64(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_f64(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // F64_2
+        t = new Type.Builder(mRS, Element.F64_2(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_f64_2(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_f64_2(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // F64_3
+        t = new Type.Builder(mRS, Element.F64_3(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_f64_3(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_f64_3(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // F64_4
+        t = new Type.Builder(mRS, Element.F64_4(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_f64_4(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_f64_4(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // kernel_test (struct)
+        in = new ScriptField_kernel_test(mRS, x).getAllocation();
+        out = new ScriptField_kernel_test(mRS, x).getAllocation();
+        kernel_all.forEach_test_struct(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_struct(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // BOOLEAN
+        t = new Type.Builder(mRS, Element.BOOLEAN(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_bool(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_bool(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // A_8
+        t = new Type.Builder(mRS, Element.I8(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.A_8(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i8(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i8(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // RGBA_8888
+        t = new Type.Builder(mRS, Element.I8_4(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.RGBA_8888(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i8_4(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i8_4(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+
+        // RGB_888
+        t = new Type.Builder(mRS, Element.I8_3(mRS)).setX(x).create();
+        in = Allocation.createTyped(mRS, t);
+        t = new Type.Builder(mRS, Element.RGB_888(mRS)).setX(x).create();
+        out = Allocation.createTyped(mRS, t);
+        kernel_all.forEach_test_i8_3(in, out);
+        mRS.finish();
+        try {
+            kernel_all.forEach_test_i8_3(in, badOut);
+            mRS.finish();
+            fail("should throw RSRuntimeException");
+        } catch (RSRuntimeException e) {
+        }
+    }
+
+
+    public void testMultipleForEach() {
+        ScriptC_foreach s = new ScriptC_foreach(mRS, mRes, R.raw.foreach);
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+
+        int X = 5;
+        int Y = 7;
+        s.set_dimX(X);
+        s.set_dimY(Y);
+        typeBuilder.setX(X).setY(Y);
+        Allocation A = Allocation.createTyped(mRS, typeBuilder.create());
+        s.bind_a(A);
+        s.forEach_root(A);
+        s.invoke_verify_root();
+        s.forEach_foo(A, A);
+        s.invoke_verify_foo();
+        s.invoke_foreach_test();
+        mRS.finish();
+        waitForMessage();
+    }
+
+    public void testNoRoot() {
+        ScriptC_noroot s = new ScriptC_noroot(mRS, mRes, R.raw.noroot);
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+
+        int X = 5;
+        int Y = 7;
+        s.set_dimX(X);
+        s.set_dimY(Y);
+        typeBuilder.setX(X).setY(Y);
+        Allocation A = Allocation.createTyped(mRS, typeBuilder.create());
+        s.bind_a(A);
+        s.forEach_foo(A, A);
+        s.invoke_verify_foo();
+        s.invoke_noroot_test();
+        mRS.finish();
+        checkForErrors();
+        waitForMessage();
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/VoldExploitTest.java b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
index d428c60..d7f97ee 100644
--- a/tests/tests/security/src/android/security/cts/VoldExploitTest.java
+++ b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
@@ -42,12 +42,8 @@
     public void testTryCommandInjection() throws Exception {
         final StorageManager sm = (StorageManager) getContext().getSystemService(
                 Context.STORAGE_SERVICE);
-        try {
-            sm.getMountedObbPath("/dev/null\0asec list");
-            fail("able to inject vold commands");
-        } catch(IllegalArgumentException e) {
-            // expected
-        }
+        String path = sm.getMountedObbPath("/dev/null\0asec list");
+        assertNull(path);
     }
 
     /**
diff --git a/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java b/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java
index aa8874c..3aa8f35 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... (but still shouldn't break alphabetic chars)
+            //              01234567
+            layout(replace("L XXX#X", '#', c), new int[] {2});
+            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/cts/TextUtilsTest.java b/tests/tests/text/src/android/text/cts/TextUtilsTest.java
index 5ae1ef5..157f146 100755
--- a/tests/tests/text/src/android/text/cts/TextUtilsTest.java
+++ b/tests/tests/text/src/android/text/cts/TextUtilsTest.java
@@ -27,24 +27,28 @@
 import android.os.Parcelable;
 import android.test.AndroidTestCase;
 import android.text.GetChars;
-import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.SpannedString;
 import android.text.TextPaint;
 import android.text.TextUtils;
-import android.text.TextUtils.EllipsizeCallback;
 import android.text.TextUtils.TruncateAt;
 import android.text.style.BackgroundColorSpan;
 import android.text.style.ReplacementSpan;
 import android.text.style.TextAppearanceSpan;
 import android.text.style.URLSpan;
 import android.util.StringBuilderPrinter;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
 
 import java.util.ArrayList;
+import java.util.Locale;
 import java.util.regex.Pattern;
 
+import static android.view.View.LAYOUT_DIRECTION_LTR;
+import static android.view.View.LAYOUT_DIRECTION_RTL;
+
 /**
  * Test {@link TextUtils}.
  */
@@ -2026,4 +2030,174 @@
         TextUtils.dumpSpans(spanned, printer, prefix);
         assertTrue(builder.length() > 0);
     }
-}
+
+    @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "getLayoutDirectionFromLocale",
+            args = {Locale.class}
+    )
+    public void testGetLayoutDirectionFromLocale() {
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(null));
+
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.ENGLISH));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.CANADA));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.FRANCE));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.FRENCH));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.GERMAN));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.GERMANY));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.ITALIAN));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.ITALY));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.UK));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.US));
+
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.ROOT));
+
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.CHINA));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.CHINESE));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.JAPAN));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.JAPANESE));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.KOREA));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.KOREAN));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.PRC));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.TAIWAN));
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE));
+
+        Locale locale = new Locale("ar");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "AE");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "BH");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "DZ");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "EG");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "IQ");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "JO");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "KW");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "LB");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "LY");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "MA");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "OM");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "QA");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "SA");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "SD");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "SY");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "TN");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ar", "YE");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("fa");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("fa", "AF");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("fa", "IR");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("iw");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("iw", "IL");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("he");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("he", "IL");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("pa_Arab");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("pa_Arab", "PK");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("ps");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ps", "AF");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("ur");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ur", "IN");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("ur", "PK");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+
+        locale = new Locale("uz_Arab");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+        locale = new Locale("uz_Arab", "AF");
+        assertEquals(LAYOUT_DIRECTION_RTL,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+
+        // Locale without a real language
+        locale = new Locale("zz");
+        assertEquals(LAYOUT_DIRECTION_LTR,
+                TextUtils.getLayoutDirectionFromLocale(locale));
+    }}
diff --git a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
index 1907ac7..25e6306 100644
--- a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
+++ b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
@@ -52,9 +52,9 @@
                 DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_LONG));
         assertEquals("Sun",
                 DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_MEDIUM));
-        assertEquals("Su",
+        assertEquals("Sun",
                 DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_SHORT));
-        assertEquals("Su",
+        assertEquals("Sun",
                 DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_SHORTER));
         assertEquals("S",
                 DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_SHORTEST));
@@ -83,8 +83,8 @@
         if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) {
             return;
         }
-        assertEquals("am", DateUtils.getAMPMString(Calendar.AM));
-        assertEquals("pm", DateUtils.getAMPMString(Calendar.PM));
+        assertEquals("AM", DateUtils.getAMPMString(Calendar.AM));
+        assertEquals("PM", DateUtils.getAMPMString(Calendar.PM));
     }
 
 
@@ -169,7 +169,7 @@
                 + HOUR_DURATION, DateUtils.FORMAT_SHOW_WEEKDAY));
         assertEquals("January 19", DateUtils.formatDateRange(mContext, timeWithCurrentYear,
                 timeWithCurrentYear + HOUR_DURATION, DateUtils.FORMAT_SHOW_DATE));
-        assertEquals("3:30am", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
+        assertEquals("3:30AM", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
                 DateUtils.FORMAT_SHOW_TIME));
         assertEquals("January 19, 2009", DateUtils.formatDateRange(mContext, fixedTime,
                 fixedTime + HOUR_DURATION, DateUtils.FORMAT_SHOW_YEAR));
@@ -177,7 +177,7 @@
                 timeWithCurrentYear + HOUR_DURATION, DateUtils.FORMAT_NO_YEAR));
         assertEquals("January", DateUtils.formatDateRange(mContext, timeWithCurrentYear,
                 timeWithCurrentYear + HOUR_DURATION, DateUtils.FORMAT_NO_MONTH_DAY));
-        assertEquals("3:30am", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
+        assertEquals("3:30AM", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
                 DateUtils.FORMAT_12HOUR | DateUtils.FORMAT_SHOW_TIME));
         assertEquals("03:30", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
                 DateUtils.FORMAT_24HOUR | DateUtils.FORMAT_SHOW_TIME));
@@ -188,14 +188,14 @@
         assertEquals("Noon", DateUtils.formatDateRange(mContext, fixedTime + noonDuration,
                 fixedTime + noonDuration,
                 DateUtils.FORMAT_12HOUR | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_CAP_NOON));
-        assertEquals("12:00pm", DateUtils.formatDateRange(mContext, fixedTime + noonDuration,
+        assertEquals("12:00PM", DateUtils.formatDateRange(mContext, fixedTime + noonDuration,
                 fixedTime + noonDuration,
                 DateUtils.FORMAT_12HOUR | DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_SHOW_TIME));
-        assertEquals("12:00am", DateUtils.formatDateRange(mContext, fixedTime - midnightDuration,
+        assertEquals("12:00AM", DateUtils.formatDateRange(mContext, fixedTime - midnightDuration,
                 fixedTime - midnightDuration,
                 DateUtils.FORMAT_12HOUR | DateUtils.FORMAT_SHOW_TIME
                 | DateUtils.FORMAT_NO_MIDNIGHT));
-        assertEquals("3:30am", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
+        assertEquals("3:30AM", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
                 DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_UTC));
         assertEquals("3am", DateUtils.formatDateRange(mContext, fixedTime - integralDuration,
                 fixedTime - integralDuration,
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/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..397735f 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
@@ -81,7 +81,92 @@
         assertEquals(120, mMarginLayoutParams.rightMargin);
         assertEquals(140, mMarginLayoutParams.bottomMargin);
 
-        assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.startMargin);
-        assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.endMargin);
+        assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.getMarginStart());
+        assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.getMarginEnd());
+
+        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.getMarginStart());
+        assertEquals(30, mMarginLayoutParams.topMargin);
+        assertEquals(120, mMarginLayoutParams.getMarginEnd());
+        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.getMarginStart());
+        assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.getMarginEnd());
+
+        assertEquals(false, mMarginLayoutParams.isMarginRelative());
+
+        // LTR / relative margin case
+        mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+        vg.setLayoutParams(mMarginLayoutParams);
+        vg.requestLayout();
+
+        assertEquals(20, mMarginLayoutParams.getMarginStart());
+        assertEquals(30, mMarginLayoutParams.topMargin);
+        assertEquals(120, mMarginLayoutParams.getMarginEnd());
+        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.getMarginStart());
+        assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.getMarginEnd());
+
+        assertEquals(false, mMarginLayoutParams.isMarginRelative());
+
+        // RTL / relative margin case
+        mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+        vg.setLayoutParams(mMarginLayoutParams);
+        vg.requestLayout();
+
+        assertEquals(20, mMarginLayoutParams.getMarginStart());
+        assertEquals(30, mMarginLayoutParams.topMargin);
+        assertEquals(120, mMarginLayoutParams.getMarginEnd());
+        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..9ec0626 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -61,7 +61,7 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.view.WindowManagerImpl;
+import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
@@ -2730,7 +2730,8 @@
         Rect outRect = new Rect();
         View view = new View(mActivity);
         // mAttachInfo is null
-        Display d = WindowManagerImpl.getDefault().getDefaultDisplay();
+        WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
+        Display d = wm.getDefaultDisplay();
         view.getWindowVisibleDisplayFrame(outRect);
         assertEquals(0, outRect.left);
         assertEquals(0, outRect.top);
@@ -3131,28 +3132,6 @@
         });
     }
 
-    @UiThreadTest
-    public void testLayoutDirection() {
-        View view = new View(mActivity);
-        assertEquals(View.LAYOUT_DIRECTION_INHERIT, view.getLayoutDirection());
-
-        view.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
-        assertEquals(View.LAYOUT_DIRECTION_LTR, view.getLayoutDirection());
-
-        view.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
-        assertEquals(View.LAYOUT_DIRECTION_RTL, view.getLayoutDirection());
-
-        view.setLayoutDirection(View.LAYOUT_DIRECTION_INHERIT);
-        assertEquals(View.LAYOUT_DIRECTION_INHERIT, view.getLayoutDirection());
-
-        view.setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
-        assertEquals(View.LAYOUT_DIRECTION_LOCALE, view.getLayoutDirection());
-
-        // View.LAYOUT_DIRECTION_MASK = 0x00000003
-        view.setLayoutDirection(0xffffffff);
-        assertEquals(0x00000003, view.getLayoutDirection());
-    }
-
     private static class MockEditText extends EditText {
         private boolean mCalledCheckInputConnectionProxy = false;
         private boolean mCalledOnCreateInputConnection = false;
@@ -3388,11 +3367,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/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 1bc8a4f..054217e 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -235,9 +235,6 @@
         Thread.sleep(100); // Wait for open to be received on the icon db thread.
         assertEquals(WebSettings.LOAD_DEFAULT, mSettings.getCacheMode());
 
-        mSettings.setCacheMode(WebSettings.LOAD_NORMAL);
-        assertEquals(WebSettings.LOAD_NORMAL, mSettings.getCacheMode());
-
         mSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
         assertEquals(WebSettings.LOAD_CACHE_ELSE_NETWORK, mSettings.getCacheMode());
         final IconListenerClient iconListener = new IconListenerClient();
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 3f7ea78..6c66f52 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -45,6 +45,7 @@
 import android.webkit.CacheManager.CacheResult;
 import android.webkit.ConsoleMessage;
 import android.webkit.DownloadListener;
+import android.webkit.JavascriptInterface;
 import android.webkit.SslErrorHandler;
 import android.webkit.WebBackForwardList;
 import android.webkit.WebChromeClient;
@@ -411,6 +412,7 @@
                 return mWasProvideResultCalled;
             }
 
+            @JavascriptInterface
             public synchronized void provideResult(String result) {
                 mWasProvideResultCalled = true;
                 mResult = result;
@@ -483,9 +485,12 @@
     public void testUseRemovedJavascriptInterface() throws Throwable {
         class RemovedObject {
             @Override
+            @JavascriptInterface
             public String toString() {
                 return "removedObject";
             }
+
+            @JavascriptInterface
             public void remove() throws Throwable {
                 mOnUiThread.removeJavascriptInterface("removedObject");
                 System.gc();
@@ -494,6 +499,8 @@
         class ResultObject {
             private String mResult;
             private boolean mIsResultAvailable;
+
+            @JavascriptInterface
             public synchronized void setResult(String result) {
                 mResult = result;
                 mIsResultAvailable = true;
@@ -1170,6 +1177,7 @@
         final class ImageLoaded {
             public boolean mImageLoaded;
 
+            @JavascriptInterface
             public void loaded() {
                 mImageLoaded = true;
             }
@@ -1769,6 +1777,8 @@
     public void testPauseResumeTimers() throws Throwable {
         class Monitor {
             private boolean mIsUpdated;
+
+            @JavascriptInterface
             public synchronized void update() {
                 mIsUpdated  = true;
                 notify();
diff --git a/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java b/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
index 760a160..f7cf4d3 100755
--- a/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
@@ -515,7 +515,6 @@
         // re-set 'clicked' flag to false
         listener.clearItemClickedStatus();
 
-
         runTestOnUiThread(new Runnable() {
             public void run() {
                 mAutoCompleteTextView.showDropDown();
@@ -534,7 +533,6 @@
                 mAutoCompleteTextView.showDropDown();
             }
         });
-        mInstrumentation.waitForIdleSync();
         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
         // Test normal key code.
         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
@@ -550,7 +548,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..5c8be24
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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_LTR, vg.getLayoutDirection());
+    }
+
+    @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());
+
+        vg.setLayoutDirection(LAYOUT_DIRECTION_RTL);
+        assertEquals(LAYOUT_DIRECTION_RTL, vg.getLayoutDirection());
+
+        vg.setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
+        // running with English locale
+        assertEquals(LAYOUT_DIRECTION_LTR, vg.getLayoutDirection());
+
+        vg.setLayoutDirection(LAYOUT_DIRECTION_INHERIT);
+        // default is LTR
+        assertEquals(LAYOUT_DIRECTION_LTR, vg.getLayoutDirection());
+    }
+
+    @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, child.getLayoutDirection());
+
+        // Parent is RTL
+        parent.setLayoutDirection(LAYOUT_DIRECTION_RTL);
+
+        assertEquals(LAYOUT_DIRECTION_RTL, parent.getLayoutDirection());
+        assertEquals(LAYOUT_DIRECTION_RTL, child.getLayoutDirection());
+    }
+
+    @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(parentResDir, ll.getLayoutDirection());
+
+        ViewGroup child1 = (ViewGroup) getActivity().findViewById(child1Id);
+        assertEquals(child1ResDir, child1.getLayoutDirection());
+
+        ViewGroup child2 = (ViewGroup) getActivity().findViewById(child2Id);
+        assertEquals(child2ResDir, child2.getLayoutDirection());
+
+        ViewGroup child3 = (ViewGroup) getActivity().findViewById(child3Id);
+        assertEquals(child3ResDir, child3.getLayoutDirection());
+
+        ViewGroup child4 = (ViewGroup) getActivity().findViewById(child4Id);
+        assertEquals(child4ResDir, child4.getLayoutDirection());
+    }
+
+    @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/RadioGroupTest.java b/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java
index a7593c4..f7baab7 100644
--- a/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java
@@ -102,9 +102,9 @@
         assertEquals(View.NO_ID, newButton.getId());
         mDefaultRadioGroup.addView(newButton, new RadioGroup.LayoutParams(
                 RadioGroup.LayoutParams.WRAP_CONTENT, RadioGroup.LayoutParams.WRAP_CONTENT));
-        // set the id with hashCode
-        // (PassThroughHierarchyChangeListener's behaviour when button is added)
-        assertEquals(newButton.hashCode(), newButton.getId());
+        // aapt-generated IDs have a nonzero high byte; check that the ID generated by
+        // RadioGroup falls within a range that will not collide with aapt IDs.
+        assertEquals(0, newButton.getId() & 0xFF000000);
     }
 
     public void testInternalCheckedStateTracker() {
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..b4279f2 100755
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -2984,6 +2984,301 @@
                 outText.text.toString());
     }
 
+    @UiThreadTest
+    public void testTextDirectionDefault() {
+        TextView tv = new TextView(mActivity);
+        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getRawTextDirection());
+    }
+
+    @UiThreadTest
+    public void testSetGetTextDirection() {
+        TextView tv = new TextView(mActivity);
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getRawTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+        assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getRawTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+        assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getRawTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+        assertEquals(View.TEXT_DIRECTION_LTR, tv.getRawTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+        assertEquals(View.TEXT_DIRECTION_RTL, tv.getRawTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+        assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getRawTextDirection());
+    }
+
+    @UiThreadTest
+    public void testGetResolvedTextDirectionLtr() {
+        TextView tv = new TextView(mActivity);
+        tv.setText("this is a test");
+
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
+
+        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_FIRST_STRONG, 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 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.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_ANY_RTL, 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 testGetResolvedTextDirectionRtl() {
+        TextView tv = new TextView(mActivity);
+        tv.setText("\u05DD\u05DE"); // hebrew
+
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
+
+        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_FIRST_STRONG, 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 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.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_FIRST_STRONG, 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());
+
+        // 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.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_RTL, 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 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.getTextDirection());
+
+        ll.removeView(tv);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
+    }
+
+    @UiThreadTest
+    public void testTextAlignmentDefault() {
+        TextView tv = new TextView(getActivity());
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
+        // resolved default text alignment is GRAVITY
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
+    }
+
+    @UiThreadTest
+    public void testSetGetTextAlignment() {
+        TextView tv = new TextView(getActivity());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getRawTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getRawTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getRawTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getRawTextAlignment());
+
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getRawTextAlignment());
+    }
+
+    @UiThreadTest
+    public void testGetResolvedTextAlignment() {
+        TextView tv = new TextView(getActivity());
+
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
+
+        // Test center alignment first so that we dont hit the default case
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
+
+        // Test the default case too
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, 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 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.getRawTextAlignment());
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
+
+        // set inherit and check that child is following parent
+        tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
+        assertEquals(View.TEXT_ALIGNMENT_INHERIT, tv.getRawTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+        assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+        assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+        assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+        assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment());
+
+        // 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.getTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
+
+        ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+        assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
+    }
+
+    @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.getTextAlignment());
+
+        ll.removeView(tv);
+        // default text alignment is GRAVITY
+        assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
+    }
+
     private static class MockOnEditorActionListener implements OnEditorActionListener {
         private boolean isOnEditorActionCalled;
 
diff --git a/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java b/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java
index 808473a..4086093 100644
--- a/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java
+++ b/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java
@@ -49,6 +49,7 @@
 import com.sun.javadoc.MethodDoc;
 import com.sun.javadoc.RootDoc;
 import com.sun.javadoc.AnnotationDesc.ElementValuePair;
+import com.sun.javadoc.AnnotationTypeElementDoc;
 
 /**
  * Doclet that outputs in the following format:
@@ -56,7 +57,7 @@
  * suite:android.holo.cts
  * case:HoloTest
  * test:testHolo
- * test:testHoloDialog
+ * test:testHoloDialog[:timeout_value]
  */
 public class CtsJavaScannerDoclet extends Doclet {
 
@@ -81,7 +82,27 @@
                     if (!method.name().startsWith("test")) {
                         continue;
                     }
-                    writer.append("test:").println(method.name());
+                    int timeout = -1;
+                    AnnotationDesc[] annotations = method.annotations();
+                    for (AnnotationDesc annot : annotations) {
+                        AnnotationTypeDoc atype = annot.annotationType();
+                        if (atype.toString().equals("android.cts.util.TimeoutReq")) {
+                            ElementValuePair[] cpairs = annot.elementValues();
+                            for (ElementValuePair pair: cpairs) {
+                                AnnotationTypeElementDoc elem = pair.element();
+                                AnnotationValue value = pair.value();
+                                if (elem.name().equals("minutes")) {
+                                    timeout = ((Integer)value.value());
+                                }
+                            }
+                        }
+                    }
+                    writer.append("test:");
+                    if (timeout >= 0) {
+                        writer.append(method.name()).println(":" + timeout);
+                    } else {
+                        writer.println(method.name());
+                    }
                 }
             }
         }
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..ba87156 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,10 +65,13 @@
         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");
+        // PTS adds PtsAndroidTestCase
+        sourcePath.add("./cts/suite/pts/deviceTests/ptsutil/src");
+        sourcePath.add("./cts/libs/util/src");
         sourcePath.add(sourceDir.toString());
         return join(sourcePath, ":");
     }
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/Test.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/Test.java
new file mode 100644
index 0000000..a9dd5e0
--- /dev/null
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/Test.java
@@ -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.
+ */
+
+package com.android.cts.xmlgenerator;
+
+public class Test {
+    private String mName;
+    private int mTimeout;
+
+    public Test(String name, int timeout) {
+        mName = name;
+        mTimeout = timeout;
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public int getTimeout() {
+        return mTimeout;
+    }
+}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java
index bab3476..a9ea6e1 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java
@@ -24,7 +24,7 @@
 
     private final String mName;
 
-    private final List<String> mTests = new ArrayList<String>();
+    private final List<Test> mTests = new ArrayList<Test>();
 
     public TestCase(String name) {
         mName = name;
@@ -34,11 +34,11 @@
         return mName;
     }
 
-    public void addTest(String test) {
-        mTests.add(test);
+    public void addTest(String testName, int timeout) {
+        mTests.add(new Test(testName, timeout));
     }
 
-    public Collection<String> getTests() {
+    public Collection<Test> getTests() {
         return Collections.unmodifiableCollection(mTests);
     }
 }
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestListParser.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestListParser.java
index 76e1437..c77d1a0 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestListParser.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestListParser.java
@@ -27,7 +27,7 @@
  * suite:android.holo.cts
  * case:HoloTest
  * test:testHolo
- * test:testHoloDialog
+ * test:testHoloDialog[:timeout_value]
  */
 class TestListParser {
 
@@ -41,7 +41,7 @@
             while(scanner.hasNextLine()) {
                 String line = scanner.nextLine();
                 String[] tokens = line.split(":");
-                if (tokens.length != 2) {
+                if (tokens.length < 2) {
                     continue;
                 }
 
@@ -52,7 +52,11 @@
                 } else if ("case".equals(key)) {
                     currentCase = handleCase(currentSuite, value);
                 } else if ("test".equals(key)) {
-                    handleTest(currentCase, value);
+                    int timeout = -1;
+                    if (tokens.length == 3) {
+                        timeout = Integer.parseInt(tokens[2]);
+                    }
+                    handleTest(currentCase, value, timeout);
                 }
             }
         } finally {
@@ -95,7 +99,7 @@
         return testCase;
     }
 
-    private void handleTest(TestCase testCase, String test) {
-        testCase.addTest(test);
+    private void handleTest(TestCase testCase, String test, int timeout) {
+        testCase.addTest(test, timeout);
     }
 }
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
index fda3acc..8a49cf3 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
@@ -174,17 +174,20 @@
         }
     }
 
-    private void writeTests(PrintWriter writer, Collection<String> tests,
+    private void writeTests(PrintWriter writer, Collection<Test> tests,
             StringBuilder nameCollector) {
-        for (String test : tests) {
-            nameCollector.append('#').append(test);
-            writer.append("<Test name=\"").append(test).append("\"");
+        for (Test test : tests) {
+            nameCollector.append('#').append(test.getName());
+            writer.append("<Test name=\"").append(test.getName()).append("\"");
             if (isKnownFailure(mExpectations, nameCollector.toString())) {
                 writer.append(" expectation=\"failure\"");
             }
+            if (test.getTimeout() >= 0) {
+                writer.append(" timeout=\"" + test.getTimeout() + "\"");
+            }
             writer.println(" />");
 
-            nameCollector.delete(nameCollector.length() - test.length() - 1,
+            nameCollector.delete(nameCollector.length() - test.getName().length() - 1,
                     nameCollector.length());
         }
     }
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/res/report/cts_result.xsl b/tools/tradefed-host/res/report/cts_result.xsl
index fd2b732..b924d2f 100644
--- a/tools/tradefed-host/res/report/cts_result.xsl
+++ b/tools/tradefed-host/res/report/cts_result.xsl
@@ -461,7 +461,7 @@
                         <TR>
                             <TH width="30%">Test</TH>
                             <TH width="5%">Result</TH>
-                            <TH>Failure Details</TH>
+                            <TH>Details</TH>
                         </TR>
 
                         <!-- test case -->
@@ -526,6 +526,11 @@
                                                             <xsl:value-of select="@result"/>
                                                         </div>
                                                     </TD>
+                                                    <TD class="failuredetails">
+                                                        <div class="details">
+                                                            <xsl:value-of select="FailedScene/@message"/>
+                                                        </div>
+                                                    </TD>
                                                     <TD class="failuredetails"></TD>
                                                 </xsl:if>
 
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
index 8029b75..3c46d9b 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
@@ -30,11 +30,17 @@
 public class CtsBuildHelper {
 
     static final String CTS_DIR_NAME = "android-cts";
+    static final String PTS_DIR_NAME = "android-pts";
+    static private boolean mCtsMode = true;
     /** The root location of the extracted CTS package */
     private final File mRootDir;
     /** the {@link CTS_DIR_NAME} directory */
     private final File mCtsDir;
 
+    public static void changeToPtsMode() {
+        mCtsMode = false;
+    }
+
     /**
      * Creates a {@link CtsBuildHelper}.
      *
@@ -43,7 +49,7 @@
      */
     public CtsBuildHelper(File rootDir) {
         mRootDir = rootDir;
-        mCtsDir = new File(mRootDir, CTS_DIR_NAME);
+        mCtsDir = new File(mRootDir, mCtsMode ? CTS_DIR_NAME : PTS_DIR_NAME);
     }
 
     /**
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/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
index a815a48..8e59cc5 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
@@ -246,6 +246,11 @@
     }
 
     public static void main(String[] args) throws InterruptedException {
+        // change to PTS mode before anything else
+        String ptsMode = System.getProperty("PTS");
+        if ((ptsMode != null) && ptsMode.equals("1")) {
+            CtsBuildHelper.changeToPtsMode();
+        }
         Console console = new CtsConsole();
         Console.startConsole(console, args);
     }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
index 686c90a..c140b6f 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
@@ -44,6 +44,8 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Writes results to an XML files in the CTS format.
@@ -96,6 +98,9 @@
 
     private File mLogDir;
 
+    private static final String PTS_PERFORMANCE_EXCEPTION = "com.android.pts.util.PtsException";
+    private static final Pattern mPtsLogPattern = Pattern.compile(
+            "com\\.android\\.pts\\.util\\.PtsException:\\s(.*)\\+\\+\\+\\+(.*)");
     public void setReportDir(File reportDir) {
         mReportDir = reportDir;
     }
@@ -216,7 +221,21 @@
      */
     @Override
     public void testFailed(TestFailure status, TestIdentifier test, String trace) {
-        mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
+        if (trace.startsWith(PTS_PERFORMANCE_EXCEPTION)) { //PTS result
+            Test tst = mCurrentPkgResult.findTest(test);
+            // this exception is always thrown as exception is thrown from tearDown.
+            // Just ignore it.
+            if (tst.getName().endsWith("testAndroidTestCaseSetupProperly")) {
+                return;
+            }
+            Matcher m = mPtsLogPattern.matcher(trace);
+            if (m.find()) {
+                mCurrentPkgResult.reportPerformanceResult(test, CtsTestStatus.PASS, m.group(1),
+                        m.group(2));
+            }
+        } else {
+            mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
+        }
     }
 
     /**
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java
index 3c78df7..dd4f31f 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java
@@ -36,6 +36,7 @@
     private static final String RESULT_ATTR = "result";
     private static final String SCENE_TAG = "FailedScene";
     private static final String STACK_TAG = "StackTrace";
+    private static final String DETAILS_TAG = "Details";
 
     private String mName;
     private CtsTestStatus mResult;
@@ -43,6 +44,8 @@
     private String mEndTime;
     private String mMessage;
     private String mStackTrace;
+    // details passed from pts
+    private String mDetails;
 
     /**
      * Create an empty {@link Test}
@@ -84,6 +87,10 @@
         return mMessage;
     }
 
+    public void setMessage(String message) {
+        mMessage = message;
+    }
+
     public String getStartTime() {
         return mStartTime;
     }
@@ -102,6 +109,14 @@
         mMessage = getFailureMessageFromStackTrace(mStackTrace);
     }
 
+    public String getDetails() {
+        return mDetails;
+    }
+
+    public void setDetails(String details) {
+        mDetails = details;
+    }
+
     public void updateEndTime() {
         mEndTime = TimeUtil.getTimestamp();
     }
@@ -132,6 +147,11 @@
                 serializer.text(mStackTrace);
                 serializer.endTag(CtsXmlResultReporter.ns, STACK_TAG);
             }
+            if (mDetails != null) {
+                serializer.startTag(CtsXmlResultReporter.ns, DETAILS_TAG);
+                serializer.text(mDetails);
+                serializer.endTag(CtsXmlResultReporter.ns, DETAILS_TAG);
+            }
             serializer.endTag(CtsXmlResultReporter.ns, SCENE_TAG);
         }
         serializer.endTag(CtsXmlResultReporter.ns, TAG);
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java
index 23590e7..ce1c2f3 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java
@@ -275,6 +275,19 @@
     }
 
     /**
+     * report performance result
+     * @param test
+     * @param status
+     * @param perf
+     */
+    public void reportPerformanceResult(TestIdentifier test, CtsTestStatus status, String summary, String details) {
+        Test result = findTest(test);
+        result.setResultStatus(status);
+        result.setMessage(summary);
+        result.setDetails(details);
+    }
+
+    /**
      * Report that the given test has completed.
      *
      * @param test
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index 3b345a7..06f940a 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -75,6 +75,10 @@
     private TestFilter mExcludedTestFilter = new TestFilter();
     private String mTargetBinaryName;
     private String mTargetNameSpace;
+    // only timeout per package is supported. To change this to method granularity,
+    // test invocation should be done in method level.
+    // So for now, only max timeout for the package is used.
+    private int mTimeoutInMins = -1;
 
     void setUri(String uri) {
         mUri = uri;
@@ -238,6 +242,12 @@
         } else {
             CLog.d("Creating instrumentation test for %s", mName);
             InstrumentationApkTest instrTest = new InstrumentationApkTest();
+            if (mTimeoutInMins >= 0) {
+                // as timeout cannot be set for each test,
+                // increase the time-out of the whole package
+                CLog.d("Setting new timeout to " + mTimeoutInMins + " mins");
+                instrTest.setTestTimeout(mTimeoutInMins * 60 * 1000);
+            }
             return setInstrumentationTest(instrTest, testCaseDir);
         }
     }
@@ -300,10 +310,15 @@
      * Add a {@link TestIdentifier} to the list of tests in this package.
      *
      * @param testDef
+     * @param timeout in mins
      */
-    void addTest(TestIdentifier testDef) {
+    void addTest(TestIdentifier testDef, int timeout) {
         mTests.add(testDef);
         mTestClasses.add(testDef.getClassName());
+        // 0 means no timeout, so keep 0 if already is.
+        if ((timeout > mTimeoutInMins) && (mTimeoutInMins != 0)) {
+            mTimeoutInMins = timeout;
+        }
     }
 
     /**
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
index 35bdfd2..675c986 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
@@ -124,12 +124,16 @@
                             classNameBuilder.append(".");
                         }
                     }
-
+                    int timeout = -1;
+                    String timeoutStr = attributes.getValue("timeout");
+                    if (timeoutStr != null) {
+                        timeout = Integer.parseInt(timeoutStr);
+                    }
                     TestIdentifier testId = new TestIdentifier(classNameBuilder.toString(),
                             methodName);
                     boolean isKnownFailure = "failure".equals(attributes.getValue("expectation"));
                     if (!isKnownFailure || mIncludeKnownFailures) {
-                        mPackageDef.addTest(testId);
+                        mPackageDef.addTest(testId, timeout);
                     }
                 }
             }
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 60c9084..8e23f13 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -54,20 +54,24 @@
 
   def __init__(self, argv):
     """Initialize the CtsBuilder from command line arguments."""
-    if not len(argv) == 6:
-      print 'Usage: %s <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath>' % argv[0]
+    if not (len(argv) == 6 or len(argv)==7):
+      print 'Usage: %s <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath> [-pts]' % argv[0]
       print ''
       print 'testRoot:       Directory under which to search for CTS tests.'
       print 'ctsOutputDir:   Directory in which the CTS repository should be created.'
       print 'tempDir:        Directory to use for storing temporary files.'
       print 'androidRootDir: Root directory of the Android source tree.'
       print 'docletPath:     Class path where the DescriptionGenerator doclet can be found.'
+      print '-pts:           generate plan for PTS.'
       sys.exit(1)
     self.test_root = sys.argv[1]
     self.out_dir = sys.argv[2]
     self.temp_dir = sys.argv[3]
     self.android_root = sys.argv[4]
     self.doclet_path = sys.argv[5]
+    self.isCts = True
+    if len(argv) ==7 and sys.argv[6] == "-pts":
+      self.isCts = False
 
     self.test_repository = os.path.join(self.out_dir, 'repository/testcases')
     self.plan_repository = os.path.join(self.out_dir, 'repository/plans')
@@ -99,6 +103,13 @@
       doc = tools.XmlFile(description)
       packages.append(doc.GetAttr('TestPackage', 'appPackageName'))
 
+    if not self.isCts: # PTS
+      plan = tools.TestPlan(packages)
+      plan.Include('.*')
+      plan.Exclude(r'android\.tests\.sigtest')
+      self.__WritePlan(plan, 'PTS')
+      return
+
     plan = tools.TestPlan(packages)
     plan.Exclude('android\.performance.*')
     self.__WritePlan(plan, 'CTS')
@@ -124,6 +135,19 @@
     plan.Include(r'android\.tests\.appsecurity')
     self.__WritePlan(plan, 'AppSecurity')
 
+    # hard-coded white list for PDK plan
+    plan.Exclude('.*')
+    plan.Include('android\.bluetooth')
+    plan.Include('android\.graphics.*')
+    plan.Include('android\.hardware')
+    plan.Include('android\.media.*')
+    plan.Include('android\.net')
+    plan.Include('android\.opengl.*')
+    plan.Include('android\.renderscript')
+    plan.Include('android\.telephony')
+    plan.Include('android\.nativemedia.*')
+    self.__WritePlan(plan, 'PDK')
+
 def LogGenerateDescription(name):
   print 'Generating test description for package %s' % name
 
@@ -141,7 +165,9 @@
 
 if __name__ == '__main__':
   builder = CtsBuilder(sys.argv)
-  result = builder.GenerateTestDescriptions()
-  if result != 0:
-    sys.exit(result)
+  if builder.isCts:
+    result = builder.GenerateTestDescriptions()
+    if result != 0:
+      sys.exit(result)
   builder.GenerateTestPlans()
+
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)
diff --git a/tools/vm-tests-tf/Android.mk b/tools/vm-tests-tf/Android.mk
index 44dac66..88f2a53 100644
--- a/tools/vm-tests-tf/Android.mk
+++ b/tools/vm-tests-tf/Android.mk
@@ -18,7 +18,9 @@
 # ============================================================
 include $(CLEAR_VARS)
 
+# custom variables used to generate test description. do not touch!
 LOCAL_TEST_TYPE := vmHostTest
+LOCAL_JAR_PATH := android.core.vm-tests-tf.jar
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)