Merge "Add CTS tests for async event callouts from drm plugin to Java app" into jb-mr2-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 1e794f9..ed155c0 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -114,9 +114,11 @@
 # Host side only tests
 cts_host_libraries := \
 	$(PTS_HOST_CASES) \
+	CtsAdbTests \
 	CtsAppSecurityTests \
 	CtsMonkeyTestCases
 
+
 # Native test executables that need to have associated test XMLs.
 cts_native_exes := \
 	NativeMediaTest_SL \
diff --git a/hostsidetests/aadb/Android.mk b/hostsidetests/aadb/Android.mk
new file mode 100644
index 0000000..2f2113c
--- /dev/null
+++ b/hostsidetests/aadb/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2013 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)
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := CtsAdbTests
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt ddmlib-prebuilt junit
+
+LOCAL_CTS_TEST_PACKAGE := android.aadb
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java
new file mode 100644
index 0000000..5e2e8e0
--- /dev/null
+++ b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2013 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.aadb;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.IFileEntry;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.util.CommandStatus;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.RunUtil;
+import com.android.tradefed.util.StreamUtil;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Functional tests for adb connection
+ * <p/>
+ * Requires a physical device to be connected.
+ */
+public class TestDeviceFuncTest extends DeviceTestCase {
+
+    private static final String LOG_TAG = "TestDeviceFuncTest";
+    private ITestDevice mTestDevice;
+    /** Expect bugreports to be at least a meg. */
+    private static final int mMinBugreportBytes = 1024 * 1024;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTestDevice = getDevice();
+    }
+
+    /**
+     * Simple testcase to ensure that the grabbing a bugreport from a real TestDevice works.
+     */
+    public void testBugreport() throws Exception {
+        String data = StreamUtil.getStringFromStream(
+                mTestDevice.getBugreport().createInputStream());
+        assertTrue(String.format("Expected at least %d characters; only saw %d", mMinBugreportBytes,
+                data.length()), data.length() >= mMinBugreportBytes);
+        // TODO: check the captured report more extensively, perhaps using loganalysis
+    }
+
+    /**
+     * Simple normal case test for
+     * {@link TestDevice#executeShellCommand(String)}.
+     * <p/>
+     * Do a 'shell ls' command, and verify /data and /system are listed in result.
+     */
+    public void testExecuteShellCommand() throws IOException, DeviceNotAvailableException {
+        Log.i(LOG_TAG, "testExecuteShellCommand");
+        assertSimpleShellCommand();
+    }
+
+    /**
+     * Verify that a simple {@link TestDevice#executeShellCommand(String)} command is successful.
+     */
+    private void assertSimpleShellCommand() throws DeviceNotAvailableException {
+        final String output = mTestDevice.executeShellCommand("ls");
+        assertTrue(output.contains("data"));
+        assertTrue(output.contains("system"));
+    }
+
+
+    /**
+     * Push and then pull a file from device, and verify contents are as expected.
+     */
+    public void testPushPull_normal() throws IOException, DeviceNotAvailableException {
+        Log.i(LOG_TAG, "testPushPull");
+        File tmpFile = null;
+        File tmpDestFile = null;
+        String deviceFilePath = null;
+
+        try {
+            tmpFile = createTempTestFile(null);
+            String externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+            assertNotNull(externalStorePath);
+            deviceFilePath = String.format("%s/%s", externalStorePath, "tmp_testPushPull.txt");
+            // ensure file does not already exist
+            mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+            assertFalse(String.format("%s exists", deviceFilePath),
+                    mTestDevice.doesFileExist(deviceFilePath));
+
+            assertTrue(mTestDevice.pushFile(tmpFile, deviceFilePath));
+            assertTrue(mTestDevice.doesFileExist(deviceFilePath));
+            tmpDestFile = FileUtil.createTempFile("tmp", "txt");
+            assertTrue(mTestDevice.pullFile(deviceFilePath, tmpDestFile));
+            assertTrue(compareFiles(tmpFile, tmpDestFile));
+        } finally {
+            if (tmpDestFile != null) {
+                tmpDestFile.delete();
+            }
+            if (deviceFilePath != null) {
+                mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+            }
+        }
+    }
+
+    /**
+     * Push and then pull a file from device, and verify contents are as expected.
+     * <p />
+     * This variant of the test uses "${EXTERNAL_STORAGE}" in the pathname.
+     */
+    public void testPushPull_extStorageVariable() throws IOException, DeviceNotAvailableException {
+        Log.i(LOG_TAG, "testPushPull");
+        File tmpFile = null;
+        File tmpDestFile = null;
+        File tmpDestFile2 = null;
+        String deviceFilePath = null;
+        final String filename = "tmp_testPushPull.txt";
+
+        try {
+            tmpFile = createTempTestFile(null);
+            String externalStorePath = "${EXTERNAL_STORAGE}";
+            assertNotNull(externalStorePath);
+            deviceFilePath = String.format("%s/%s", externalStorePath, filename);
+            // ensure file does not already exist
+            mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+            assertFalse(String.format("%s exists", deviceFilePath),
+                    mTestDevice.doesFileExist(deviceFilePath));
+
+            assertTrue(mTestDevice.pushFile(tmpFile, deviceFilePath));
+            assertTrue(mTestDevice.doesFileExist(deviceFilePath));
+            tmpDestFile = FileUtil.createTempFile("tmp", "txt");
+            assertTrue(mTestDevice.pullFile(deviceFilePath, tmpDestFile));
+            assertTrue(compareFiles(tmpFile, tmpDestFile));
+
+            tmpDestFile2 = mTestDevice.pullFileFromExternal(filename);
+            assertNotNull(tmpDestFile2);
+            assertTrue(compareFiles(tmpFile, tmpDestFile2));
+        } finally {
+            if (tmpDestFile != null) {
+                tmpDestFile.delete();
+            }
+            if (tmpDestFile2 != null) {
+                tmpDestFile2.delete();
+            }
+            if (deviceFilePath != null) {
+                mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+            }
+        }
+    }
+
+    /**
+     * Test pulling a file from device that does not exist.
+     * <p/>
+     * Expect {@link TestDevice#pullFile(String)} to return <code>false</code>
+     */
+    public void testPull_noexist() throws IOException, DeviceNotAvailableException {
+        Log.i(LOG_TAG, "testPull_noexist");
+
+        // make sure the root path is valid
+        String externalStorePath =  mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+        assertNotNull(externalStorePath);
+        String deviceFilePath = String.format("%s/%s", externalStorePath, "thisfiledoesntexist");
+        assertFalse(String.format("%s exists", deviceFilePath),
+                mTestDevice.doesFileExist(deviceFilePath));
+        assertNull(mTestDevice.pullFile(deviceFilePath));
+    }
+
+    private File createTempTestFile(File dir) throws IOException {
+        File tmpFile = null;
+        try {
+            final String fileContents = "this is the test file contents";
+            tmpFile = FileUtil.createTempFile("tmp", ".txt", dir);
+            FileUtil.writeToFile(fileContents, tmpFile);
+            return tmpFile;
+        } catch (IOException e) {
+            if (tmpFile != null) {
+                tmpFile.delete();
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * Utility method to do byte-wise content comparison of two files.
+     */
+    private boolean compareFiles(File file1, File file2) throws IOException {
+        BufferedInputStream stream1 = null;
+        BufferedInputStream stream2 = null;
+
+        try {
+            stream1 = new BufferedInputStream(new FileInputStream(file1));
+            stream2 = new BufferedInputStream(new FileInputStream(file2));
+            boolean eof = false;
+            while (!eof) {
+                int byte1 = stream1.read();
+                int byte2 = stream2.read();
+                if (byte1 != byte2) {
+                    return false;
+                }
+                eof = byte1 == -1;
+            }
+            return true;
+        } finally {
+            if (stream1 != null) {
+                stream1.close();
+            }
+            if (stream2 != null) {
+                stream2.close();
+            }
+        }
+    }
+
+    /**
+     * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
+     */
+    public void testSyncFiles_normal() throws Exception {
+        doTestSyncFiles(mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE));
+    }
+
+    /**
+     * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
+     * <p />
+     * This variant of the test uses "${EXTERNAL_STORAGE}" in the pathname.
+     */
+    public void testSyncFiles_extStorageVariable() throws Exception {
+        doTestSyncFiles("${EXTERNAL_STORAGE}");
+    }
+
+    /**
+     * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
+     */
+    public void doTestSyncFiles(String externalStorePath) throws Exception {
+        String expectedDeviceFilePath = null;
+
+        // create temp dir with one temp file
+        File tmpDir = FileUtil.createTempDir("tmp");
+        try {
+            File tmpFile = createTempTestFile(tmpDir);
+            // set last modified to 10 minutes ago
+            tmpFile.setLastModified(System.currentTimeMillis() - 10*60*1000);
+            assertNotNull(externalStorePath);
+            expectedDeviceFilePath = String.format("%s/%s/%s", externalStorePath,
+                    tmpDir.getName(), tmpFile.getName());
+
+            assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
+            assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath));
+
+            // get 'ls -l' attributes of file which includes timestamp
+            String origTmpFileStamp = mTestDevice.executeShellCommand(String.format("ls -l %s",
+                    expectedDeviceFilePath));
+            // now create another file and verify that is synced
+            File tmpFile2 = createTempTestFile(tmpDir);
+            tmpFile2.setLastModified(System.currentTimeMillis() - 10*60*1000);
+            assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
+            String expectedDeviceFilePath2 = String.format("%s/%s/%s", externalStorePath,
+                    tmpDir.getName(), tmpFile2.getName());
+            assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath2));
+
+            // verify 1st file timestamp did not change
+            String unchangedTmpFileStamp = mTestDevice.executeShellCommand(String.format("ls -l %s",
+                    expectedDeviceFilePath));
+            assertEquals(origTmpFileStamp, unchangedTmpFileStamp);
+
+            // now modify 1st file and verify it does change remotely
+            String testString = "blah";
+            FileOutputStream stream = new FileOutputStream(tmpFile);
+            stream.write(testString.getBytes());
+            stream.close();
+
+            assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
+            String tmpFileContents = mTestDevice.executeShellCommand(String.format("cat %s",
+                    expectedDeviceFilePath));
+            assertTrue(tmpFileContents.contains(testString));
+        } finally {
+            if (expectedDeviceFilePath != null && externalStorePath != null) {
+                // note that expectedDeviceFilePath has externalStorePath prepended at definition
+                mTestDevice.executeShellCommand(String.format("rm -r %s", expectedDeviceFilePath));
+            }
+            FileUtil.recursiveDelete(tmpDir);
+        }
+    }
+
+    /**
+     * Test pushing a directory
+     */
+    public void testPushDir() throws IOException, DeviceNotAvailableException {
+        String expectedDeviceFilePath = null;
+        String externalStorePath = null;
+        File rootDir = FileUtil.createTempDir("tmp");
+        // create temp dir with one temp file
+        try {
+            File tmpDir = FileUtil.createTempDir("tmp", rootDir);
+            File tmpFile = createTempTestFile(tmpDir);
+            externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+            assertNotNull(externalStorePath);
+            expectedDeviceFilePath = String.format("%s/%s/%s", externalStorePath,
+                    tmpDir.getName(), tmpFile.getName());
+
+            assertTrue(mTestDevice.pushDir(rootDir, externalStorePath));
+            assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath));
+
+        } finally {
+            if (expectedDeviceFilePath != null && externalStorePath != null) {
+                mTestDevice.executeShellCommand(String.format("rm -r %s/%s", externalStorePath,
+                        expectedDeviceFilePath));
+            }
+            FileUtil.recursiveDelete(rootDir);
+        }
+    }
+
+    /**
+     * Basic test for {@link TestDevice#getScreenshot()}.
+     * <p/>
+     * Grab a screenshot, save it to a file, and perform a cursory size check to ensure its valid.
+     */
+    public void testGetScreenshot() throws DeviceNotAvailableException, IOException {
+        CLog.i(LOG_TAG, "testGetScreenshot");
+        InputStreamSource source = getDevice().getScreenshot();
+        assertNotNull(source);
+        File tmpPngFile = FileUtil.createTempFile("screenshot", ".png");
+        try {
+            FileUtil.writeToFile(source.createInputStream(), tmpPngFile);
+            CLog.i("Created file at %s", tmpPngFile.getAbsolutePath());
+            assertTrue("Saved png file is less than 16K - is it invalid?",
+                    tmpPngFile.length() > 16*1024);
+            // TODO: add more stringent checks
+        } finally {
+            FileUtil.deleteFile(tmpPngFile);
+            source.cancel();
+        }
+    }
+
+    /**
+     * Basic test for {@link TestDevice#getLogcat(long)}.
+     * <p/>
+     * Dumps a bunch of messages to logcat, calls getLogcat(), and verifies size of capture file is
+     * equal to provided data.
+     */
+    public void testGetLogcat_size() throws DeviceNotAvailableException, IOException {
+        CLog.i(LOG_TAG, "testGetLogcat_size");
+        for (int i = 0; i < 100; i++) {
+            getDevice().executeShellCommand(String.format("log testGetLogcat_size log dump %d", i));
+        }
+        // sleep a small amount of time to ensure last log message makes it into capture
+        RunUtil.getDefault().sleep(10);
+        InputStreamSource source = getDevice().getLogcat(100 * 1024);
+        assertNotNull(source);
+        File tmpTxtFile = FileUtil.createTempFile("logcat", ".txt");
+        try {
+            FileUtil.writeToFile(source.createInputStream(), tmpTxtFile);
+            CLog.i("Created file at %s", tmpTxtFile.getAbsolutePath());
+            assertEquals("Saved text file is not equal to buffer size", 100 * 1024,
+                    tmpTxtFile.length());
+            // ensure last log message is present in log
+            String s = FileUtil.readStringFromFile(tmpTxtFile);
+            assertTrue("last log message is not in captured logcat",
+                    s.contains("testGetLogcat_size log dump 99"));
+        } finally {
+            FileUtil.deleteFile(tmpTxtFile);
+            source.cancel();
+        }
+    }
+}
diff --git a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java
new file mode 100644
index 0000000..c780fb9
--- /dev/null
+++ b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2013 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.aadb;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.util.FileUtil;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Long running functional tests for {@link TestDevice} that verify an operation can be run
+ * many times in sequence
+ * <p/>
+ * Requires a physical device to be connected.
+ */
+public class TestDeviceStressTest extends DeviceTestCase {
+
+    private int mIterations = 50;
+
+    private static final String LOG_TAG = "TestDeviceStressTest";
+    private static final int TEST_FILE_COUNT= 200;
+    private ITestDevice mTestDevice;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTestDevice = getDevice();
+    }
+
+    private File createTempTestFiles() throws IOException {
+        File tmpDir = null;
+        File tmpFile = null;
+
+        tmpDir = FileUtil.createTempDir("testDir");
+
+        final String fileContents = "this is the test file contents";
+        for (int i = 0; i < TEST_FILE_COUNT; i++) {
+            tmpFile = FileUtil.createTempFile(String.format("tmp_%d", i), ".txt", tmpDir);
+            FileUtil.writeToFile(fileContents, tmpFile);
+        }
+        return tmpDir;
+
+    }
+
+    /**
+     * Stress test to push a folder which contains 200 text file to device
+     * internal storage.
+     */
+    public void testPushFolderWithManyFiles() throws IOException, DeviceNotAvailableException {
+        File tmpDir = null;
+        String deviceFilePath = null;
+        String externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+        assertNotNull(externalStorePath);
+        deviceFilePath = String.format("%s/%s", externalStorePath, "testDir");
+
+        // start the stress test
+        try {
+            // Create the test folder and make sure the test folder doesn't exist in
+            // device before the test start.
+            tmpDir = createTempTestFiles();
+            for (int i = 0; i < mIterations; i++) {
+                mTestDevice.executeShellCommand(String.format("rm -r %s", deviceFilePath));
+                assertFalse(String.format("%s exists", deviceFilePath),
+                        mTestDevice.doesFileExist(deviceFilePath));
+                assertTrue(mTestDevice.pushDir(tmpDir, deviceFilePath));
+                assertTrue(mTestDevice.doesFileExist(deviceFilePath));
+            }
+        } finally {
+            if (tmpDir != null) {
+                FileUtil.recursiveDelete(tmpDir);
+            }
+            mTestDevice.executeShellCommand(String.format("rm -r %s", deviceFilePath));
+            assertFalse(String.format("%s exists", deviceFilePath),
+                    mTestDevice.doesFileExist(deviceFilePath));
+        }
+    }
+}
diff --git a/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp b/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp
index 439e451..5b74bf3 100644
--- a/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp
+++ b/suite/pts/deviceTests/opengl/jni/graphics/GLUtils.cpp
@@ -139,7 +139,7 @@
 
     GLuint err = glGetError();
     if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
+        ALOGE("GLError %d", err);
         return false;
     }
 
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp b/suite/pts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
index bd132b9..1d9cc88 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
@@ -92,6 +92,9 @@
 extern "C" JNIEXPORT void JNICALL
 Java_com_android_pts_opengl_primitive_GLActivity_setupContextSwitchBenchmark(
         JNIEnv* env, jclass clazz, jobject surface, jboolean offscreen, jint workload) {
-    gRenderer = new ContextSwitchRenderer(
-            ANativeWindow_fromSurface(env, surface), offscreen, workload);
+    if (workload <= 8) {
+        // This test uses 8 iterations, so workload can't be more than 8.
+        gRenderer = new ContextSwitchRenderer(
+                ANativeWindow_fromSurface(env, surface), offscreen, workload);
+    }
 }
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/Renderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/Renderer.cpp
index 4bc0cda..fa3ec83 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/Renderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/Renderer.cpp
@@ -18,8 +18,7 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
+#include <primitive/Trace.h>
 
 static const EGLint contextAttribs[] = {
         EGL_CONTEXT_CLIENT_VERSION, 2,
@@ -42,7 +41,7 @@
 }
 
 bool Renderer::setUp() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     if (EGL_NO_DISPLAY == mEglDisplay || EGL_SUCCESS != eglGetError()) {
         return false;
@@ -87,12 +86,16 @@
     glViewport(0, 0, width, height);
 
     if (mOffscreen) {
-        int w = GLUtils::roundUpToSmallestPowerOf2(width);
-        int h = GLUtils::roundUpToSmallestPowerOf2(height);
-        if (!GLUtils::createFBO(mFboId, mRboId, mCboId, w, h)) {
+        mFboWidth = GLUtils::roundUpToSmallestPowerOf2(width);
+        mFboHeight = GLUtils::roundUpToSmallestPowerOf2(height);
+        if (!GLUtils::createFBO(mFboId, mRboId, mCboId, mFboWidth, mFboHeight)) {
             return false;
         }
+        mBuffer = new GLushort[mFboWidth * mFboHeight];
     } else {
+        mFboWidth = 0;
+        mFboHeight = 0;
+        mBuffer = 0;
         mFboId = 0;
         mRboId = 0;
         mCboId = 0;
@@ -100,14 +103,17 @@
 
     GLuint err = glGetError();
     if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
+        ALOGE("GLError %d", err);
         return false;
     }
     return true;
 }
 
 bool Renderer::tearDown() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
+    if (mBuffer != 0) {
+        delete[] mBuffer;
+    }
     if (mFboId != 0) {
         glDeleteFramebuffers(1, &mFboId);
         mFboId = 0;
@@ -135,3 +141,20 @@
     }
     return EGL_SUCCESS == eglGetError();
 }
+
+bool Renderer::draw() {
+    SCOPED_TRACE();
+    GLuint err = glGetError();
+    if (err != GL_NO_ERROR) {
+        ALOGE("GLError %d", err);
+        return false;
+    }
+
+    if (mOffscreen) {
+        // Read the pixels back from the frame buffer.
+        glReadPixels(0, 0, mFboWidth, mFboHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, mBuffer);
+        return true;
+    } else {
+        return eglSwapBuffers(mEglDisplay, mEglSurface);
+    }
+}
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/Renderer.h b/suite/pts/deviceTests/opengl/jni/primitive/Renderer.h
index 49c7e98..cbe9419 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/Renderer.h
+++ b/suite/pts/deviceTests/opengl/jni/primitive/Renderer.h
@@ -25,7 +25,7 @@
     Renderer(ANativeWindow* window, bool offscreen, int workload);
     virtual bool setUp();
     virtual bool tearDown();
-    virtual bool draw() = 0;
+    virtual bool draw();
     virtual ~Renderer() {};
 protected:
     ANativeWindow* mWindow;
@@ -33,9 +33,12 @@
     EGLSurface mEglSurface;
     EGLContext mEglContext;
     EGLConfig mGlConfig;
-    GLuint mFboId; //Frame buffer
-    GLuint mRboId; //Depth buffer
-    GLuint mCboId; //Color buffer
+    int mFboWidth;// Frame buffer width
+    int mFboHeight;// Frame buffer height
+    GLuint mFboId;// Frame buffer id
+    GLuint mRboId;// Depth buffer id
+    GLuint mCboId;// Color buffer id
+    GLushort* mBuffer;// Used for FBO read back
     GLuint mProgramId;
     EGLint width;
     EGLint height;
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/Trace.h b/suite/pts/deviceTests/opengl/jni/primitive/Trace.h
new file mode 100644
index 0000000..713d3a0
--- /dev/null
+++ b/suite/pts/deviceTests/opengl/jni/primitive/Trace.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 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 TRACE_H
+#define TRACE_H
+
+// #define TRACE
+
+#ifdef TRACE
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <utils/Trace.h>
+#define SCOPED_TRACE() android::ScopedTrace st(ATRACE_TAG, __func__)
+#else
+#define SCOPED_TRACE()
+#endif
+
+#endif
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
index cdfaaec..e365db6 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
@@ -27,21 +27,22 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
+#include <primitive/Trace.h>
 
 static const EGLint contextAttribs[] =
         { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
 
+static const int NUM_WORKER_CONTEXTS = 7;
+
 static const int CS_NUM_VERTICES = 6;
 
 static const float CS_VERTICES[CS_NUM_VERTICES * 3] = {
-        1.0f, 1.0f, -1.0f,
-        -1.0f, 1.0f, -1.0f,
-        -1.0f, -1.0f, -1.0f,
-        -1.0f, -1.0f, -1.0f,
-        1.0f, -1.0f, -1.0f,
-        1.0f, 1.0f, -1.0f };
+        0.1f, 0.1f, -0.1f,
+        -0.1f, 0.1f, -0.1f,
+        -0.1f, -0.1f, -0.1f,
+        -0.1f, -0.1f, -0.1f,
+        0.1f, -0.1f, -0.1f,
+        0.1f, 0.1f, -0.1f };
 
 static const float CS_TEX_COORDS[CS_NUM_VERTICES * 2] = {
         1.0f, 1.0f,
@@ -54,10 +55,12 @@
 static const char* CS_VERTEX =
         "attribute vec4 a_Position;"
         "attribute vec2 a_TexCoord;"
+        "uniform float u_Translate;"
         "varying vec2 v_TexCoord;"
         "void main() {"
         "  v_TexCoord = a_TexCoord;"
         "  gl_Position = a_Position;"
+        "  gl_Position.x = a_Position.x + u_Translate;"
         "}";
 
 static const char* CS_FRAGMENT =
@@ -73,31 +76,32 @@
 }
 
 bool ContextSwitchRenderer::setUp() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (!Renderer::setUp()) {
         return false;
     }
 
-    // We don't need the context created by Renderer.
-    eglDestroyContext(mEglDisplay, mEglContext);
-    mEglContext = EGL_NO_CONTEXT;
-
-    int w = GLUtils::roundUpToSmallestPowerOf2(width);
-    int h = GLUtils::roundUpToSmallestPowerOf2(height);
-
-    mContexts = new EGLContext[mWorkload];
-    mTextureIds = new GLuint[mWorkload];
-    mProgramIds = new GLuint[mWorkload];
-    mTextureUniformHandles = new GLuint[mWorkload];
-    mPositionHandles = new GLuint[mWorkload];
-    mTexCoordHandles = new GLuint[mWorkload];
-    if (mOffscreen) {
-        mFboIds = new GLuint[mWorkload];
-        mRboIds = new GLuint[mWorkload];
-        mCboIds = new GLuint[mWorkload];
+    // Setup texture.
+    mTextureId = GLUtils::genRandTex(64, 64);
+    if (mTextureId == 0) {
+        return false;
     }
-    for (int i = 0; i < mWorkload; i++) {
-        mContexts[i] = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT, contextAttribs);
+
+    // Create program.
+    mProgramId = GLUtils::createProgram(&CS_VERTEX, &CS_FRAGMENT);
+    if (mProgramId == 0) {
+        return false;
+    }
+    // Bind attributes.
+    mTextureUniformHandle = glGetUniformLocation(mProgramId, "u_Texture");
+    mTranslateUniformHandle = glGetUniformLocation(mProgramId, "u_Translate");
+    mPositionHandle = glGetAttribLocation(mProgramId, "a_Position");
+    mTexCoordHandle = glGetAttribLocation(mProgramId, "a_TexCoord");
+
+    mContexts = new EGLContext[NUM_WORKER_CONTEXTS];
+    for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
+        // Create the contexts, they share data with the main one.
+        mContexts[i] = eglCreateContext(mEglDisplay, mGlConfig, mEglContext, contextAttribs);
         if (EGL_NO_CONTEXT == mContexts[i] || EGL_SUCCESS != eglGetError()) {
             return false;
         }
@@ -106,34 +110,11 @@
                 || EGL_SUCCESS != eglGetError()) {
             return false;
         }
-
-        if (mOffscreen) {
-            // Setup FBOs.
-            if (!GLUtils::createFBO(mFboIds[i], mRboIds[i], mCboIds[i], w, h)) {
-                return false;
-            }
-        }
-
-        // Setup textures.
-        mTextureIds[i] = GLUtils::genRandTex(64, 64);
-        if (mTextureIds[i] == 0) {
-            return false;
-        }
-
-        // Create program.
-        mProgramIds[i] = GLUtils::createProgram(&CS_VERTEX, &CS_FRAGMENT);
-        if (mProgramIds[i] == 0) {
-            return false;
-        }
-        // Bind attributes.
-        mTextureUniformHandles[i] = glGetUniformLocation(mProgramIds[i], "u_Texture");
-        mPositionHandles[i] = glGetAttribLocation(mProgramIds[i], "a_Position");
-        mTexCoordHandles[i] = glGetAttribLocation(mProgramIds[i], "a_TexCoord");
     }
 
     GLuint err = glGetError();
     if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
+        ALOGE("GLError %d", err);
         return false;
     }
 
@@ -141,30 +122,17 @@
 }
 
 bool ContextSwitchRenderer::tearDown() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mContexts) {
-        for (int i = 0; i < mWorkload; i++) {
+        // Destroy the contexts, the main one will be handled by Renderer::tearDown().
+        for (int i = 0; i < NUM_WORKER_CONTEXTS; i++) {
             eglDestroyContext(mEglDisplay, mContexts[i]);
         }
         delete[] mContexts;
     }
-    if (mOffscreen) {
-        if (mFboIds) {
-            glDeleteFramebuffers(mWorkload, mFboIds);
-            delete[] mFboIds;
-        }
-        if (mRboIds) {
-            glDeleteRenderbuffers(mWorkload, mRboIds);
-            delete[] mRboIds;
-        }
-        if (mCboIds) {
-            glDeleteRenderbuffers(mWorkload, mCboIds);
-            delete[] mCboIds;
-        }
-    }
-    if (mTextureIds) {
-        glDeleteTextures(mWorkload, mTextureIds);
-        delete[] mTextureIds;
+    if (mTextureId != 0) {
+        glDeleteTextures(1, &mTextureId);
+        mTextureId = 0;
     }
     if (!Renderer::tearDown()) {
         return false;
@@ -173,46 +141,64 @@
 }
 
 bool ContextSwitchRenderer::draw() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
-    for (int i = 0; i < mWorkload; i++) {
-        if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i])
-                || EGL_SUCCESS != eglGetError()) {
-            return false;
-        }
+    SCOPED_TRACE();
 
-        if (mOffscreen) {
-            glBindFramebuffer(GL_FRAMEBUFFER, mFboIds[i]);
-            if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-                return false;
-            }
-        }
-
-        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-
-        glUseProgram(mProgramIds[i]);
-        glActiveTexture(GL_TEXTURE0);
-        // Bind the texture to this unit.
-        glBindTexture(GL_TEXTURE_2D, mTextureIds[i]);
-
-        // Tell the texture uniform sampler to use this texture in the shader by binding to texture
-        // unit 0.
-        glUniform1i(mTextureUniformHandles[i], 0);
-
-        glEnableVertexAttribArray(mPositionHandles[i]);
-        glEnableVertexAttribArray(mTexCoordHandles[i]);
-        glVertexAttribPointer(mPositionHandles[i], 3, GL_FLOAT, false, 0, CS_VERTICES);
-        glVertexAttribPointer(mTexCoordHandles[i], 2, GL_FLOAT, false, 0, CS_TEX_COORDS);
-
-        glDrawArrays(GL_TRIANGLES, 0, CS_NUM_VERTICES);
-        glFinish();
-    }
-
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
+    if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)
+            || EGL_SUCCESS != eglGetError()) {
         return false;
     }
 
-    return (mOffscreen) ? true : eglSwapBuffers(mEglDisplay, mEglSurface);
+    if (mOffscreen) {
+        glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
+    }
+
+    // Set the background clear color to black.
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    // No culling of back faces
+    glDisable(GL_CULL_FACE);
+    // No depth testing
+    glDisable(GL_DEPTH_TEST);
+
+    const int TOTAL_NUM_CONTEXTS = NUM_WORKER_CONTEXTS + 1;
+    const float TRANSLATION = 0.9f - (TOTAL_NUM_CONTEXTS * 0.2f);
+    for (int i = 0; i < TOTAL_NUM_CONTEXTS; i++) {
+        glUseProgram(mProgramId);
+
+        glActiveTexture (GL_TEXTURE0);
+        // Bind the texture to this unit.
+        glBindTexture(GL_TEXTURE_2D, mTextureId);
+
+        // Tell the texture uniform sampler to use this texture in the shader by binding to texture
+        // unit 0.
+        glUniform1i(mTextureUniformHandle, 0);
+
+        // Set the x translate.
+        glUniform1f(mTranslateUniformHandle, (i * 0.2f) + TRANSLATION);
+
+        glEnableVertexAttribArray(mPositionHandle);
+        glEnableVertexAttribArray(mTexCoordHandle);
+        glVertexAttribPointer(mPositionHandle, 3, GL_FLOAT, false, 0, CS_VERTICES);
+        glVertexAttribPointer(mTexCoordHandle, 2, GL_FLOAT, false, 0, CS_TEX_COORDS);
+
+        glDrawArrays(GL_TRIANGLES, 0, CS_NUM_VERTICES);
+
+        // Switch to next context.
+        if (i < (mWorkload - 1)) {
+            if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mContexts[i])
+                    || EGL_SUCCESS != eglGetError()) {
+                return false;
+            }
+        }
+    }
+
+    if (mOffscreen) {
+        // Need to switch back to the main context so the renderer can do the read back.
+        if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)
+                || EGL_SUCCESS != eglGetError()) {
+            return false;
+        }
+    }
+
+    return Renderer::draw();
 }
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h b/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
index 24d8df1..d4e7595 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
+++ b/suite/pts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
@@ -24,18 +24,12 @@
     bool tearDown();
     bool draw();
 private:
+    EGLContext* mContexts;
+    GLuint mTextureId;
     GLuint mTextureUniformHandle;
+    GLuint mTranslateUniformHandle;
     GLuint mPositionHandle;
     GLuint mTexCoordHandle;
-    EGLContext* mContexts;
-    GLuint* mTextureIds;
-    GLuint* mFboIds;
-    GLuint* mRboIds;
-    GLuint* mCboIds;
-    GLuint* mProgramIds;
-    GLuint* mTextureUniformHandles;
-    GLuint* mPositionHandles;
-    GLuint* mTexCoordHandles;
 };
 
 #endif
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
index 3db5eea..f178912 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
@@ -11,7 +11,6 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-#include <math.h>
 #include <EGL/egl.h>
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
@@ -27,8 +26,7 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
+#include <primitive/Trace.h>
 
 static const int FP_NUM_VERTICES = 6;
 
@@ -104,7 +102,7 @@
 }
 
 bool FullPipelineRenderer::setUp() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (!Renderer::setUp()) {
         return false;
     }
@@ -126,12 +124,12 @@
     float centerY = 0.0f;
     float centerZ = 0.0f;
 
-    // Set our up vector. This is where our head would be pointing were we holding the camera.
+    // Set our up vector.
     float upX = 0.0f;
     float upY = 1.0f;
     float upZ = 0.0f;
 
-    // Set the view matrix. This matrix can be said to represent the camera position.
+    // Set the view matrix.
     mViewMatrix = Matrix::newLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
 
     // Create a new perspective projection matrix. The height will stay the same
@@ -152,9 +150,9 @@
         return false;
     }
 
-    float count = pow(2, mWorkload - 1);
+    float count = mWorkload * mWorkload;
     float middle = count / 2.0f;
-    float scale = 1.0f / count;
+    float scale = 2.0f / count;
 
     mMesh = new Mesh(FP_VERTICES, FP_NORMALS, FP_TEX_COORDS, FP_NUM_VERTICES, mTextureId);
     mSceneGraph = new ProgramNode();
@@ -173,7 +171,7 @@
 }
 
 bool FullPipelineRenderer::tearDown() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mTextureId != 0) {
         glDeleteTextures(1, &mTextureId);
         mTextureId = 0;
@@ -197,7 +195,7 @@
 }
 
 bool FullPipelineRenderer::draw() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mOffscreen) {
         glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
     }
@@ -211,16 +209,5 @@
     mModelMatrix->identity();
     mSceneGraph->draw(*mProgram, *mModelMatrix, *mViewMatrix, *mProjectionMatrix);
 
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
-        return false;
-    }
-
-    if (mOffscreen) {
-        glFinish();
-        return true;
-    } else {
-        return eglSwapBuffers(mEglDisplay, mEglSurface);
-    }
+    return Renderer::draw();
 }
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
index d2fd762..2f3d647 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
@@ -18,8 +18,7 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
+#include <primitive/Trace.h>
 
 static const int PO_NUM_VERTICES = 6;
 
@@ -60,7 +59,7 @@
 }
 
 bool PixelOutputRenderer::setUp() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (!Renderer::setUp()) {
         return false;
     }
@@ -83,7 +82,7 @@
 }
 
 bool PixelOutputRenderer::tearDown() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mTextureId != 0) {
         glDeleteTextures(1, &mTextureId);
         mTextureId = 0;
@@ -95,7 +94,7 @@
 }
 
 bool PixelOutputRenderer::draw() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mOffscreen) {
         glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
     }
@@ -130,16 +129,5 @@
         glDrawArrays(GL_TRIANGLES, 0, PO_NUM_VERTICES);
     }
 
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
-        return false;
-    }
-
-    if (mOffscreen) {
-        glFinish();
-        return true;
-    } else {
-        return eglSwapBuffers(mEglDisplay, mEglSurface);
-    }
+    return Renderer::draw();
 }
diff --git a/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp b/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
index 62fe1ac..156f81e 100644
--- a/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
+++ b/suite/pts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
@@ -20,10 +20,9 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
+#include <primitive/Trace.h>
 
-static const float GOLDEN_RATIO = (1.0 + sqrt(5.0)) / 2.0;
+static const float GOLDEN_RATIO = (1.0f + sqrt(5.0f)) / 2.0f;
 
 static const int SP_NUM_VERTICES = 6;
 
@@ -63,7 +62,7 @@
 //Add workload here
 
 static const char* SP_FRAGMENT_2 =
-        " * 5;"//workload * 5 (5 is a balanced number, bigger = more work)
+        " * 4;"//workload * 4 (4 is a tweaking number, bigger = more work)
         "  vec2 z;"
         "  z.x = 3.0 * (v_TexCoord.x - 0.5);"
         "  z.y = 2.0 * (v_TexCoord.y - 0.5);"
@@ -101,7 +100,7 @@
 }
 
 bool ShaderPerfRenderer::setUp() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (!Renderer::setUp()) {
         return false;
     }
@@ -144,7 +143,7 @@
 
     GLuint err = glGetError();
     if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
+        ALOGE("GLError %d", err);
         return false;
     }
 
@@ -152,7 +151,7 @@
 }
 
 bool ShaderPerfRenderer::draw() {
-    android::ScopedTrace st(ATRACE_TAG, __func__);
+    SCOPED_TRACE();
     if (mOffscreen) {
         glBindFramebuffer(GL_FRAMEBUFFER, mFboId);
     }
@@ -180,16 +179,5 @@
 
     glDrawArrays(GL_TRIANGLES, 0, SP_NUM_VERTICES);
 
-    GLuint err = glGetError();
-    if (err != GL_NO_ERROR) {
-        ALOGV("GLError %d", err);
-        return false;
-    }
-
-    if (mOffscreen) {
-        glFinish();
-        return true;
-    } else {
-        return eglSwapBuffers(mEglDisplay, mEglSurface);
-    }
+    return Renderer::draw();
 }
diff --git a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLBenchmark.java b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLBenchmark.java
index 0eab7cd..66405cb 100644
--- a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLBenchmark.java
+++ b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLBenchmark.java
@@ -20,7 +20,6 @@
 import android.content.Intent;
 import android.cts.util.TimeoutReq;
 import android.opengl.Matrix;
-import android.util.Log;
 
 import java.util.Arrays;
 
@@ -29,6 +28,10 @@
  */
 public class GLBenchmark extends PtsActivityInstrumentationTestCase2<GLActivity> {
 
+    private static final int NUM_FRAMES = 100;
+    private static final int NUM_ITERATIONS = 8;
+    private static final int TIME_OUT = 1000000;
+
     public GLBenchmark() {
         super(GLActivity.class);
     }
@@ -36,59 +39,65 @@
     /**
      * Runs the full OpenGL ES 2.0 pipeline test offscreen.
      */
-    @TimeoutReq(minutes = 20)
+    @TimeoutReq(minutes = 100)
     public void testFullPipelineOffscreen() throws Exception {
-        runBenchmark(Benchmark.FullPipeline, true, 500, 8, 1000000);
+        runBenchmark(Benchmark.FullPipeline, true, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the full OpenGL ES 2.0 pipeline test onscreen.
      */
-    @TimeoutReq(minutes = 20)
+    @TimeoutReq(minutes = 100)
     public void testFullPipelineOnscreen() throws Exception {
-        runBenchmark(Benchmark.FullPipeline, false, 500, 8, 1000000);
+        runBenchmark(Benchmark.FullPipeline, false, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the pixel output test offscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testPixelOutputOffscreen() throws Exception {
-        runBenchmark(Benchmark.PixelOutput, true, 500, 8, 1000000);
+        runBenchmark(Benchmark.PixelOutput, true, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the pixel output test onscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testPixelOutputOnscreen() throws Exception {
-        runBenchmark(Benchmark.PixelOutput, false, 500, 8, 1000000);
+        runBenchmark(Benchmark.PixelOutput, false, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the shader performance test offscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testShaderPerfOffscreen() throws Exception {
-        runBenchmark(Benchmark.ShaderPerf, true, 500, 8, 1000000);
+        runBenchmark(Benchmark.ShaderPerf, true, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the shader performance test onscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testShaderPerfOnscreen() throws Exception {
-        runBenchmark(Benchmark.ShaderPerf, false, 500, 8, 1000000);
+        runBenchmark(Benchmark.ShaderPerf, false, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the context switch overhead test offscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testContextSwitchOffscreen() throws Exception {
-        runBenchmark(Benchmark.ContextSwitch, true, 500, 8, 1000000);
+        runBenchmark(Benchmark.ContextSwitch, true, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
      * Runs the context switch overhead test onscreen.
      */
+    @TimeoutReq(minutes = 100)
     public void testContextSwitchOnscreen() throws Exception {
-        runBenchmark(Benchmark.ContextSwitch, false, 500, 8, 1000000);
+        runBenchmark(Benchmark.ContextSwitch, false, NUM_FRAMES, NUM_ITERATIONS, TIME_OUT);
     }
 
     /**
@@ -124,6 +133,8 @@
                 for (double d : fpsValues) {
                     score += d;
                 }
+                score /= numIterations;// Average.
+
                 getReportLog().printArray(
                         "Fps Values", fpsValues, ResultType.HIGHER_BETTER, ResultUnit.FPS);
                 getReportLog()
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/DeviceReportLog.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/DeviceReportLog.java
index 9747ca5..43e93d3 100644
--- a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/DeviceReportLog.java
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/DeviceReportLog.java
@@ -16,10 +16,16 @@
 
 package com.android.pts.util;
 
+import android.app.Instrumentation;
+import android.os.Bundle;
 import android.util.Log;
 
+import java.lang.Exception;
+
 public class DeviceReportLog extends ReportLog {
-    private static final String TAG = "PtsReport";
+    private static final String TAG = "DevicePtsReport";
+    private static final String PTS_RESULT = "PTS_RESULT";
+    private static final int INST_STATUS_IN_PROGRESS = 2;
 
     DeviceReportLog() {
         mDepth = 4;
@@ -29,4 +35,11 @@
     protected void printLog(String msg) {
         Log.i(TAG, msg);
     }
+
+    public void deliverReportToHost(Instrumentation instrumentation) {
+        Log.i(TAG, "deliverReportToHost");
+        Bundle output = new Bundle();
+        output.putString(PTS_RESULT, generateReport());
+        instrumentation.sendStatus(INST_STATUS_IN_PROGRESS, output);
+    }
 }
diff --git a/tests/tests/nativeopengl/libnativeopengltests/GLTestHelper.cpp b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/DummyActivity.java
similarity index 66%
rename from tests/tests/nativeopengl/libnativeopengltests/GLTestHelper.cpp
rename to suite/pts/deviceTests/ptsutil/src/com/android/pts/util/DummyActivity.java
index ed527a6..c3ceb9f 100644
--- a/tests/tests/nativeopengl/libnativeopengltests/GLTestHelper.cpp
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/DummyActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 The Android Open Source Project
+ * Copyright (C) 2013 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,16 +14,11 @@
  * limitations under the License.
  */
 
-#include "GLTestHelper.h"
 
-using namespace android;
+package com.android.pts.util;
 
-ANativeWindow* GLTestHelper::mWindow;
+import android.app.Activity;
 
-ANativeWindow* GLTestHelper::getWindow() {
-    return mWindow;
-}
+public class DummyActivity extends Activity {
 
-void GLTestHelper::setWindow(ANativeWindow* value) {
-    mWindow = value;
 }
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
index 0c9cdfa..a14be01 100644
--- a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsActivityInstrumentationTestCase2.java
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsActivityInstrumentationTestCase2.java
@@ -24,7 +24,7 @@
 public class PtsActivityInstrumentationTestCase2<T extends Activity> extends
         ActivityInstrumentationTestCase2<T> {
 
-    private ReportLog mReportLog = new DeviceReportLog();
+    private DeviceReportLog mReportLog = new DeviceReportLog();
 
     public PtsActivityInstrumentationTestCase2(Class<T> activityClass) {
         super(activityClass);
@@ -36,7 +36,8 @@
 
     @Override
     protected void tearDown() throws Exception {
-        mReportLog.throwReportToHost();
+        mReportLog.deliverReportToHost(getInstrumentation());
+        super.tearDown();
     }
 
 }
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
index b847df7..6da7bdc 100644
--- a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsAndroidTestCase.java
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsAndroidTestCase.java
@@ -17,18 +17,20 @@
 
 package com.android.pts.util;
 
+import android.content.Context;
 import android.test.AndroidTestCase;
 
-public class PtsAndroidTestCase extends AndroidTestCase {
-
-    private ReportLog mReportLog = new DeviceReportLog();
-
-    public ReportLog getReportLog() {
-        return mReportLog;
+/**
+ *  This class emulates AndroidTestCase, but internally it is ActivityInstrumentationTestCase2
+ *  to access Instrumentation.
+ *  DummyActivity is not supposed to be accessed.
+ */
+public class PtsAndroidTestCase extends PtsActivityInstrumentationTestCase2<DummyActivity> {
+    public PtsAndroidTestCase() {
+        super(DummyActivity.class);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        mReportLog.throwReportToHost();
+    public Context getContext() {
+        return getInstrumentation().getContext();
     }
 }
diff --git a/suite/pts/hostTests/bootup/src/com/android/pts/bootup/BootupTimeTest.java b/suite/pts/hostTests/bootup/src/com/android/pts/bootup/BootupTimeTest.java
index dd7b834..d02b260 100644
--- a/suite/pts/hostTests/bootup/src/com/android/pts/bootup/BootupTimeTest.java
+++ b/suite/pts/hostTests/bootup/src/com/android/pts/bootup/BootupTimeTest.java
@@ -17,6 +17,7 @@
 package com.android.pts.bootup;
 
 import android.cts.util.TimeoutReq;
+import com.android.pts.util.HostReportLog;
 import com.android.pts.util.MeasureRun;
 import com.android.pts.util.MeasureTime;
 import com.android.pts.util.ResultType;
@@ -32,27 +33,18 @@
  *  Measure reboot-time using adb shell reboot
  */
 public class BootupTimeTest extends DeviceTestCase {
-
-    private ReportLog mReport = null;
     // add some delay before each reboot
     final static long SLEEP_BEFORE_REBOOT_TIME = 2 * 60 * 1000L;
     final static int REBOOT_TIMEOUT_MS = 10 * 60 * 1000;
 
-    @Override
-    protected void setUp() throws Exception {
-        mReport = new ReportLog();
-        super.setUp();
-    }
-
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mReport.throwReportToHost();
-    }
-
     @TimeoutReq(minutes = 30)
     public void testBootupTime() throws Exception {
+        // cannot run in emulator
+        if (getDevice().getSerialNumber().startsWith("emulator-")) {
+            return;
+        }
+        HostReportLog report =
+                new HostReportLog(getDevice().getSerialNumber(), ReportLog.getClassMethodNames());
         final int NUMBER_REPEAT = 5;
         double[] result = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
             @Override
@@ -67,11 +59,12 @@
                 rebootDevice();
             }
         });
-        mReport.printArray("bootup time", result, ResultType.LOWER_BETTER,
+        report.printArray("bootup time", result, ResultType.LOWER_BETTER,
                 ResultUnit.MS);
         StatResult stat = Stat.getStat(result);
-        mReport.printSummary("bootup time", stat.mAverage, ResultType.LOWER_BETTER,
+        report.printSummary("bootup time", stat.mAverage, ResultType.LOWER_BETTER,
                 ResultUnit.MS);
+        report.deliverReportToHost();
     }
 
     private void rebootDevice() throws DeviceNotAvailableException {
diff --git a/suite/pts/hostTests/ptshostutil/src/com/android/pts/ptsutil/LogcatLineReceiver.java b/suite/pts/hostTests/ptshostutil/src/com/android/pts/ptsutil/LogcatLineReceiver.java
deleted file mode 100644
index cb4980c..0000000
--- a/suite/pts/hostTests/ptshostutil/src/com/android/pts/ptsutil/LogcatLineReceiver.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.ptsutil;
-
-import com.android.tradefed.device.ITestDevice;
-
-/**
- * class to handle logcat log per each line.
- * processALine is supposed to be overridden.
- */
-public class LogcatLineReceiver extends LogcatMonitor {
-    public LogcatLineReceiver(ITestDevice device, String logcatFilter, long timeoutInSec) {
-        super(device, logcatFilter, timeoutInSec);
-    }
-
-    /**
-     * empty default implementation. Will be called whenever a line of log is received
-     * @param line
-     * @throws Exception
-     */
-    public void processALine(String line) throws Exception {
-
-    }
-
-    @Override
-    public void addOutput(byte[] data, int offset, int length) {
-        String lines = new String(data, offset, length);
-        try {
-            for (String line : lines.split("\n")) {
-                processALine(line);
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-}
diff --git a/suite/pts/hostTests/ptshostutil/src/com/android/pts/ptsutil/LogcatMonitor.java b/suite/pts/hostTests/ptshostutil/src/com/android/pts/ptsutil/LogcatMonitor.java
deleted file mode 100644
index adc1340..0000000
--- a/suite/pts/hostTests/ptshostutil/src/com/android/pts/ptsutil/LogcatMonitor.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.ptsutil;
-
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.tradefed.device.BackgroundDeviceAction;
-import com.android.tradefed.device.ITestDevice;
-
-import java.io.IOException;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * class to monitor adb logcat asynchronously.
- * Unlike tradefed's LogcatReceiver, log is accumulated to a buffer, and the log is removed after
- * reading once.
- */
-public class LogcatMonitor implements IShellOutputReceiver {
-    private static final String TAG = "LogcatMonitor";
-    private LinkedBlockingQueue<String> mQ = new LinkedBlockingQueue<String>();
-    private boolean mRunning = false;
-    private long mTimeoutInSec;
-    private BackgroundDeviceAction mDeviceAction;
-    // sentinel to detect EOS
-    private static final String EOS = "LOGCAT_MONITOR_EOS";
-    private static final String LOGCAT_CMD = "logcat -v threadtime ";
-
-    public LogcatMonitor(ITestDevice device, String logcatFilter, long timeoutInSec) {
-        mTimeoutInSec = timeoutInSec;
-        int logStartDelay = 0;
-        mDeviceAction = new BackgroundDeviceAction(LOGCAT_CMD + logcatFilter, TAG, device,
-                this, logStartDelay);
-    }
-
-    /** start monitoring log */
-    public void start() {
-        if (mRunning) {
-            return;
-        }
-        clear();
-        mDeviceAction.start();
-        mRunning = true;
-    }
-
-    /** stop monitoring */
-    public void stop() {
-        mDeviceAction.cancel();
-        mRunning = false;
-    }
-
-    /** clear all stored logs */
-    public void clear() {
-        mQ.clear();
-    }
-
-    /**
-     * read a line of log. If there is no data stored, it can wait until
-     *   the timeout specified in the constructor.
-     * @return null for time-out. Otherwise, a line of log is returned.
-     * @throws IOException for EOS (logcat terminated for whatever reason)
-     * @throws InterruptedException
-     */
-    public String getALine() throws IOException, InterruptedException {
-        String line = mQ.poll(mTimeoutInSec, TimeUnit.SECONDS);
-        if (line == EOS) {
-            throw new IOException();
-        }
-        return line;
-    }
-
-    public boolean dataAvailable() {
-        return !mQ.isEmpty();
-    }
-
-    @Override
-    public void addOutput(byte[] data, int offset, int length) {
-        String lines = new String(data, offset, length);
-        for (String line : lines.split("\n")) {
-            mQ.add(line);
-        }
-    }
-
-    @Override
-    public void flush() {
-        mQ.add(EOS);
-        mRunning = false;
-    }
-
-    @Override
-    public boolean isCancelled() {
-        return !mRunning;
-    }
-}
diff --git a/suite/pts/hostTests/ptshostutil/src/com/android/pts/util/HostReportLog.java b/suite/pts/hostTests/ptshostutil/src/com/android/pts/util/HostReportLog.java
new file mode 100644
index 0000000..49f24fe
--- /dev/null
+++ b/suite/pts/hostTests/ptshostutil/src/com/android/pts/util/HostReportLog.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 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 com.android.cts.tradefed.result.PtsHostStore;
+
+
+/**
+ * ReportLog for host tests
+ * Note that setTestInfo should be set before throwing report
+ */
+public class HostReportLog extends ReportLog {
+    private String mDeviceSerial;
+    private String mClassMethodName;
+
+    /**
+     * @param deviceSerial serial number of the device
+     * @param classMethodName class name and method name of the test in class#method format.
+     *        Note that ReportLog.getClassMethodNames() provide this.
+     */
+    public HostReportLog(String deviceSerial, String classMethodName) {
+        mDeviceSerial = deviceSerial;
+        mClassMethodName = classMethodName;
+    }
+
+    public void deliverReportToHost() {
+        PtsHostStore.storePtsResult(mDeviceSerial, mClassMethodName, generateReport());
+    }
+}
diff --git a/suite/pts/hostTests/uihost/src/com/android/pts/uihost/InstallTimeTest.java b/suite/pts/hostTests/uihost/src/com/android/pts/uihost/InstallTimeTest.java
index 056e0f4..55e9b40 100644
--- a/suite/pts/hostTests/uihost/src/com/android/pts/uihost/InstallTimeTest.java
+++ b/suite/pts/hostTests/uihost/src/com/android/pts/uihost/InstallTimeTest.java
@@ -17,6 +17,7 @@
 package com.android.pts.uihost;
 
 import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.pts.util.HostReportLog;
 import com.android.pts.util.MeasureRun;
 import com.android.pts.util.MeasureTime;
 import com.android.pts.util.ResultType;
@@ -38,7 +39,6 @@
 public class InstallTimeTest extends DeviceTestCase implements IBuildReceiver {
     private CtsBuildHelper mBuild;
     private ITestDevice mDevice;
-    private ReportLog mReport = null;
 
     static final String PACKAGE = "com.replica.replicaisland";
     static final String APK = "com.replica.replicaisland.apk";
@@ -51,19 +51,19 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mReport = new ReportLog();
         mDevice = getDevice();
     }
 
 
     @Override
     protected void tearDown() throws Exception {
-        super.tearDown();
         mDevice.uninstallPackage(PACKAGE);
-        mReport.throwReportToHost();
+        super.tearDown();
     }
 
     public void testInstallTime() throws Exception {
+        HostReportLog report =
+                new HostReportLog(mDevice.getSerialNumber(), ReportLog.getClassMethodNames());
         final int NUMBER_REPEAT = 10;
         final CtsBuildHelper build = mBuild;
         final ITestDevice device = mDevice;
@@ -78,11 +78,12 @@
                 device.installPackage(app, false);
             }
         });
-        mReport.printArray("install time", result, ResultType.LOWER_BETTER,
+        report.printArray("install time", result, ResultType.LOWER_BETTER,
                 ResultUnit.MS);
         StatResult stat = Stat.getStat(result);
-        mReport.printSummary("install time", stat.mAverage, ResultType.LOWER_BETTER,
+        report.printSummary("install time", stat.mAverage, ResultType.LOWER_BETTER,
                 ResultUnit.MS);
+        report.deliverReportToHost();
     }
 
 }
diff --git a/suite/pts/hostTests/uihost/src/com/android/pts/uihost/TaskSwitchingTest.java b/suite/pts/hostTests/uihost/src/com/android/pts/uihost/TaskSwitchingTest.java
index 49d14a3..f1eb80a 100644
--- a/suite/pts/hostTests/uihost/src/com/android/pts/uihost/TaskSwitchingTest.java
+++ b/suite/pts/hostTests/uihost/src/com/android/pts/uihost/TaskSwitchingTest.java
@@ -19,14 +19,14 @@
 import android.cts.util.TimeoutReq;
 
 import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.tradefed.result.PtsReportUtil;
+import com.android.cts.tradefed.result.PtsHostStore;
 import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
 import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.pts.util.MeasureRun;
-import com.android.pts.util.MeasureTime;
-import com.android.pts.util.PtsException;
-import com.android.pts.util.Stat;
-import com.android.pts.util.Stat.StatResult;
+import com.android.pts.util.HostReportLog;
+import com.android.pts.util.ReportLog;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
@@ -40,6 +40,7 @@
 import java.io.File;
 import java.util.Map;
 
+
 /**
  * Measure time to taskswitching between two Apps: A & B
  * Actual test is done in device, but this host side code installs all necessary APKs
@@ -50,6 +51,7 @@
     private final static String CTS_RUNNER = "android.test.InstrumentationCtsTestRunner";
     private CtsBuildHelper mBuild;
     private ITestDevice mDevice;
+    private String mPtsReport = null;
 
     static final String[] PACKAGES = {
         "com.android.pts.taskswitching.control",
@@ -81,36 +83,36 @@
 
     @Override
     protected void tearDown() throws Exception {
-        super.tearDown();
         for (int i = 0; i < PACKAGES.length; i++) {
             mDevice.uninstallPackage(PACKAGES[i]);
         }
+        super.tearDown();
     }
 
     @TimeoutReq(minutes = 30)
     public void testTaskswitching() throws Exception {
+        HostReportLog report =
+                new HostReportLog(mDevice.getSerialNumber(), ReportLog.getClassMethodNames());
         RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(PACKAGES[0], CTS_RUNNER,
                 mDevice.getIDevice());
-        CollectingTestListener listener = new CollectingTestListener();
+        LocalListener listener = new LocalListener();
         mDevice.runInstrumentationTests(testRunner, listener);
         TestRunResult result = listener.getCurrentRunResults();
         if (result.isRunFailure()) {
             fail(result.getRunFailureMessage());
         }
-        Map<TestIdentifier, TestResult> details = result.getTestResults();
-        final String expectedException = "com.android.pts.util.PtsException";
-        for (Map.Entry<TestIdentifier, TestResult> entry : details.entrySet()) {
-            TestResult res = entry.getValue();
-            String stackTrace = res.getStackTrace();
-            if (stackTrace != null) {
-                if (stackTrace.startsWith(expectedException)) {
-                    String[] lines = stackTrace.split("[\r\n]+");
-                    String msg = lines[0].substring(expectedException.length() + 1).trim();
-                    throw new PtsException(msg);
-                }
-            }
-        }
-        fail("no performance data");
+        assertNotNull("no performance data", mPtsReport);
+        PtsHostStore.storePtsResult(mDevice.getSerialNumber(),
+                ReportLog.getClassMethodNames(), mPtsReport);
+
     }
 
+    public class LocalListener extends CollectingTestListener {
+        @Override
+        public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {
+            // necessary as testMetrics passed from CollectingTestListerner is empty
+            mPtsReport = PtsReportUtil.getPtsResultFromMetrics(testMetrics);
+            super.testEnded(test, testMetrics);
+        }
+    }
 }
diff --git a/suite/pts/lib/commonutil/Android.mk b/suite/pts/lib/commonutil/Android.mk
index 152f862..73df09b 100644
--- a/suite/pts/lib/commonutil/Android.mk
+++ b/suite/pts/lib/commonutil/Android.mk
@@ -28,7 +28,7 @@
 
 include $(CLEAR_VARS)
 
-# only TmeoutReq annotation used from the libs/util, so add it here
+# only TimeoutReq annotation used from the libs/util, so add it here
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src) \
     ../../../../libs/util/src/android/cts/util/TimeoutReq.java
diff --git a/suite/pts/lib/commonutil/src/com/android/pts/util/ReportLog.java b/suite/pts/lib/commonutil/src/com/android/pts/util/ReportLog.java
index 8a5e624..63f5589 100644
--- a/suite/pts/lib/commonutil/src/com/android/pts/util/ReportLog.java
+++ b/suite/pts/lib/commonutil/src/com/android/pts/util/ReportLog.java
@@ -115,9 +115,10 @@
                 LOG_ELEM_SEPARATOR + unit.getXmlString() + LOG_ELEM_SEPARATOR + value;
     }
 
-    public void throwReportToHost() throws PtsException {
+    protected String generateReport() {
         if ((mSummary == null) && mMessages.isEmpty()) {
-            return;
+            // just return empty string
+            return "";
         }
         StringBuilder builder = new StringBuilder();
         builder.append(mSummary);
@@ -132,7 +133,7 @@
         }
         mSummary = null;
         mMessages.clear();
-        throw new PtsException(builder.toString());
+        return builder.toString();
     }
 
     /**
@@ -177,7 +178,7 @@
     }
 
     /**
-     * get classname.methodname from call stack of the current thread
+     * get classname#methodname from call stack of the current thread
      */
     public static String getClassMethodNames() {
         return getClassMethodNames(mDepth, false);
diff --git a/suite/pts/utils/grapher.py b/suite/pts/utils/grapher.py
index 94bf25e..e326612 100755
--- a/suite/pts/utils/grapher.py
+++ b/suite/pts/utils/grapher.py
@@ -26,6 +26,13 @@
   sudo apt-get install python-matplotlib
 """
 
+colors = {
+  'maguro':'#FF0000',
+  'mako':'#00FF00',
+  'manta':'#0000FF',
+  'tilapia':'#00FFFF'
+}
+
 def main(argv):
   if len(argv) != 2:
     print "grapher.py pts_report_dir"
@@ -44,7 +51,7 @@
       plt.title(benchmark[benchmark.index('#') + 1:])
       # For each result in the data set
       for r in results:
-        score = r['result']
+        score = r.get('result', 'no results')
         x = []
         y = []
         if score == 'pass':
@@ -56,8 +63,11 @@
         if score != 'no results':
           # Create a plot
           ax = fig.add_subplot(111)
+          name = r['device']
+          lbl = name + ' (%s)'%score
+          clr = colors.get(name, "#%06X" % (hash(name) % 0xFFFFFF))
           # Plot the workload vs the values
-          ax.plot(x, y, 'o-', label=r['device'] + ' (%s)'%score)
+          ax.plot(x, y, 'o-', label=lbl, color=clr)
           # Add a legend
           ax.legend(loc='upper right').get_frame().set_fill(False)
       (ymin, ymax) = plt.ylim()
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 ec3524d..6a66f1b 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 10e169a..85dfc7aa 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-ldpi/holo_panel_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view.png
index 659809a..66cecf2 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view_feb.png
index 2930e2f..f78a47a 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view_feb.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/nativeopengl/AndroidManifest.xml b/tests/tests/nativeopengl/AndroidManifest.xml
index 52157b4..72d87ac 100644
--- a/tests/tests/nativeopengl/AndroidManifest.xml
+++ b/tests/tests/nativeopengl/AndroidManifest.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 /*
- * Copyright 2012 Google Inc.
+ * Copyright 2013 Google Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/tests/tests/nativeopengl/libnativeopengltests/Android.mk b/tests/tests/nativeopengl/libnativeopengltests/Android.mk
index b6ca1cb..c9e10c4 100644
--- a/tests/tests/nativeopengl/libnativeopengltests/Android.mk
+++ b/tests/tests/nativeopengl/libnativeopengltests/Android.mk
@@ -16,7 +16,7 @@
 # This is the shared library included by the JNI test app.
 #
 
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH:= $(call my-dir)/../standalone/jni/
 
 include $(CLEAR_VARS)
 
@@ -34,14 +34,13 @@
 LOCAL_SRC_FILES := \
         register.cpp \
         GLTestHelper.cpp \
-        android_test_wrappedgtest_WrappedGTestActivity.cpp \
-        com_android_opengl_cts_GLTestActivity.cpp \
         tests/GLTest_test.cpp
 
 LOCAL_SHARED_LIBRARIES := libEGL \
                           libGLESv2 \
                           libstlport \
-                          libandroid
+                          libandroid \
+                          liblog
 
 LOCAL_STATIC_LIBRARIES := libgtest
 
diff --git a/tests/tests/nativeopengl/libnativeopengltests/android_test_wrappedgtest_WrappedGTestActivity.cpp b/tests/tests/nativeopengl/libnativeopengltests/android_test_wrappedgtest_WrappedGTestActivity.cpp
deleted file mode 100644
index 5e1c30e..0000000
--- a/tests/tests/nativeopengl/libnativeopengltests/android_test_wrappedgtest_WrappedGTestActivity.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 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 <android/log.h>
-#include <gtest/gtest.h>
-#include <jni.h>
-
-using namespace testing;
-
-class GTestListener : public EmptyTestEventListener {
-public:
-    GTestListener(JNIEnv *env, jobject activity)
-        : mActivity(activity), mEnv(env) {
-
-        jclass clazz = env->FindClass(
-              "android/test/wrappedgtest/WrappedGTestActivity");
-        mSendStatusID = env->GetMethodID(clazz, "sendStatus",
-              "(Ljava/lang/String;)V");
-        mMessageBuffer = new char[2048];
-    }
-
-    ~GTestListener() {
-        delete[] mMessageBuffer;
-    }
-
-private:
-    jobject   mActivity;
-    JNIEnv *  mEnv;
-    jmethodID mSendStatusID;
-    char *    mMessageBuffer;
-
-    virtual void OnTestIterationStart(const UnitTest& unit_test,
-            int iteration) {
-        snprintf(mMessageBuffer, sizeof(char) * 2048,
-                "[==========] Running %i tests from %i test cases.",
-                unit_test.test_to_run_count(),
-                unit_test.test_case_to_run_count());
-
-        mEnv->CallVoidMethod(mActivity, mSendStatusID,
-                mEnv->NewStringUTF(mMessageBuffer));
-    }
-
-    virtual void OnTestStart(const TestInfo& test_info) {
-        snprintf(mMessageBuffer, sizeof(char) * 2048, "[ RUN      ] %s.%s",
-                test_info.test_case_name(), test_info.name());
-
-        mEnv->CallVoidMethod(mActivity, mSendStatusID,
-                mEnv->NewStringUTF(mMessageBuffer));
-    }
-
-    virtual void OnTestPartResult(const TestPartResult& result) {
-        if (result.type() == TestPartResult::kSuccess) {
-            return;
-        }
-
-        snprintf(mMessageBuffer, sizeof(char) * 2048, "%s:%i: Failure\n%s",
-                result.file_name(), result.line_number(), result.message());
-
-        mEnv->CallVoidMethod(mActivity, mSendStatusID,
-                mEnv->NewStringUTF(mMessageBuffer));
-    }
-
-    virtual void OnTestEnd(const TestInfo& test_info) {
-        const char * result = test_info.result()->Passed() ?
-                "[       OK ] " : "[  FAILED  ] ";
-
-        snprintf(mMessageBuffer, sizeof(char) * 2048, "%s%s.%s (%lli ms)",
-                result, test_info.test_case_name(), test_info.name(),
-                test_info.result()->elapsed_time());
-
-        mEnv->CallVoidMethod(mActivity, mSendStatusID,
-                mEnv->NewStringUTF(mMessageBuffer));
-    }
-
-    virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) {
-        snprintf(mMessageBuffer, sizeof(char) * 2048,
-                "[==========] %i tests from %i test cases ran. (%lli ms total)",
-                unit_test.test_to_run_count(),
-                unit_test.test_case_to_run_count(), unit_test.elapsed_time());
-
-        mEnv->CallVoidMethod(mActivity, mSendStatusID,
-                mEnv->NewStringUTF(mMessageBuffer));
-    }
-};
-
-static jboolean WrappedGTestActivity_runTests(JNIEnv *env, jobject obj,
-        jobject activity) {
-    // init gtest with no args
-    int argc = 0;
-    InitGoogleTest(&argc, (char**)NULL);
-
-    // delete the default listener
-    TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
-    delete listeners.Release(listeners.default_result_printer());
-
-    // add custom listener
-    GTestListener * listener = new GTestListener(env, activity);
-    listeners.Append(listener);
-
-    // run tests
-    int result = RUN_ALL_TESTS();
-
-    delete listener;
-    return result;
-};
-
-static JNINativeMethod methods[] = {
-    // name, signature, function
-    { "runTests", "(Landroid/test/wrappedgtest/WrappedGTestActivity;)I", (void*)WrappedGTestActivity_runTests },
-};
-
-int register_WrappedGTestActivity(JNIEnv *env) {
-    return env->RegisterNatives(
-            env->FindClass("android/test/wrappedgtest/WrappedGTestActivity"),
-            methods, sizeof(methods) / sizeof(JNINativeMethod));
-};
diff --git a/tests/tests/nativeopengl/libnativeopengltests/com_android_opengl_cts_GLTestActivity.cpp b/tests/tests/nativeopengl/libnativeopengltests/com_android_opengl_cts_GLTestActivity.cpp
deleted file mode 100644
index 8544f2a..0000000
--- a/tests/tests/nativeopengl/libnativeopengltests/com_android_opengl_cts_GLTestActivity.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 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 <gtest/gtest.h>
-#include <jni.h>
-
-#include "GLTestHelper.h"
-#include <android/native_window_jni.h>
-
-using namespace android;
-
-static void GLTestActivity_setSurface(JNIEnv *env, jobject obj,
-        jobject surface) {
-    ANativeWindow* window = ANativeWindow_fromSurface(env, surface);
-    GLTestHelper::setWindow(window);
-};
-
-static JNINativeMethod methods[] = {
-    // name, signature, function
-    { "setSurface", "(Landroid/view/Surface;)V", (void*)GLTestActivity_setSurface },
-};
-
-int register_GLTestActivity(JNIEnv *env) {
-    return env->RegisterNatives(
-            env->FindClass("com/android/opengl/cts/GLTestActivity"),
-            methods, sizeof(methods) / sizeof(JNINativeMethod));
-};
diff --git a/tests/tests/nativeopengl/standalone/AndroidManifest.xml b/tests/tests/nativeopengl/standalone/AndroidManifest.xml
new file mode 100644
index 0000000..a82e42a
--- /dev/null
+++ b/tests/tests/nativeopengl/standalone/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * 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.gltest"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="8"
+        android:targetSdkVersion="15" />
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <application>
+        <activity android:name=".GLTestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/tests/tests/nativeopengl/standalone/jni/Android.mk b/tests/tests/nativeopengl/standalone/jni/Android.mk
new file mode 100644
index 0000000..c23a1df
--- /dev/null
+++ b/tests/tests/nativeopengl/standalone/jni/Android.mk
@@ -0,0 +1,48 @@
+# Copyright 2013 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.
+#
+
+MY_LOCAL_PATH := $(call my-dir)
+MY_GTEST_PATH := $(MY_LOCAL_PATH)/../../../../../../external/gtest
+
+# gtest
+
+LOCAL_PATH := $(MY_GTEST_PATH)
+
+include $(CLEAR_VARS)
+
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_MODULE := libgtest
+LOCAL_C_INCLUDES := $(MY_GTEST_PATH)/include
+LOCAL_SRC_FILES := src/gtest-all.cc
+
+include $(BUILD_SHARED_LIBRARY)
+
+# nativetests
+
+LOCAL_PATH := $(MY_LOCAL_PATH)
+
+include $(CLEAR_VARS)
+
+LIB_PATH := $(LOCAL_PATH)/../libs/$(TARGET_ARCH_ABI)/
+LOCAL_C_INCLUDES := $(MY_GTEST_PATH)/include
+LOCAL_LDLIBS    := -L$(LIB_PATH) -landroid -lEGL -lGLESv2 -llog -lgtest
+LOCAL_MODULE    := nativeopengltests
+LOCAL_SRC_FILES := GLTestHelper.cpp \
+                   register.cpp \
+                   tests/GLTest_test.cpp
+
+LOCAL_SHARE_LIBRARIES := libgtest
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/nativeopengl/standalone/jni/Application.mk b/tests/tests/nativeopengl/standalone/jni/Application.mk
new file mode 100644
index 0000000..76d05a7
--- /dev/null
+++ b/tests/tests/nativeopengl/standalone/jni/Application.mk
@@ -0,0 +1,16 @@
+# Copyright 2013 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.
+#
+
+APP_STL := stlport_shared
diff --git a/tests/tests/nativeopengl/standalone/jni/GLTestHelper.cpp b/tests/tests/nativeopengl/standalone/jni/GLTestHelper.cpp
new file mode 100644
index 0000000..d1f29d5
--- /dev/null
+++ b/tests/tests/nativeopengl/standalone/jni/GLTestHelper.cpp
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#define LOG_TAG "GLTest"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+
+#include <android/log.h>
+#include <android/native_window.h>
+#include <GLTestHelper.h>
+
+// this listener is used to forward the subset of
+// gtest output needed to generate CTS results
+class CTSGTestListener : public EmptyTestEventListener {
+public:
+    CTSGTestListener(JNIEnv *env, jobject activity)
+        : mActivity(activity), mEnv(env) {
+
+        jclass clazz = env->FindClass(
+              "android/test/wrappedgtest/WrappedGTestActivity");
+        mSendStatusID = env->GetMethodID(clazz, "sendStatus",
+              "(Ljava/lang/String;)V");
+        mMessageBuffer = new char[2048];
+    }
+
+    ~CTSGTestListener() {
+        delete[] mMessageBuffer;
+    }
+
+private:
+    jobject   mActivity;
+    JNIEnv *  mEnv;
+    jmethodID mSendStatusID;
+    char *    mMessageBuffer;
+
+    virtual void OnTestIterationStart(const UnitTest& unit_test,
+            int iteration) {
+        snprintf(mMessageBuffer, sizeof(char) * 2048,
+                "[==========] Running %i tests from %i test cases.",
+                unit_test.test_to_run_count(),
+                unit_test.test_case_to_run_count());
+
+        mEnv->CallVoidMethod(mActivity, mSendStatusID,
+                mEnv->NewStringUTF(mMessageBuffer));
+    }
+
+    virtual void OnTestStart(const TestInfo& test_info) {
+        snprintf(mMessageBuffer, sizeof(char) * 2048, "[ RUN      ] %s.%s",
+                test_info.test_case_name(), test_info.name());
+
+        mEnv->CallVoidMethod(mActivity, mSendStatusID,
+                mEnv->NewStringUTF(mMessageBuffer));
+    }
+
+    virtual void OnTestPartResult(const TestPartResult& result) {
+        if (result.type() == TestPartResult::kSuccess) {
+            return;
+        }
+
+        snprintf(mMessageBuffer, sizeof(char) * 2048, "%s:%i: Failure\n%s",
+                result.file_name(), result.line_number(), result.message());
+
+        mEnv->CallVoidMethod(mActivity, mSendStatusID,
+                mEnv->NewStringUTF(mMessageBuffer));
+    }
+
+    virtual void OnTestEnd(const TestInfo& test_info) {
+        const char * result = test_info.result()->Passed() ?
+                "[       OK ] " : "[  FAILED  ] ";
+
+        snprintf(mMessageBuffer, sizeof(char) * 2048, "%s%s.%s (%lli ms)",
+                result, test_info.test_case_name(), test_info.name(),
+                test_info.result()->elapsed_time());
+
+        mEnv->CallVoidMethod(mActivity, mSendStatusID,
+                mEnv->NewStringUTF(mMessageBuffer));
+    }
+
+    virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) {
+        snprintf(mMessageBuffer, sizeof(char) * 2048,
+                "[==========] %i tests from %i test cases ran. (%lli ms total)",
+                unit_test.test_to_run_count(),
+                unit_test.test_case_to_run_count(), unit_test.elapsed_time());
+
+        mEnv->CallVoidMethod(mActivity, mSendStatusID,
+                mEnv->NewStringUTF(mMessageBuffer));
+    }
+};
+
+// this listener is similar to the default gtest listener
+// but it outputs the results to the log instead of stdout
+class LogGTestListener : public EmptyTestEventListener {
+
+private:
+    virtual void OnTestIterationStart(const UnitTest& unit_test,
+            int iteration) {
+        LOGI("[==========] Running %i tests from %i test cases.\n",
+                unit_test.test_to_run_count(),
+                unit_test.test_case_to_run_count());
+    }
+
+    virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) {
+        LOGI("[==========] Global test environment set-up.\n");
+    }
+
+    virtual void OnTestCaseStart(const TestCase& test_case) {
+        LOGI("[----------] %i tests from %s\n",
+                test_case.test_to_run_count(),
+                test_case.name());
+
+    }
+
+    virtual void OnTestStart(const TestInfo& test_info) {
+        LOGI("[ RUN      ] %s.%s\n", test_info.test_case_name(),
+                test_info.name());
+
+    }
+
+    virtual void OnTestPartResult(const TestPartResult& result) {
+        if (result.type() == TestPartResult::kSuccess) {
+            return;
+        }
+
+        LOGI("%s:%i: Failure\n%s\n", result.file_name(), result.line_number(),
+                result.message());
+    }
+
+    virtual void OnTestEnd(const TestInfo& test_info) {
+        const char * result = test_info.result()->Passed() ?
+                "[       OK ] " : "[  FAILED  ] ";
+
+        LOGI("%s%s.%s (%lli ms)\n", result, test_info.test_case_name(),
+                test_info.name(), test_info.result()->elapsed_time());
+    }
+
+
+    virtual void OnTestCaseEnd(const TestCase& test_case) {
+        LOGI("[----------] %i tests from %s (%lli ms total)\n",
+                test_case.test_to_run_count(), test_case.name(),
+                test_case.elapsed_time());
+
+    }
+
+    virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) {
+        LOGI("[==========] Global test environment tear-down.\n");
+    }
+
+    void PrintFailedTests(const UnitTest& unit_test) {
+        const int failed_test_count = unit_test.failed_test_count();
+        if (failed_test_count == 0) {
+            return;
+        }
+
+        for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
+            const TestCase& test_case = *unit_test.GetTestCase(i);
+
+            if (!test_case.should_run() || test_case.failed_test_count() == 0) {
+                continue;
+            }
+
+            for (int j = 0; j < test_case.total_test_count(); ++j) {
+                const TestInfo& test_info = *test_case.GetTestInfo(j);
+                if (!test_info.should_run() || test_info.result()->Passed()) {
+                    continue;
+                }
+                LOGI("[  FAILED  ] %s.%s\n", test_case.name(),
+                        test_info.name());
+            }
+        }
+    }
+    virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) {
+        LOGI("[==========] %i tests from %i test cases ran. (%lli ms total)\n",
+                unit_test.test_to_run_count(),
+                unit_test.test_case_to_run_count(), unit_test.elapsed_time());
+
+        LOGI("[  PASSED  ] %i tests\n", unit_test.successful_test_count());
+
+        if(unit_test.Passed()) {
+            return;
+        }
+
+        LOGI("[  FAILED  ] %i tests, listed below:\n",
+                unit_test.failed_test_count());
+
+        PrintFailedTests(unit_test);
+
+        LOGI("\n%2d FAILED TESTS\n", unit_test.failed_test_count());
+    }
+};
+
+ANativeWindow* GLTestHelper::mWindow;
+
+ANativeWindow* GLTestHelper::getWindow() {
+    return mWindow;
+}
+
+void GLTestHelper::setWindow(JNIEnv *env, jobject obj, jobject surface) {
+    mWindow = ANativeWindow_fromSurface(env, surface);
+}
+
+int GLTestHelper::runGTests(TestEventListener * listener, char * filter) {
+
+    if (filter) {
+        ::testing::GTEST_FLAG(filter) = filter;
+    }
+
+    int argc = 0;
+    InitGoogleTest(&argc, (char**)NULL);
+
+    TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
+    delete listeners.Release(listeners.default_result_printer());
+
+    listeners.Append(listener);
+    int result = RUN_ALL_TESTS();
+    return result;
+}
+
+int GLTestHelper::runTests(JNIEnv *env, jobject obj, jstring filter) {
+    LogGTestListener * listener = new LogGTestListener();
+
+    char * filter_cstr = NULL;
+
+    // set filter if there is one
+    if (filter) {
+       filter_cstr = new char[512];
+       const char * ptr = env->GetStringUTFChars(filter, NULL);
+       snprintf(filter_cstr, sizeof(char) * 512, "%s", ptr);
+       env->ReleaseStringUTFChars(filter, ptr);
+    }
+
+    int result = runGTests(listener, filter_cstr);
+
+    if (filter_cstr) {
+        delete[] filter_cstr;
+    }
+
+    delete listener;
+    return result;
+}
+
+int GLTestHelper::runTestsCTS(JNIEnv *env, jobject obj, jobject activity) {
+    CTSGTestListener * listener = new CTSGTestListener(env, activity);
+    int result = runGTests(listener, NULL);
+    delete listener;
+    return result;
+}
+
+int GLTestHelper::registerNative(JNIEnv * env) {
+
+    jclass clazz = env->FindClass("com/android/opengl/cts/GLTestActivity");
+
+    jthrowable exception = env->ExceptionOccurred();
+    // CTS class not found, assume stand-alone application
+    if (exception) {
+        env->ExceptionClear();
+
+        if (!env->IsInstanceOf(env->ExceptionOccurred(),
+                    env->FindClass("java/lang/NoClassDefFoundError"))) {
+            env->Throw(exception);
+        }
+
+        //
+        JNINativeMethod standaloneMethods[] = {
+            // name, signature, function
+            { "setSurface", "(Landroid/view/Surface;)V", (void*)(GLTestHelper::setWindow) },
+            { "runTests", "(Ljava/lang/String;)V", (void*)(GLTestHelper::runTests) },
+        };
+
+        return env->RegisterNatives(
+                env->FindClass("com/android/gltest/GLTestActivity"),
+                standaloneMethods,
+                sizeof(standaloneMethods) / sizeof(JNINativeMethod));
+    }
+
+    // GLTestActivity methods
+    JNINativeMethod glTestActMethods[] = {
+        // name, signature, function
+        { "setSurface", "(Landroid/view/Surface;)V", (void*)(GLTestHelper::setWindow) },
+    };
+
+    int result = env->RegisterNatives(clazz, glTestActMethods,
+                         sizeof(glTestActMethods) / sizeof(JNINativeMethod));
+
+    if (result) {
+        return result;
+    }
+
+    // WrappedGTestActivity methods
+    JNINativeMethod wrappedGTestActMethods[] = {
+        // name, signature, function
+        { "runTests", "(Landroid/test/wrappedgtest/WrappedGTestActivity;)I",
+            (void*)(GLTestHelper::runTestsCTS) },
+    };
+
+    return env->RegisterNatives(
+            env->FindClass("android/test/wrappedgtest/WrappedGTestActivity"),
+            wrappedGTestActMethods,
+            sizeof(wrappedGTestActMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/nativeopengl/libnativeopengltests/GLTestHelper.h b/tests/tests/nativeopengl/standalone/jni/GLTestHelper.h
similarity index 63%
rename from tests/tests/nativeopengl/libnativeopengltests/GLTestHelper.h
rename to tests/tests/nativeopengl/standalone/jni/GLTestHelper.h
index c0775f0..d09d2f1 100644
--- a/tests/tests/nativeopengl/libnativeopengltests/GLTestHelper.h
+++ b/tests/tests/nativeopengl/standalone/jni/GLTestHelper.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright 2013 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.
@@ -17,20 +17,22 @@
 #ifndef ANDROID_GL_TEST_HELPER_H
 #define ANDROID_GL_TEST_HELPER_H
 
-#include <stdint.h>
-#include <sys/types.h>
-#include <android/native_window.h>
-#include <utils/RefBase.h>
+#include <android/native_window_jni.h>
+#include <gtest/gtest.h>
 
-using namespace android;
+using namespace testing;
 
 class GLTestHelper
 {
 private:
     static ANativeWindow* mWindow;
+    static int runGTests(TestEventListener* listener, char * filter);
+    static int runTests(JNIEnv* env, jobject obj, jstring filter);
+    static int runTestsCTS(JNIEnv* env, jobject obj, jobject activity);
 public:
     static ANativeWindow* getWindow();
-    static void setWindow(ANativeWindow* value);
+    static void setWindow(JNIEnv* env, jobject obj, jobject surface);
+    static int registerNative(JNIEnv* env);
 };
 
 
diff --git a/tests/tests/nativeopengl/libnativeopengltests/register.cpp b/tests/tests/nativeopengl/standalone/jni/register.cpp
similarity index 77%
rename from tests/tests/nativeopengl/libnativeopengltests/register.cpp
rename to tests/tests/nativeopengl/standalone/jni/register.cpp
index 97a8bd4..8dd14ed 100644
--- a/tests/tests/nativeopengl/libnativeopengltests/register.cpp
+++ b/tests/tests/nativeopengl/standalone/jni/register.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 The Android Open Source Project
+ * Copyright 2013 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.
@@ -15,7 +15,7 @@
  */
 
 #include <jni.h>
-#include <stdlib.h>
+#include <GLTestHelper.h>
 
 /*
  * This function is called automatically by the system when this
@@ -29,13 +29,7 @@
         return JNI_ERR;
     }
 
-    extern int register_WrappedGTestActivity(JNIEnv *);
-    if (register_WrappedGTestActivity(env)) {
-        return JNI_ERR;
-    }
-
-    extern int register_GLTestActivity(JNIEnv *);
-    if (register_GLTestActivity(env)) {
+    if (GLTestHelper::registerNative(env)) {
         return JNI_ERR;
     }
 
diff --git a/tests/tests/nativeopengl/libnativeopengltests/tests/GLTest_test.cpp b/tests/tests/nativeopengl/standalone/jni/tests/GLTest_test.cpp
similarity index 98%
rename from tests/tests/nativeopengl/libnativeopengltests/tests/GLTest_test.cpp
rename to tests/tests/nativeopengl/standalone/jni/tests/GLTest_test.cpp
index 37bfcb5..5df090d 100644
--- a/tests/tests/nativeopengl/libnativeopengltests/tests/GLTest_test.cpp
+++ b/tests/tests/nativeopengl/standalone/jni/tests/GLTest_test.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 The Android Open Source Project
+ * Copyright 2013 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.
@@ -17,15 +17,15 @@
 
 #include <android/native_window.h>
 
-#include <gtest/gtest.h>
-
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
+
+#include <gtest/gtest.h>
+
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-
-#include "GLTestHelper.h"
+#include <GLTestHelper.h>
 
 
 namespace android {
diff --git a/tests/tests/nativeopengl/standalone/src/com/android/gltest/GLTestActivity.java b/tests/tests/nativeopengl/standalone/src/com/android/gltest/GLTestActivity.java
new file mode 100644
index 0000000..3c1e2af
--- /dev/null
+++ b/tests/tests/nativeopengl/standalone/src/com/android/gltest/GLTestActivity.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2013 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.gltest;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.Surface;
+
+public class GLTestActivity extends Activity {
+
+    private class TestThread extends Thread {
+
+        public void run() {
+            // it is possible to set the GTest filter flag from here
+            // for example "GLTest.ClearColorTest" to run that specific test only
+            runTests(null);
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+
+            finish();
+            System.exit(0);
+        }
+    }
+
+    private SurfaceView mSurfaceView;
+
+    private SurfaceHolder.Callback mHolderCallback = new SurfaceHolder.Callback() {
+
+        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+            setSurface(holder.getSurface());
+        }
+
+        public void surfaceCreated(SurfaceHolder holder) {
+            setSurface(holder.getSurface());
+            Thread t = new TestThread();
+            t.start();
+        }
+
+        public void surfaceDestroyed(SurfaceHolder holder) {
+        }
+    };
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        if (checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
+                == PackageManager.PERMISSION_GRANTED) {
+            KeyguardManager keyguardManager =
+                (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+            keyguardManager.newKeyguardLock("gltest").disableKeyguard();
+        }
+
+        super.onCreate(savedInstanceState);
+
+        mSurfaceView = new SurfaceView(this);
+        mSurfaceView.getHolder().addCallback(mHolderCallback);
+        setContentView(mSurfaceView);
+        System.loadLibrary("stlport_shared");
+        System.loadLibrary("gtest");
+        System.loadLibrary("nativeopengltests");
+    }
+
+    private static native void setSurface(Surface surface);
+    private static native void runTests(String filter);
+}
diff --git a/tests/tests/security/src/android/security/cts/CertificateData.java b/tests/tests/security/src/android/security/cts/CertificateData.java
index 1b039a5..f2e2f8c 100644
--- a/tests/tests/security/src/android/security/cts/CertificateData.java
+++ b/tests/tests/security/src/android/security/cts/CertificateData.java
@@ -63,6 +63,7 @@
       "59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16",
       "50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31",
       "1B:4B:39:61:26:27:6B:64:91:A2:68:6D:D7:02:43:21:2D:1F:1D:96",
+      "77:47:4F:C6:30:E4:0F:4C:47:64:3F:84:BA:B8:C6:95:4A:8A:41:EC",
       "8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4",
       "56:E0:FA:C0:3B:8F:18:23:55:18:E5:D3:11:CA:E8:C2:43:31:AB:66",
       "02:72:68:29:3E:5F:5D:17:AA:A4:B3:C3:E6:36:1E:1F:92:57:5E:AA",
diff --git a/tests/tests/security/src/android/security/cts/KernelSettingsTest.java b/tests/tests/security/src/android/security/cts/KernelSettingsTest.java
index 6daaffe..f8ee283 100644
--- a/tests/tests/security/src/android/security/cts/KernelSettingsTest.java
+++ b/tests/tests/security/src/android/security/cts/KernelSettingsTest.java
@@ -96,14 +96,14 @@
      * which is commonly used by exploit writers to gain root access.
      *
      * Support for loadable modules can be removed by editing the Linux kernel
-     * config and removing the CONFIG_KMOD option.
+     * config and removing the CONFIG_MODULES option.
      */
     public void testNoLoadableModules() throws IOException {
         assertFalse(
             "Support for loadable modules is compiled into the kernel. "
                 + "Loadable modules are often used by rootkits and other "
                 + "exploits and should be disabled. Please remove "
-                + "CONFIG_KMOD from your kernel config and compile "
+                + "CONFIG_MODULES from your kernel config and compile "
                 + "all modules directly into the kernel.",
             new File("/proc/sys/kernel/modprobe").exists());
     }
diff --git a/tests/tests/security/src/android/security/cts/SqliteJournalLeakTest.java b/tests/tests/security/src/android/security/cts/SqliteJournalLeakTest.java
old mode 100755
new mode 100644
diff --git a/tests/tests/text/src/android/text/util/cts/LinkifyTest.java b/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
index 404f9d7..45111f2 100644
--- a/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
+++ b/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
@@ -26,6 +26,7 @@
 import android.text.util.Linkify.TransformFilter;
 import android.widget.TextView;
 
+import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -73,7 +74,6 @@
 
     public void testAddLinks1() {
         SpannableString spannable = new SpannableString("name@gmail.com, "
-                + "123456789, tel:(0812)1234567 "
                 + "www.google.com, http://www.google.com/language_tools?hl=en, ");
 
         assertTrue(Linkify.addLinks(spannable, Linkify.WEB_URLS));
@@ -87,12 +87,6 @@
         assertEquals(1, spans.length);
         assertEquals("mailto:name@gmail.com", spans[0].getURL());
 
-        assertTrue(Linkify.addLinks(spannable, Linkify.PHONE_NUMBERS));
-        spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
-        assertEquals(2, spans.length);
-        assertEquals("tel:123456789", spans[0].getURL());
-        assertEquals("tel:08121234567", spans[1].getURL());
-
         try {
             Linkify.addLinks((Spannable) null, Linkify.WEB_URLS);
             fail("Should throw NullPointerException!");
@@ -304,4 +298,43 @@
         assertEquals("test:FilterUpperCase.pattern", spans[0].getURL());
         assertEquals("test:12", spans[1].getURL());
     }
+
+    public void testAddLinks7() {
+        String numbersInvalid = "123456789 not a phone number";
+        String numbersUKLocal = "tel:(0812)1234560 (0812)1234561";
+        String numbersUSLocal = "tel:(812)1234562 (812)123.4563 "
+                + " tel:(800)5551210 (800) 555-1211 555-1212";
+        String numbersIntl = "tel:+4408121234564 +44-0812-123-4565"
+                + " tel:+18005551213 +1-800-555-1214";
+        SpannableString spannable = new SpannableString(
+                numbersInvalid
+                + " " + numbersUKLocal
+                + " " + numbersUSLocal
+                + " " + numbersIntl);
+
+        // phonenumber linkify is locale-dependent
+        if (Locale.US.equals(Locale.getDefault())) {
+            assertTrue(Linkify.addLinks(spannable, Linkify.PHONE_NUMBERS));
+            URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
+            assertEquals(9, spans.length);
+            assertEquals("tel:8121234562", spans[0].getURL());
+            assertEquals("tel:8121234563", spans[1].getURL());
+            assertEquals("tel:8005551210", spans[2].getURL());
+            assertEquals("tel:8005551211", spans[3].getURL());
+            assertEquals("tel:5551212", spans[4].getURL());
+            assertEquals("tel:+4408121234564", spans[5].getURL());
+            assertEquals("tel:+4408121234565", spans[6].getURL());
+            assertEquals("tel:+18005551213", spans[7].getURL());
+            assertEquals("tel:+18005551214", spans[8].getURL());
+        }
+
+        try {
+            Linkify.addLinks((Spannable) null, Linkify.WEB_URLS);
+            fail("Should throw NullPointerException!");
+        } catch (NullPointerException e) {
+            // expect
+        }
+
+        assertFalse(Linkify.addLinks((Spannable) null, 0));
+    }
 }
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 404f5de..fe364bc 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
@@ -109,7 +109,6 @@
         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);
@@ -124,7 +123,6 @@
         // LTR / relative margin case
         mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
         vg.setLayoutParams(mMarginLayoutParams);
-        vg.requestLayout();
 
         assertEquals(20, mMarginLayoutParams.getMarginStart());
         assertEquals(30, mMarginLayoutParams.topMargin);
@@ -142,7 +140,6 @@
         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);
@@ -157,7 +154,6 @@
         // RTL / relative margin case
         mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
         vg.setLayoutParams(mMarginLayoutParams);
-        vg.requestLayout();
 
         assertEquals(20, mMarginLayoutParams.getMarginStart());
         assertEquals(30, mMarginLayoutParams.topMargin);
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 888bb73..0af3f21 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -247,10 +247,11 @@
         Rect rect = new Rect();
         final Button button = new Button(mActivity);
         final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT;
+        final int btnHeight = view.getHeight()/3;
         runTestOnUiThread(new Runnable() {
             public void run() {
                 mActivity.addContentView(button,
-                        new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
+                        new LinearLayout.LayoutParams(WRAP_CONTENT, btnHeight));
             }
         });
         getInstrumentation().waitForIdleSync();
diff --git a/tools/tradefed-host/Android.mk b/tools/tradefed-host/Android.mk
index e8965ab..4a9e2fc 100644
--- a/tools/tradefed-host/Android.mk
+++ b/tools/tradefed-host/Android.mk
@@ -16,7 +16,8 @@
 
 include $(CLEAR_VARS)
 
-# Only compile source java files in this lib.
+# suite/pts/hostTests/ptshostutil is treated specially
+# as it cannot be put into ptscommonutilhost due to dependency on cts-tradefed
 LOCAL_SRC_FILES := \
 	$(call all-java-files-under, src) \
 	$(call all-java-files-under, ../../suite/pts/hostTests/ptshostutil/src)
diff --git a/tools/tradefed-host/res/report/cts_result.xsl b/tools/tradefed-host/res/report/cts_result.xsl
index b924d2f..0c38be1 100644
--- a/tools/tradefed-host/res/report/cts_result.xsl
+++ b/tools/tradefed-host/res/report/cts_result.xsl
@@ -526,11 +526,6 @@
                                                             <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/CtsBuildProvider.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
index 942f1b1..e91595b 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.2_r3";
+    public static final String CTS_BUILD_VERSION = "4.2_r4";
 
     /**
      * {@inheritDoc}
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 2f62d71..9517d8e 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
@@ -99,9 +99,8 @@
     private File mLogDir;
     private String mSuiteName;
 
-    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(.*)\\+\\+\\+\\+(.*)");
+    private static final Pattern mPtsLogPattern = Pattern.compile("(.*)\\+\\+\\+\\+(.*)");
+
     public void setReportDir(File reportDir) {
         mReportDir = reportDir;
     }
@@ -226,21 +225,7 @@
      */
     @Override
     public void testFailed(TestFailure status, TestIdentifier test, String 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);
-        }
+        mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
     }
 
     /**
@@ -248,6 +233,7 @@
      */
     @Override
     public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {
+        collectPtsResults(test, testMetrics);
         mCurrentPkgResult.reportTestEnded(test);
         Test result = mCurrentPkgResult.findTest(test);
         String stack = result.getStackTrace() == null ? "" : "\n" + result.getStackTrace();
@@ -256,6 +242,31 @@
     }
 
     /**
+     * Collect Pts results for both device and host tests to the package result.
+     * @param test test ran
+     * @param testMetrics test metrics which can contain performance result for device tests
+     */
+    private void collectPtsResults(TestIdentifier test, Map<String, String> testMetrics) {
+        // device test can have performance results in testMetrics
+        String perfResult = PtsReportUtil.getPtsResultFromMetrics(testMetrics);
+        // host test should be checked in PtsHostStore.
+        if (perfResult == null) {
+            perfResult = PtsHostStore.removePtsResult(mDeviceSerial, test);
+        }
+        if (perfResult != null) {
+            // PTS result is passed in Summary++++Details format.
+            // Extract Summary and Details, and pass them.
+            Matcher m = mPtsLogPattern.matcher(perfResult);
+            if (m.find()) {
+                mCurrentPkgResult.reportPerformanceResult(test, CtsTestStatus.PASS, m.group(1),
+                        m.group(2));
+            } else {
+                logResult("PTS Result unrecognizable:" + perfResult);
+            }
+        }
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/PtsHostStore.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/PtsHostStore.java
new file mode 100644
index 0000000..5944c66
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/PtsHostStore.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.tradefed.result;
+
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.device.ITestDevice;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Utility class for storing Pts Results.
+ * This is necessary for host tests where test metrics cannot be passed.
+ */
+public class PtsHostStore {
+
+    // needs concurrent verion as there can be multiple client accessing this.
+    // But there is no additional protection for the same key as that should not happen.
+    private static final ConcurrentHashMap<String, String> mMap =
+            new ConcurrentHashMap<String, String>();
+
+    /**
+     * Stores PTS result. Existing result with the same key will be replaced.
+     * Note that key is generated in the form of device_serial#class#method name.
+     * So there should be no concurrent test for the same (serial, class, method).
+     * @param device
+     * @param test
+     * @param result PTS result string
+     */
+    public static void storePtsResult(String deviceSerial, String classMethodName, String result) {
+        mMap.put(generateTestKey(deviceSerial, classMethodName), result);
+    }
+
+    /**
+     * retrieves a PTS result for the given condition and remove it from the internal
+     * storage. If there is no result for the given condition, it will return null.
+     */
+    public static String removePtsResult(String deviceSerial, TestIdentifier test) {
+        return mMap.remove(generateTestKey(deviceSerial, test));
+    }
+
+    /**
+     * return test key in the form of device_serial#class_name#method_name
+     */
+    private static String generateTestKey(String deviceSerial, TestIdentifier test) {
+        return String.format("%s#%s", deviceSerial, test.toString());
+
+    }
+
+    /**
+     * return test key in the form of device_serial#class_name#method_name
+     */
+    private static String generateTestKey(String deviceSerial, String classMethodName) {
+        return String.format("%s#%s", deviceSerial, classMethodName);
+
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/PtsReportUtil.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/PtsReportUtil.java
new file mode 100644
index 0000000..2e3dab1
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/PtsReportUtil.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.tradefed.result;
+
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.device.ITestDevice;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Static utility class for handling Pts Results.
+ */
+public class PtsReportUtil {
+    private static final String PTS_RESULT_KEY = "PTS_RESULT";
+
+    /**
+     * Utility method to extract PTS result from test metrics
+     * @param testMetrics
+     * @return result or null if not found
+     */
+    public static String getPtsResultFromMetrics(Map<String, String> testMetrics) {
+        for (Map.Entry<String, String> entry: testMetrics.entrySet()) {
+            if (PTS_RESULT_KEY.equals(entry.getKey())) {
+                return entry.getValue();
+            }
+        }
+        return null;
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index 9188dca..27f7c21 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -493,6 +493,9 @@
                 "CtsViewTestCases",
                 "CtsWidgetTestCases" );
         long intervalInMSec = mRebootIntervalMin * 60 * 1000;
+        if (mDevice.getSerialNumber().startsWith("emulator-")) {
+            return;
+        }
         if (!mDisableReboot) {
             long currentTime = System.currentTimeMillis();
             if (((currentTime - mPrevRebootTime) > intervalInMSec) ||
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 3cb986f..95d60ac 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -143,6 +143,7 @@
 
     # hard-coded white list for PDK plan
     plan.Exclude('.*')
+    plan.Include('android\.aadb')
     plan.Include('android\.bluetooth')
     plan.Include('android\.graphics.*')
     plan.Include('android\.hardware')