Merge "Add CTS tests for VP9 decoder."
diff --git a/CtsCoverage.mk b/CtsCoverage.mk
index 8d67a99..8e5d2af 100644
--- a/CtsCoverage.mk
+++ b/CtsCoverage.mk
@@ -35,19 +35,28 @@
 cts-verifier-coverage-report := $(coverage_out)/verifier-coverage.html
 cts-combined-coverage-report := $(coverage_out)/combined-coverage.html
 
-cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description) $(ACP)
+cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description)
 
-$(cts-test-coverage-report) : $(CTS_COVERAGE_TEST_CASE_LIST) $(cts_api_coverage_dependencies)
+cts_coverage_test_cases_dependencies := $(foreach c, $(CTS_COVERAGE_TEST_CASE_LIST), $(call intermediates-dir-for,APPS,$(c))/package.apk)
+$(cts-test-coverage-report) : PRIVATE_TEST_CASES_APKS := $(cts_coverage_test_cases_dependencies)
+$(cts-test-coverage-report) : $(cts_coverage_test_cases_dependencies) $(cts_api_coverage_dependencies) | $(ACP)
 	$(call generate-coverage-report,"CTS Tests API Coverage Report",\
-			$(CTS_COVERAGE_TEST_CASE_LIST),cts-test-apks,html,test-coverage.html)
+			$(PRIVATE_TEST_CASES_APKS),html,test-coverage.html)
 
-$(cts-verifier-coverage-report) : CtsVerifier $(cts_api_coverage_dependencies)
+cts_coverage_test_cases_dependencies := $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk
+$(cts-test-coverage-report) : PRIVATE_TEST_CASES_APKS := $(cts_coverage_test_cases_dependencies)
+$(cts-verifier-coverage-report) : $(cts_coverage_test_cases_dependencies) $(cts_api_coverage_dependencies) | $(ACP)
 	$(call generate-coverage-report,"CTS Verifier API Coverage Report",\
-			CtsVerifier,cts-verifier-apks,html,verifier-coverage.html)
+			$(PRIVATE_TEST_CASES_APKS),html,verifier-coverage.html)
 
-$(cts-combined-coverage-report) : CtsVerifier $(cts_api_coverage_dependencies) $(CTS_COVERAGE_TEST_CASE_LIST) $(cts_api_coverage_dependencies)
+cts_coverage_test_cases_dependencies := $(foreach c, $(CTS_COVERAGE_TEST_CASE_LIST) CtsVerifier, $(call intermediates-dir-for,APPS,$(c))/package.apk)
+$(cts-test-coverage-report) : PRIVATE_TEST_CASES_APKS := $(cts_coverage_test_cases_dependencies)
+$(cts-combined-coverage-report) : $(cts_coverage_test_cases_dependencies) $(cts_api_coverage_dependencies) | $(ACP)
 	$(call generate-coverage-report,"CTS Combined API Coverage Report",\
-			$(CTS_COVERAGE_TEST_CASE_LIST) CtsVerifier,cts-combined-apks,html,combined-coverage.html)
+			$(PRIVATE_TEST_CASES_APKS),html,combined-coverage.html)
+
+cts_api_coverage_dependencies :=
+cts_coverage_test_cases_dependencies :=
 
 .PHONY: cts-test-coverage
 cts-test-coverage : $(cts-test-coverage-report)
@@ -67,19 +76,11 @@
 
 # Arguments;
 #  1 - Name of the report printed out on the screen
-#  2 - Name of APK packages that will be scanned to generate the report
-#  3 - Name of variable to hold the calculated paths of the APKs
-#  4 - Format of the report
-#  5 - Output file name of the report
+#  2 - List of apk files that will be scanned to generate the report
+#  3 - Format of the report
+#  4 - Output file name of the report
 define generate-coverage-report
-	$(foreach testcase,$(2),$(eval $(call add-testcase-apk,$(3),$(testcase))))
 	$(hide) mkdir -p $(coverage_out)
-	$(hide) $(cts_api_coverage_exe) -d $(dexdeps_exe) -a $(api_xml_description) -f $(4) -o $(coverage_out)/$(5) $($(3))
-	$(hide) echo $(1): file://$(ANDROID_BUILD_TOP)/$(coverage_out)/$(5)
-endef
-
-# classes.dex is stripped from package.apk if dex-preopt is enabled,
-# so we use the copy that definitely includes classes.dex.
-define add-testcase-apk
-	$(1) += $(call intermediates-dir-for,APPS,$(2))/package.apk.unaligned
+	$(hide) $(cts_api_coverage_exe) -d $(dexdeps_exe) -a $(api_xml_description) -f $(3) -o $(coverage_out)/$(4) $(2)
+	@ echo $(1): file://$(ANDROID_BUILD_TOP)/$(coverage_out)/$(4)
 endef
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 4b7229d..cdb9e9d 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -132,7 +132,8 @@
 CTS_TEST_CASES := $(call cts-get-lib-paths,$(cts_host_libraries)) \
 		$(call cts-get-package-paths,$(cts_test_packages)) \
 		$(call cts-get-native-paths,$(cts_native_exes)) \
-		$(call cts-get-ui-lib-paths,$(cts_ui_tests))
+		$(call cts-get-ui-lib-paths,$(cts_ui_tests)) \
+		$(call cts-get-ui-lib-paths,$(pts_device_lib_tests))
 
 # All the XMLs that will end up under the repository/testcases
 # and that need to be created before making the final CTS distribution.
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index 3b1674e..834320b 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -32,6 +32,8 @@
 
 LOCAL_SDK_VERSION := current
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
 
 # Builds and launches CTS Verifier on a device.
diff --git a/suite/audio_quality/Android.mk b/suite/audio_quality/Android.mk
index 21d8fb8..65abd23 100644
--- a/suite/audio_quality/Android.mk
+++ b/suite/audio_quality/Android.mk
@@ -22,18 +22,24 @@
 CTS_AUDIO_INSTALL_DIR := $(HOST_OUT)/cts-audio-quality/android-cts-audio-quality
 CTS_AUDIO_QUALITY_ZIP := $(HOST_OUT)/cts-audio-quality/android-cts-audio-quality.zip
 
-$(CTS_AUDIO_QUALITY_ZIP): cts_audio_quality_test cts_audio_quality \
-  CtsAudioClient $(CTS_AUDIO_TOP)/test_description
-	$(hide) mkdir -p $(CTS_AUDIO_INSTALL_DIR)
+cts_audio_quality_client_apk := $(TARGET_OUT_DATA_APPS)/CtsAudioClient.apk
+cts_audio_quality_host_bins := $(HOST_OUT)/bin/cts_audio_quality_test $(HOST_OUT)/bin/cts_audio_quality
+$(CTS_AUDIO_QUALITY_ZIP): PRIVATE_CLIENT_APK := $(cts_audio_quality_client_apk)
+$(CTS_AUDIO_QUALITY_ZIP): PRIVATE_HOST_BINS := $(cts_audio_quality_host_bins)
+$(CTS_AUDIO_QUALITY_ZIP): PRIVATE_TEST_DESC := $(CTS_AUDIO_TOP)/test_description
+$(CTS_AUDIO_QUALITY_ZIP): $(cts_audio_quality_client_apk) $(cts_audio_quality_host_bins) \
+    $(CTS_AUDIO_TOP)/test_description | $(ACP)
 	$(hide) mkdir -p $(CTS_AUDIO_INSTALL_DIR)/client
-	$(hide) $(ACP) -fp $(PRODUCT_OUT)/data/app/CtsAudioClient.apk \
+	$(hide) $(ACP) -fp $(PRIVATE_CLIENT_APK) \
         $(CTS_AUDIO_INSTALL_DIR)/client
-	$(hide) $(ACP) -fp $(HOST_OUT)/bin/cts_audio_quality_test $(CTS_AUDIO_INSTALL_DIR)
-	$(hide) $(ACP) -fp $(HOST_OUT)/bin/cts_audio_quality $(CTS_AUDIO_INSTALL_DIR)
-	$(hide) $(ACP) -fr $(CTS_AUDIO_TOP)/test_description $(CTS_AUDIO_INSTALL_DIR)
+	$(hide) $(ACP) -fp $(PRIVATE_HOST_BINS) $(CTS_AUDIO_INSTALL_DIR)
+	$(hide) $(ACP) -fr $(PRIVATE_TEST_DESC) $(CTS_AUDIO_INSTALL_DIR)
 	$(hide) echo "Package cts_audio: $@"
-	$(hide) cd $(HOST_OUT)/cts-audio-quality && \
-        zip -rq android-cts-audio-quality.zip android-cts-audio-quality -x android-cts-audio-quality/reports/\*
+	$(hide) cd $(dir $@) && \
+        zip -rq $(notdir $@) android-cts-audio-quality -x android-cts-audio-quality/reports/\*
+
+cts_audio_quality_client_apk :=
+cts_audio_quality_host_bins :=
 
 # target to build only this package
 .PHONY: cts_audio_quality_package
diff --git a/suite/audio_quality/client/Android.mk b/suite/audio_quality/client/Android.mk
index 090c758..6d60541 100644
--- a/suite/audio_quality/client/Android.mk
+++ b/suite/audio_quality/client/Android.mk
@@ -30,4 +30,6 @@
 # intentional to keep compatibility with ICS
 LOCAL_SDK_VERSION := 15
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/suite/pts/PtsBenchmarkingList.mk b/suite/pts/PtsBenchmarkingList.mk
index ab79bca..4a59c4f 100644
--- a/suite/pts/PtsBenchmarkingList.mk
+++ b/suite/pts/PtsBenchmarkingList.mk
@@ -30,9 +30,12 @@
     PtsDeviceTaskswitchingAppA \
     PtsDeviceTaskswitchingAppB \
     PtsDeviceTaskswitchingControl \
-    PtsDeviceJankApp
+    PtsDeviceOpenGl
 
 PTS_HOST_CASES := \
     PtsHostBootup \
     PtsHostUi \
-    PtsHostJank
+    PtsHostJankOpenGl
+
+pts_device_lib_tests := \
+    PtsDeviceJankOpenGl
\ No newline at end of file
diff --git a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveActivity.java b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveActivity.java
index 377e851..ac5222c 100644
--- a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveActivity.java
+++ b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveActivity.java
@@ -51,8 +51,8 @@
         super.onCreate(data);
         System.loadLibrary("ptsopengl_jni");
         Intent intent = getIntent();
-        mBenchmark = BenchmarkName.valueOf(intent.getStringExtra(
-                GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME));
+        mBenchmark = BenchmarkName.valueOf(
+                intent.getStringExtra(GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME));
         mOffscreen = intent.getBooleanExtra(GLActivityIntentKeys.INTENT_EXTRA_OFFSCREEN, false);
         mNumFrames = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 0);
         mNumIterations = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_ITERATIONS, 0);
@@ -96,6 +96,7 @@
     private void complete() {
         // Release semiphore.
         mSemaphore.release();
+        finish();
     }
 
     private synchronized void setException(Exception e) {
@@ -135,6 +136,7 @@
                 complete();
                 return;
             }
+            Log.i(TAG, mBenchmark + " Benchmark Started");
             // Creates a watchdog to ensure a iteration doesn't exceed the timeout.
             watchDog = new WatchDog(mTimeout, this);
             // Used to record the start and end time of the iteration.
@@ -170,6 +172,7 @@
                 }
             }
             complete();
+            Log.i(TAG, mBenchmark + " Benchmark Completed");
         }
 
         public void onTimeout() {
diff --git a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveBenchmark.java b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveBenchmark.java
index 1f40c7a..6180dd0 100644
--- a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveBenchmark.java
+++ b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/primitive/GLPrimitiveBenchmark.java
@@ -141,7 +141,6 @@
                 getReportLog().printSummary(
                         "Average Frames Per Second", score, ResultType.HIGHER_BETTER,
                         ResultUnit.SCORE);
-                activity.finish();
             }
         }
     }
diff --git a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceActivity.java b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceActivity.java
index c7fa7b9..09f97c5 100644
--- a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceActivity.java
+++ b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceActivity.java
@@ -66,6 +66,7 @@
             }
             // Release semiphore.
             mSemaphore.release();
+            finish();
         }
     }
 
diff --git a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceBenchmark.java b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceBenchmark.java
index 6aebab8..0f5afc3 100644
--- a/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceBenchmark.java
+++ b/suite/pts/deviceTests/opengl/src/com/android/pts/opengl/reference/GLReferenceBenchmark.java
@@ -95,7 +95,6 @@
                 getReportLog().printSummary(
                         "Total Time", totalTime, ResultType.LOWER_BETTER, ResultUnit.MS);
                  */
-                activity.finish();
             }
         }
     }
diff --git a/suite/pts/hostTests/jank/Android.mk b/suite/pts/hostTests/jank/Android.mk
index efd0bd8..1d5346c 100644
--- a/suite/pts/hostTests/jank/Android.mk
+++ b/suite/pts/hostTests/jank/Android.mk
@@ -20,13 +20,22 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_MODULE := PtsHostJank
+LOCAL_MODULE := PtsHostJankOpenGl
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt ddmlib-prebuilt ptscommonutilhost
 
-LOCAL_CTS_TEST_PACKAGE := com.android.pts.jank
+LOCAL_CTS_TEST_PACKAGE := com.android.pts.jank.opengl
+
+LOCAL_DEVICE_JAR_ := PtsDeviceJankOpenGl
+cts_library_jar_ := $(CTS_TESTCASES_OUT)/$(LOCAL_DEVICE_JAR_).jar
+
+$(cts_library_jar_): $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_DEVICE_JAR_))/javalib.jar | $(ACP)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(hide) $(ACP) -fp $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_DEVICE_JAR_))/javalib.jar $@
+
+$(CTS_TESTCASES_OUT)/PtsHostJankOpenGl.xml: $(cts_library_jar_)
 
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
-# Build the test APK using its own makefile, and any other CTS-related packages
-include $(call all-makefiles-under,$(LOCAL_PATH))
+# Build the library using its own makefile
+include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/suite/pts/hostTests/jank/app/Android.mk b/suite/pts/hostTests/jank/app/Android.mk
index 5ef1a92..81f5f73 100644
--- a/suite/pts/hostTests/jank/app/Android.mk
+++ b/suite/pts/hostTests/jank/app/Android.mk
@@ -13,32 +13,16 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_STATIC_JAVA_LIBRARIES := ptsutil ctsutil ctstestrunner
-
-LOCAL_JNI_SHARED_LIBRARIES := libptsopengl_jni
-
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
-# add the src of the benchmark, but filter out the tests
-BENCHMARK_SRC := $(call all-java-files-under, ../../../deviceTests/opengl/src)
-LOCAL_SRC_FILES += $(filter-out %Benchmark.java, $(BENCHMARK_SRC))
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := PtsDeviceJankOpenGl
+LOCAL_DEX_PREOPT := false
 
-#$(info $(LOCAL_SRC_FILES))
+LOCAL_JAVA_LIBRARIES := uiautomator.core
 
-LOCAL_ASSET_DIR := $(LOCAL_PATH)/../../../deviceTests/opengl/assets
+LOCAL_STATIC_JAVA_LIBRARIES := com.android.uiautomator.platform.common
 
-LOCAL_PACKAGE_NAME := PtsDeviceJankApp
-
-LOCAL_SDK_VERSION := 16
-
-include $(BUILD_CTS_PACKAGE)
-
-
+include $(BUILD_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/suite/pts/hostTests/jank/app/AndroidManifest.xml b/suite/pts/hostTests/jank/app/AndroidManifest.xml
deleted file mode 100644
index 8c2e577..0000000
--- a/suite/pts/hostTests/jank/app/AndroidManifest.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.pts.jank" >
-
-    <uses-feature
-        android:glEsVersion="0x00020000"
-        android:required="true" />
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-        <activity
-            android:name="com.android.pts.opengl.primitive.GLPrimitiveActivity"
-            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
-            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-
-    <instrumentation
-        android:name="android.test.InstrumentationCtsTestRunner"
-        android:label="Jank Test"
-        android:targetPackage="com.android.pts.jank" />
-
-</manifest>
\ No newline at end of file
diff --git a/suite/pts/hostTests/jank/app/src/com/android/pts/jank/JankTest.java b/suite/pts/hostTests/jank/app/src/com/android/pts/jank/JankTest.java
deleted file mode 100644
index 84caa63..0000000
--- a/suite/pts/hostTests/jank/app/src/com/android/pts/jank/JankTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.jank;
-
-import com.android.pts.opengl.GLActivityIntentKeys;
-import com.android.pts.opengl.primitive.BenchmarkName;
-import com.android.pts.opengl.primitive.GLPrimitiveActivity;
-import com.android.pts.util.PtsActivityInstrumentationTestCase2;
-
-import android.content.Intent;
-
-public class JankTest extends PtsActivityInstrumentationTestCase2<GLPrimitiveActivity> {
-
-    public JankTest() {
-        super(GLPrimitiveActivity.class);
-    }
-
-    /**
-     * Runs the full OpenGL ES 2.0 pipeline test.
-     */
-    public void testFullPipeline() throws Exception {
-        runBenchmark(BenchmarkName.FullPipeline);
-    }
-
-    /**
-     * Runs the pixel output test.
-     */
-    public void testPixelOutput() throws Exception {
-        runBenchmark(BenchmarkName.PixelOutput);
-    }
-
-    /**
-     * Runs the shader performance test.
-     */
-    public void testShaderPerf() throws Exception {
-        runBenchmark(BenchmarkName.ShaderPerf);
-    }
-
-    /**
-     * Runs the context switch overhead test.
-     */
-    public void testContextSwitch() throws Exception {
-        runBenchmark(BenchmarkName.ContextSwitch);
-    }
-
-    /**
-     * Runs the benchhmark for jank test.
-     */
-    public void runBenchmark(BenchmarkName benchmark) throws Exception {
-        Intent intent = new Intent();
-        String benchmarkName = benchmark.toString();
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME, benchmarkName);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_OFFSCREEN, false);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 200);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_ITERATIONS, 1);
-        intent.putExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, 50000);
-        GLPrimitiveActivity activity = null;
-        setActivityIntent(intent);
-        try {
-            activity = getActivity();
-            activity.waitForCompletion();
-        } finally {
-            if (activity != null) {
-                activity.finish();
-            }
-        }
-    }
-}
diff --git a/suite/pts/hostTests/jank/app/src/com/android/pts/jank/opengl/PtsDeviceJankOpenGl.java b/suite/pts/hostTests/jank/app/src/com/android/pts/jank/opengl/PtsDeviceJankOpenGl.java
new file mode 100644
index 0000000..259649c
--- /dev/null
+++ b/suite/pts/hostTests/jank/app/src/com/android/pts/jank/opengl/PtsDeviceJankOpenGl.java
@@ -0,0 +1,185 @@
+/*
+ * 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.jank.opengl;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.uiautomator.platform.JankTestBase;
+import com.android.uiautomator.platform.SurfaceFlingerHelper;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Scanner;
+import java.util.concurrent.Semaphore;
+
+public class PtsDeviceJankOpenGl extends JankTestBase {
+    private final static String TAG = "JankTest";
+    private final static String PACKAGE = "com.android.pts.opengl";
+    private final static String COMPONENT =
+            PACKAGE + "/" + PACKAGE + ".primitive.GLPrimitiveActivity";
+    private final static String START_CMD = "am start -W -a android.intent.action.MAIN -n %s";
+    private final static String STOP_CMD = "am force-stop %s";
+    private final static String INTENT_STRING_EXTRA = " --es %s %s";
+    private final static String INTENT_BOOLEAN_EXTRA = " --ez %s %b";
+    private final static String INTENT_INTEGER_EXTRA = " --ei %s %d";
+    private static String APP_WINDOW_NAME = "SurfaceView";
+    private static long SLEEP_TIME = 2000; // 2 seconds
+    private static int NUM_ITERATIONS = 5;
+    private static int TRACE_TIME = 5;
+
+    @Override
+    protected String getPropertyString(Bundle params, String key)
+            throws FileNotFoundException, IOException {
+        if (key.equals("iteration")) {
+            return NUM_ITERATIONS + "";
+        }
+        if (key.equals("tracetime")) {
+            return TRACE_TIME + "";
+        }
+        return super.getPropertyString(params, key);
+    }
+
+    /**
+     * Runs the full OpenGL ES 2.0 pipeline test.
+     */
+    public void testFullPipeline() throws Exception {
+        runBenchmark("FullPipeline");
+    }
+
+    /**
+     * Runs the pixel output test.
+     */
+    public void testPixelOutput() throws Exception {
+        runBenchmark("PixelOutput");
+    }
+
+    /**
+     * Runs the shader performance test.
+     */
+    public void testShaderPerf() throws Exception {
+        runBenchmark("ShaderPerf");
+    }
+
+    /**
+     * Runs the context switch overhead test.
+     */
+    public void testContextSwitch() throws Exception {
+        runBenchmark("ContextSwitch");
+    }
+
+    /**
+     * Runs the benchhmark for jank test.
+     */
+    public void runBenchmark(String benchmark) throws Exception {
+        // Start activity command
+        final StringBuilder sb = new StringBuilder();
+        sb.append(String.format(START_CMD, COMPONENT));
+        sb.append(String.format(INTENT_STRING_EXTRA, "benchmark_name", benchmark));
+        sb.append(String.format(INTENT_BOOLEAN_EXTRA, "offscreen", false));
+        sb.append(String.format(INTENT_INTEGER_EXTRA, "num_frames", 200));
+        sb.append(String.format(INTENT_INTEGER_EXTRA, "num_iterations", 1));
+        sb.append(String.format(INTENT_INTEGER_EXTRA, "timeout", 10000));
+        final String startCommand = sb.toString();
+        final String stopCommand = String.format(STOP_CMD, PACKAGE);
+
+        Log.i(TAG, "Start command: " + startCommand);
+        Log.i(TAG, "Stop command: " + stopCommand);
+
+        setIteration(NUM_ITERATIONS);
+        for (int i = 0; i < NUM_ITERATIONS; i++) {
+            // Stop any existing instances
+            runShellCommand(stopCommand);
+            // Start activity
+            runShellCommand(startCommand);
+
+            // Start systrace
+            // TODO(jgennis): Systrace has been commented out because of read-tgid permission error
+            // startTrace(mTestCaseName, i);
+
+            // Clear SurfaceFlinger buffer
+            Log.i(TAG, "Clearing SurfaceFlinger buffer");
+            SurfaceFlingerHelper.clearBuffer(APP_WINDOW_NAME);
+
+            // This is where user interactions would go, in this case just sleep
+            sleep(SLEEP_TIME);
+
+            // Dump SurfaceFlinger buffer
+            Log.i(TAG, "Dumping SurfaceFlinger buffer");
+            boolean result = SurfaceFlingerHelper.dumpFrameLatency(APP_WINDOW_NAME, true);
+            assertTrue("SurfaceFlingerHelper could not get timestamps", result);
+
+            // Stop systrace
+            // endTrace();
+
+            // Record results
+            recordResults(mTestCaseName, i);
+        }
+        // Save aggregated results
+        saveResults(mTestCaseName);
+        // Stop any remaining instances
+        runShellCommand(stopCommand);
+    }
+
+    private void runShellCommand(String command) throws Exception {
+        Process p = null;
+        Scanner out = null;
+        Scanner err = null;
+        try {
+            p = Runtime.getRuntime().exec(command);
+
+            StringBuilder outStr = new StringBuilder();
+            StringBuilder errStr = new StringBuilder();
+            out = new Scanner(p.getInputStream());
+            err = new Scanner(p.getErrorStream());
+            boolean read = true;
+            while (read) {
+                if (out.hasNextLine()) {
+                    outStr.append(out.nextLine());
+                    outStr.append("\n");
+                } else if (err.hasNextLine()) {
+                    errStr.append(err.nextLine());
+                    errStr.append("\n");
+                } else {
+                    read = false;
+                }
+            }
+            Log.i(TAG, command);
+            if (outStr.length() > 0) {
+                Log.i(TAG, outStr.toString());
+            }
+            if (errStr.length() > 0) {
+                Log.e(TAG, errStr.toString());
+            }
+        } finally {
+            if (p != null) {
+                int status = p.waitFor();
+                if (status != 0) {
+                    throw new RuntimeException(
+                            String.format("Run shell command: %s, status: %s", command, status));
+                }
+                p.destroy();
+                p = null;
+            }
+            if (out != null) {
+                out.close();
+            }
+            if (err != null) {
+                err.close();
+            }
+        }
+    }
+
+}
diff --git a/suite/pts/hostTests/jank/src/com/android/pts/jank/PtsHostJankTest.java b/suite/pts/hostTests/jank/src/com/android/pts/jank/PtsHostJankTest.java
index 85a8f5e..1264786 100644
--- a/suite/pts/hostTests/jank/src/com/android/pts/jank/PtsHostJankTest.java
+++ b/suite/pts/hostTests/jank/src/com/android/pts/jank/PtsHostJankTest.java
@@ -15,6 +15,7 @@
 
 import com.android.cts.tradefed.build.CtsBuildHelper;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.IShellOutputReceiver;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.pts.util.HostReportLog;
@@ -34,30 +35,27 @@
 import java.io.InputStreamReader;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
+import java.util.HashMap;
+import java.util.Scanner;
 
 public class PtsHostJankTest extends DeviceTestCase implements IBuildReceiver {
 
     private static final String TAG = "PtsHostJankTest";
-    private static final String CTS_RUNNER = "android.test.InstrumentationCtsTestRunner";
-    private static final String APP_WINDOW_NAME = "SurfaceView";
-    private static final String PACKAGE = "com.android.pts.jank";
-    private static final String APK = "PtsDeviceJankApp.apk";
-    private static final String CLEAR_BUFFER_CMD =
-            "adb -s %s shell dumpsys SurfaceFlinger --latency-clear %s";
-    private static final String FRAME_LATENCY_CMD =
-            "adb -s %s shell dumpsys SurfaceFlinger --latency %s";
-    private static final long PENDING_FENCE_TIMESTAMP = (1L << 63) - 1;
-    private static final double MILLISECOND = 1E3;
-    private static final int REQ_NUM_DELTAS = 100;
+    private static final String DEVICE_LOCATION = "/data/local/tmp/";
+    private static final String RUN_UI_AUTOMATOR_CMD = "uiautomator runtest %s -c %s";
+    private final String mHostTestClass;
+    private final String mDeviceTestClass;
+    private final String mJarName;
+    private final String mJarPath;
+    protected ITestDevice mDevice;
+    protected CtsBuildHelper mBuild;
 
-    private ArrayList<Double> mTimestamps = new ArrayList<Double>();
-    private double mRefreshPeriod;
-    private volatile int mNumDeltas = 0;
-    private volatile int mJankNumber = 0;
-    private volatile int mTotalJanks = 0;
-    private CtsBuildHelper mBuild;
-    private ITestDevice mDevice;
+    public PtsHostJankTest(String jarName, String deviceTestClass, String hostTestClass) {
+        this.mHostTestClass = hostTestClass;
+        this.mDeviceTestClass = deviceTestClass;
+        this.mJarName = jarName;
+        this.mJarPath = DEVICE_LOCATION + jarName;
+    }
 
     @Override
     public void setBuild(IBuildInfo buildInfo) {
@@ -68,181 +66,78 @@
     protected void setUp() throws Exception {
         super.setUp();
         mDevice = getDevice();
-        mDevice.uninstallPackage(PACKAGE);
-        File app = mBuild.getTestApp(APK);
-        mDevice.installPackage(app, false);
+        // Push jar to device.
+        File jarFile = mBuild.getTestApp(mJarName);
+        boolean result = mDevice.pushFile(jarFile, mJarPath);
+        assertTrue("Failed to push file to " + mJarPath, result);
     }
 
-
     @Override
     protected void tearDown() throws Exception {
-        mDevice.uninstallPackage(PACKAGE);
+        // Delete jar from device.
+        mDevice.executeShellCommand("rm " + mJarPath);
         super.tearDown();
     }
 
-    public void testFullPipeline() throws Exception {
-        runGLPrimitiveBenchmark("testFullPipeline");
-    }
+    public void runUiAutomatorTest(String testName) throws Exception {
+        // Delete any existing result files
+        mDevice.executeShellCommand("rm -r " + DEVICE_LOCATION + "*.txt");
 
-    public void testPixelOutput() throws Exception {
-        runGLPrimitiveBenchmark("testPixelOutput");
-    }
+        // Run ui automator test.
+        mDevice.executeShellCommand(
+                String.format(RUN_UI_AUTOMATOR_CMD, mJarName, mDeviceTestClass + "#" + testName),
+                new IShellOutputReceiver() {
+                    private StringBuilder sb = new StringBuilder();
 
-    public void testShaderPerf() throws Exception {
-        runGLPrimitiveBenchmark("testShaderPerf");
-    }
+                    public void addOutput(byte[] data, int offset, int length) {
+                        byte[] raw = new byte[length];
+                        for (int i = 0; i < length; i++) {
+                            raw[i] = data[i + offset];
+                        }
+                        sb.append(new String(raw));
+                    }
 
-    public void testContextSwitch() throws Exception {
-        runGLPrimitiveBenchmark("testContextSwitch");
-    }
+                    public void flush() {
+                        Log.logAndDisplay(LogLevel.INFO, TAG, sb.toString());
+                    }
 
-    public void runGLPrimitiveBenchmark(String benchmark) throws Exception {
-        // Collect timestamps.
-        final TimestampCollector worker = new TimestampCollector();
-        worker.start();
+                    public boolean isCancelled() {
+                        return false;
+                    }
+                });
 
-        // Start the benchmark.
-        RemoteAndroidTestRunner testRunner =
-                new RemoteAndroidTestRunner(PACKAGE, CTS_RUNNER, mDevice.getIDevice());
-        testRunner.setMethodName("com.android.pts.jank.JankTest", benchmark);
-        CollectingTestListener listener = new CollectingTestListener();
-        mDevice.runInstrumentationTests(testRunner, listener);
-
-        // Wait for the worker.
-        worker.finish();
-
-        TestRunResult result = listener.getCurrentRunResults();
-        if (result.isRunFailure()) {
-            throw new Exception(result.getRunFailureMessage());
+        // Pull result file across
+        File result = mDevice.pullFile(DEVICE_LOCATION + "UiJankinessTestsOutput.txt");
+        assertNotNull("Couldn't get result file", result);
+        // Parse result file
+        Scanner in = new Scanner(result);
+        HashMap<String, Double> results = new HashMap<String, Double>(4);
+        while (in.hasNextLine()) {
+            String[] parts = in.nextLine().split(":");
+            if (parts.length == 2) {
+                results.put(parts[0], Double.parseDouble(parts[1]));
+            }
         }
+        Log.logAndDisplay(LogLevel.INFO, TAG, "Results: " + results);
+        assertEquals("Could not parse the results file: ", 4, results.size());
 
-        assertFalse("Couldn't get enough timestamps", needMoreDeltas());
+        double avgNumJanks = results.get("average number of jankiness");
+        double maxNumJanks = results.get("max number of jankiness");
+        double avgFrameRate = results.get("average frame rate");
+        double avgMaxAccFrames = results.get("average of max accumulated frames");
 
         // Create and deliver the report.
-        HostReportLog report = new HostReportLog(
-                mDevice.getSerialNumber(), PtsHostJankTest.class.getName() + "#" + benchmark);
+        HostReportLog report =
+                new HostReportLog(mDevice.getSerialNumber(), mHostTestClass + "#" + testName);
         report.printValue(
-                "Number of Janks", mJankNumber, ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        report.printValue("Total Janks", mTotalJanks, ResultType.LOWER_BETTER, ResultUnit.COUNT);
-        double jankiness = ((double) mJankNumber / mNumDeltas) * 100.0;
+                "Average Frame Rate", avgFrameRate, ResultType.HIGHER_BETTER, ResultUnit.COUNT);
+        report.printValue("Average of Maximum Accumulated Frames", avgMaxAccFrames,
+                ResultType.LOWER_BETTER, ResultUnit.COUNT);
+        report.printValue(
+                "Maximum Number of Janks", maxNumJanks, ResultType.LOWER_BETTER, ResultUnit.COUNT);
         report.printSummary(
-                "Jankiness Percentage", jankiness, ResultType.LOWER_BETTER, ResultUnit.SCORE);
+                "Average Number of Janks", avgNumJanks, ResultType.LOWER_BETTER, ResultUnit.SCORE);
         report.deliverReportToHost();
     }
 
-    private boolean needMoreDeltas() {
-        return mNumDeltas < REQ_NUM_DELTAS;
-    }
-
-    private void calcJank() {
-        final int numTimestamps = mTimestamps.size();
-        if (numTimestamps > 2) {
-            final int numIntervals = numTimestamps - 1;
-            double[] intervals = new double[numIntervals];
-            for (int i = 0; i < numIntervals; i++) {
-                intervals[i] = mTimestamps.get(i + 1) - mTimestamps.get(i);
-            }
-            final int numDeltas = Math.min(numIntervals - 1, REQ_NUM_DELTAS - mNumDeltas);
-            for (int i = 0; i < numDeltas; i++) {
-                double delta = intervals[i + 1] - intervals[i];
-                double normalizedDelta = delta / mRefreshPeriod;
-                // This makes delay over 1.5 * frameIntervalNomial a jank.
-                // Note that too big delay is not excluded here as there should be no pause.
-                int jankiness = (int) Math.round(Math.max(normalizedDelta, 0.0));
-                if (jankiness > 0) {
-                    mJankNumber++;
-                    Log.i(TAG, "Jank at frame " + (mNumDeltas + i));
-                }
-                mTotalJanks += jankiness;
-            }
-            mNumDeltas += numDeltas;
-        }
-        mTimestamps.clear();
-    }
-
-    private class TimestampCollector extends Thread {
-        private volatile Exception mException = null;
-        private volatile boolean mRunning = true;
-
-        public void run() {
-            try {
-                // Loop because SurfaceFlinger's buffer is small.
-                while (mRunning) {
-                    clearBuffer();
-                    Thread.sleep(2000);
-                    dumpBuffer();
-                    calcJank();
-                    // Keep going till we have enough deltas
-                    mRunning = needMoreDeltas();
-                }
-            } catch (Exception e) {
-                mException = e;
-            }
-        }
-
-        public void finish() throws Exception {
-            mRunning = false;
-            try {
-                join(20000);// Wait 20s for thread to join
-            } catch (InterruptedException e) {
-                // Nobody cares
-            }
-            // If there was an error, throw it.
-            if (mException != null) {
-                throw mException;
-            }
-        }
-    }
-
-    private void clearBuffer() throws Exception {
-        // Clear SurfaceFlinger latency buffer.
-        Process p = null;
-        try {
-            p = runShellCommand(
-                    String.format(CLEAR_BUFFER_CMD, mDevice.getSerialNumber(), APP_WINDOW_NAME));
-        } finally {
-            if (p != null) {
-                p.destroy();
-                p = null;
-            }
-        }
-    }
-
-    private void dumpBuffer() throws Exception {
-        // Dump SurfaceFlinger latency buffer.
-        Process p = null;
-        try {
-            p = runShellCommand(
-                    String.format(FRAME_LATENCY_CMD, mDevice.getSerialNumber(), APP_WINDOW_NAME));
-            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
-            String line = reader.readLine();
-            if (line != null) {
-                mRefreshPeriod = Long.parseLong(line.trim()) / 1e6;// Convert from ns to ms
-                while ((line = reader.readLine()) != null) {
-                    String[] values = line.split("\\s+");
-                    if (values.length == 3) {
-                        long timestamp = Long.parseLong(values[1]);
-                        if (timestamp != PENDING_FENCE_TIMESTAMP && timestamp != 0) {
-                            mTimestamps.add(timestamp / 1e6);// Convert from ns to ms
-                        }
-                    }
-                }
-            }
-        } finally {
-            if (p != null) {
-                p.destroy();
-                p = null;
-            }
-        }
-    }
-
-    private Process runShellCommand(String command) throws Exception {
-        Process p = Runtime.getRuntime().exec(command);
-        int status = p.waitFor();
-        if (status != 0) {
-            throw new RuntimeException(
-                    String.format("Run shell command: %s, status: %s", command, status));
-        }
-        return p;
-    }
 }
diff --git a/suite/pts/hostTests/jank/src/com/android/pts/jank/opengl/PtsHostJankOpenGl.java b/suite/pts/hostTests/jank/src/com/android/pts/jank/opengl/PtsHostJankOpenGl.java
new file mode 100644
index 0000000..aea0b11
--- /dev/null
+++ b/suite/pts/hostTests/jank/src/com/android/pts/jank/opengl/PtsHostJankOpenGl.java
@@ -0,0 +1,66 @@
+/*
+ * 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.jank.opengl;
+
+import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.pts.jank.PtsHostJankTest;
+
+import java.io.File;
+
+public class PtsHostJankOpenGl extends PtsHostJankTest {
+
+    private static final String APK_PACKAGE = "com.android.pts.opengl";
+    private static final String APK = "PtsDeviceOpenGl.apk";
+    private static final String PACKAGE = "com.android.pts.jank.opengl";
+    private static final String HOST_CLASS = PtsHostJankOpenGl.class.getName();
+    private static final String DEVICE_CLASS = PACKAGE + ".PtsDeviceJankOpenGl";
+    private static final String JAR_NAME = "PtsDeviceJankOpenGl.jar";
+
+    public PtsHostJankOpenGl() {
+        super(JAR_NAME, DEVICE_CLASS, HOST_CLASS);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // Install the app.
+        mDevice.uninstallPackage(APK_PACKAGE);
+        File app = mBuild.getTestApp(APK);
+        mDevice.installPackage(app, false);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Uninstall the app.
+        mDevice.uninstallPackage(APK_PACKAGE);
+        super.tearDown();
+    }
+
+    public void testFullPipeline() throws Exception {
+        runUiAutomatorTest("testFullPipeline");
+    }
+
+    public void testPixelOutput() throws Exception {
+        runUiAutomatorTest("testPixelOutput");
+    }
+
+    public void testShaderPerf() throws Exception {
+        runUiAutomatorTest("testShaderPerf");
+    }
+
+    public void testContextSwitch() throws Exception {
+        runUiAutomatorTest("testContextSwitch");
+    }
+}
diff --git a/tests/ProcessTest/Android.mk b/tests/ProcessTest/Android.mk
index ba58e87..4f23fac 100644
--- a/tests/ProcessTest/Android.mk
+++ b/tests/ProcessTest/Android.mk
@@ -28,6 +28,8 @@
 
 LOCAL_PACKAGE_NAME := ProcessTests
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/ProcessTest/NoShareUidApp/Android.mk b/tests/ProcessTest/NoShareUidApp/Android.mk
index 66bf8ce..c57d71d 100644
--- a/tests/ProcessTest/NoShareUidApp/Android.mk
+++ b/tests/ProcessTest/NoShareUidApp/Android.mk
@@ -26,5 +26,6 @@
 LOCAL_PACKAGE_NAME := NoShareUidApp
 
 LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
 
 include $(BUILD_PACKAGE)
diff --git a/tests/ProcessTest/ShareUidApp/Android.mk b/tests/ProcessTest/ShareUidApp/Android.mk
index aeb4661..131f768 100644
--- a/tests/ProcessTest/ShareUidApp/Android.mk
+++ b/tests/ProcessTest/ShareUidApp/Android.mk
@@ -26,5 +26,6 @@
 LOCAL_PACKAGE_NAME := ShareUidApp
 
 LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
 
 include $(BUILD_PACKAGE)
diff --git a/tests/SignatureTest/tests/Android.mk b/tests/SignatureTest/tests/Android.mk
index b458aad..bdd0a90 100644
--- a/tests/SignatureTest/tests/Android.mk
+++ b/tests/SignatureTest/tests/Android.mk
@@ -17,4 +17,6 @@
 
 LOCAL_PROGUARD_FLAGS := -ignorewarnings
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/tests/tests/media/src/android/media/cts/InputSurface.java b/tests/tests/media/src/android/media/cts/InputSurface.java
index 5397295..5d72979 100644
--- a/tests/tests/media/src/android/media/cts/InputSurface.java
+++ b/tests/tests/media/src/android/media/cts/InputSurface.java
@@ -142,6 +142,13 @@
         }
     }
 
+    public void makeUnCurrent() {
+        if (!EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE,
+                EGL14.EGL_NO_CONTEXT)) {
+            throw new RuntimeException("eglMakeCurrent failed");
+        }
+    }
+
     /**
      * Calls eglSwapBuffers.  Use this to "publish" the current frame.
      */
@@ -157,6 +164,24 @@
     }
 
     /**
+     * Queries the surface's width.
+     */
+    public int getWidth() {
+        int[] value = new int[1];
+        EGL14.eglQuerySurface(mEGLDisplay, mEGLSurface, EGL14.EGL_WIDTH, value, 0);
+        return value[0];
+    }
+
+    /**
+     * Queries the surface's height.
+     */
+    public int getHeight() {
+        int[] value = new int[1];
+        EGL14.eglQuerySurface(mEGLDisplay, mEGLSurface, EGL14.EGL_HEIGHT, value, 0);
+        return value[0];
+    }
+
+    /**
      * Sends the presentation time stamp to EGL.  Time is expressed in nanoseconds.
      */
     public void setPresentationTime(long nsecs) {
diff --git a/tests/tests/media/src/android/media/cts/PresentationSyncTest.java b/tests/tests/media/src/android/media/cts/PresentationSyncTest.java
new file mode 100644
index 0000000..2846602
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/PresentationSyncTest.java
@@ -0,0 +1,405 @@
+/*
+ * 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 android.media.cts;
+
+import android.opengl.GLES20;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Trace;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
+import android.view.Choreographer;
+import android.view.SurfaceHolder;
+
+
+/**
+ * Tests synchronized frame presentation.
+ *
+ * SurfaceFlinger allows a "desired presentation time" value to be passed along with buffers of
+ * data.  This exercises that feature.
+ */
+public class PresentationSyncTest extends ActivityInstrumentationTestCase2<MediaStubActivity>
+        implements SurfaceHolder.Callback {
+    private static final String TAG = "RenderSyncTest";
+    private static final boolean VERBOSE = false;           // lots of logging
+    private static final int FRAME_COUNT = 128;             // ~2 sec @ 60fps
+
+    // message values
+    private static final int START_TEST = 0;
+    private static final int END_TEST = 1;
+
+    // width and height of the Surface we're given to draw on
+    private int mWidth;
+    private int mHeight;
+
+    public PresentationSyncTest() {
+        super(MediaStubActivity.class);
+    }
+
+    /**
+     * Tests whether the output frame rate can be limited by the presentation time.
+     * <p>
+     * Generates and displays the same series of images three times.  The first run uses "now"
+     * as the desired presentation time to establish an estimate of the refresh time.  Later
+     * runs set the presentation time to (start_time + frame_number * refresh_time * multiplier),
+     * with the expectation that a multiplier of 2 will cause the animation to render at
+     * half speed.
+     * <p>
+     * This test does not use Choreographer.  The longer the test runs, the farther out of
+     * phase the test will become with respect to the actual vsync timing.
+     * <p>
+     * Setting the presentation time for a frame is most easily done through an EGL extension,
+     * so we render each frame through GL.
+     *
+     * @throws Exception
+     */
+    //@Suppress
+    public void testThroughput() throws Exception {
+        // Get the Surface from the SurfaceView.
+        // TODO: is it safe to assume that it's ready?
+        SurfaceHolder holder = getActivity().getSurfaceHolder();
+        holder.addCallback(this);
+
+        // We use the width/height to render a simple series of patterns.  If we get this
+        // wrong it shouldn't really matter -- some driver optimizations might make things
+        // faster, but it shouldn't affect how long it takes the frame to be displayed.
+        //
+        // We can get this from the View or from the EGLSurface.  We don't have easy direct
+        // access to any of those things, so just ask our InputSurface to get it from EGL,
+        // since that's where we're drawing.
+        //
+        // Note: InputSurface was intended for a different purpose, but it's 99% right for our
+        // needs.  Maybe rename it to "RecordableSurface"?  Or trivially wrap it with a
+        // subclass that suppresses the EGL_RECORDABLE_ANDROID flag?
+        InputSurface output = new InputSurface(holder.getSurface());
+        mWidth = output.getWidth();
+        mHeight = output.getHeight();
+        Log.d(TAG, "Surface w=" + mWidth + " h=" + mHeight);
+        output.makeCurrent();
+
+        // Run a test with no presentation times specified.  Assuming nothing else is
+        // fighting us for resources, all frames should display as quickly as possible,
+        // and we can estimate the refresh rate of the device.
+        long baseTimeNsec = runThroughputTest(output, 0L, -1);
+        long refreshNsec = baseTimeNsec / FRAME_COUNT;
+        Log.i(TAG, "Using " + refreshNsec + "ns as refresh rate");
+
+        // Run tests with times specified, at 1x, 1/2x, and 1/4x speed.
+        runThroughputTest(output, refreshNsec, 1);
+        runThroughputTest(output, refreshNsec, 2);
+        runThroughputTest(output, refreshNsec, 4);
+
+        output.release();
+    }
+
+    /**
+     * Runs the throughput test on the provided surface with the specified time values.
+     * <p>
+     * If mult is -1, the test runs in "training" mode, rendering frames as quickly as
+     * possible.  This can be used to establish a baseline.
+     * <p>
+     * @return the test duration, in nanoseconds
+     */
+    private long runThroughputTest(InputSurface output, long frameTimeNsec, int mult) {
+        Log.d(TAG, "runThroughputTest: " + mult);
+        long startNsec = System.nanoTime();
+        long showNsec = 0;
+
+        if (true) {
+            // Output a frame that creates a "marker" in the --latency output
+            drawFrame(0, mult);
+            output.setPresentationTime(startNsec - 16700000L * 100);
+            Trace.beginSection("TEST BEGIN");
+            output.swapBuffers();
+            Trace.endSection();
+            startNsec = System.nanoTime();
+        }
+
+        for (int frameNum = 0; frameNum < FRAME_COUNT; frameNum++) {
+            if (mult != -1) {
+                showNsec = startNsec + frameNum * frameTimeNsec * mult;
+                //Log.d(TAG, "showNsec=" + showNsec);
+            }
+            drawFrame(frameNum, mult);
+            output.setPresentationTime(showNsec);
+            //Log.d(TAG, "ZZZ des=" + showNsec + " now=" + System.nanoTime());
+            Trace.beginSection("swapbuf " + frameNum);
+            output.swapBuffers();
+            Trace.endSection();
+        }
+
+        long endNsec = System.nanoTime();
+        long actualNsec = endNsec - startNsec;
+
+        if (mult != -1) {
+            // Some variation is inevitable, but we should be within a few percent of expected.
+            long expectedNsec = frameTimeNsec * FRAME_COUNT * mult;
+            long deltaNsec = Math.abs(expectedNsec - actualNsec);
+            double delta = (double) deltaNsec / expectedNsec;
+            if (delta > 0.1) {
+                Log.e(TAG, "mult=" + mult + ": expected=" + expectedNsec +
+                        " actual=" + actualNsec + " p=" + delta);
+                // TODO: fail() instead of Log()
+            } else {
+                Log.d(TAG, "mult=" + mult + ": expected=" + expectedNsec +
+                        " actual=" + actualNsec + " p=" + delta);
+            }
+        }
+        return endNsec - startNsec;
+    }
+
+
+    /**
+     * Exercises the test code, driving it off of Choreographer.  The animation is driven at
+     * full speed, but with rendering requested at a future time.  With each run the distance
+     * into the future is increased.
+     * <p>
+     * Loopers can't be reused once they quit, so it's easiest to create a new thread for
+     * each run.
+     * <p>
+     * (This isn't exactly a test -- it's primarily a way to exercise the code.  Evaluate the
+     * results with "dumpsys SurfaceFlinger --latency SurfaceView" for each multiplier.
+     * The idea is to see frames where the desired-present is as close as possible to the
+     * actual-present, while still minimizing frame-ready.  If we go too far into the future
+     * the BufferQueue will start to back up.)
+     * <p>
+     * @throws Exception
+     */
+    @Suppress
+    public void testChoreographed() throws Throwable {
+        // Get the Surface from the SurfaceView.
+        // TODO: is it safe to assume that it's ready?
+        SurfaceHolder holder = getActivity().getSurfaceHolder();
+        holder.addCallback(this);
+
+        InputSurface output = new InputSurface(holder.getSurface());
+        mWidth = output.getWidth();
+        mHeight = output.getHeight();
+        Log.d(TAG, "Surface w=" + mWidth + " h=" + mHeight);
+
+        for (int i = 1; i < 5; i++) {
+            ChoreographedWrapper.runTest(this, output, i);
+        }
+
+        output.release();
+    }
+
+    /**
+     * Shifts the test to a new thread, so we can manage our own Looper.  Any exception
+     * thrown on the new thread is propagated to the caller.
+     */
+    private static class ChoreographedWrapper implements Runnable {
+        private final PresentationSyncTest mTest;
+        private final InputSurface mOutput;
+        private final int mFrameDelay;
+        private Throwable mThrowable;
+
+        private ChoreographedWrapper(PresentationSyncTest test, InputSurface output,
+                int frameDelay) {
+            mTest = test;
+            mOutput = output;
+            mFrameDelay = frameDelay;
+        }
+
+        @Override
+        public void run() {
+            try {
+                mTest.runChoreographedTest(mOutput, mFrameDelay);
+            } catch (Throwable th) {
+                mThrowable = th;
+            }
+        }
+
+        /** Entry point. */
+        public static void runTest(PresentationSyncTest obj, InputSurface output,
+                int frameDelay) throws Throwable {
+            ChoreographedWrapper wrapper = new ChoreographedWrapper(obj, output, frameDelay);
+            Thread th = new Thread(wrapper, "sync test");
+            th.start();
+            th.join();
+            if (wrapper.mThrowable != null) {
+                throw wrapper.mThrowable;
+            }
+        }
+    }
+
+    /**
+     * Runs the test, driven by callbacks from the Looper we define here.
+     */
+    private void runChoreographedTest(InputSurface output, int frameDelay) {
+        Log.d(TAG, "runChoreographedTest");
+
+        output.makeCurrent();
+        final ChoRunner chore = new ChoRunner(output);
+
+        Looper.prepare();
+        Handler handler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case START_TEST:
+                        Log.d(TAG, "Starting test");
+                        chore.start(this, msg.arg1 /*frameDelay*/);
+                        break;
+                    case END_TEST:
+                        Log.d(TAG, "Ending test");
+                        Looper.myLooper().quitSafely();
+                        break;
+                    default:
+                        Log.d(TAG, "unknown message " + msg.what);
+                        break;
+                }
+            }
+        };
+
+        handler.sendMessage(Message.obtain(handler, START_TEST, frameDelay, 0));
+
+        Log.d(TAG, "looping (frameDelay=" + frameDelay + ")");
+        long startNanos = System.nanoTime();
+        Trace.beginSection("TEST BEGIN fd=" + frameDelay);
+        Looper.loop();
+        Trace.endSection();
+        long durationNanos = System.nanoTime() - startNanos;
+        Log.d(TAG, "loop exiting after " + durationNanos +
+                " (" + durationNanos / FRAME_COUNT + "ns)");
+
+        output.makeUnCurrent();
+    }
+
+
+    private class ChoRunner implements Choreographer.FrameCallback {
+        private final InputSurface mOutput;
+        private int mFrameDelay;
+        private Handler mHandler;
+        private int mCurFrame;
+        private Choreographer mChocho;
+        private long mPrevFrameTimeNanos;
+        private long mFrameDiff;
+
+        public ChoRunner(InputSurface output) {
+            mOutput = output;
+        }
+
+        public void start(Handler handler, int frameDelay) {
+            mHandler = handler;
+            mFrameDelay = frameDelay;
+
+            mCurFrame = 0;
+            mChocho = Choreographer.getInstance();
+            mChocho.postFrameCallback(this);
+        }
+
+        @Override
+        public void doFrame(long frameTimeNanos) {
+            if (mPrevFrameTimeNanos != 0) {
+                // Update our vsync rate guess every frame so that, if we start with a
+                // stutter, we don't carry it for the whole test.
+                assertTrue(frameTimeNanos > mPrevFrameTimeNanos);
+                long prevDiff = frameTimeNanos - mPrevFrameTimeNanos;
+                if (mFrameDiff == 0 || mFrameDiff > prevDiff) {
+                    mFrameDiff = prevDiff;
+                    Log.d(TAG, "refresh rate approx " + mFrameDiff + "ns");
+                }
+
+                // If the current diff is >= 2x the expected frame time diff, we stuttered
+                // and need to drop a frame.  (We might even need to drop more than one
+                // frame; ignoring that for now.)
+                if (prevDiff > mFrameDiff * 1.9) {
+                    Log.d(TAG, "skip " + mCurFrame + " diff=" + prevDiff);
+                    mCurFrame++;
+                }
+            }
+            mPrevFrameTimeNanos = frameTimeNanos;
+
+            if (mFrameDiff != 0) {
+                // set desired display time to N frames in the future, rather than ASAP.
+                //
+                // Note this is a "don't open until Xmas" feature.  If vsyncs are happening
+                // at times T1, T2, T3, and we want the frame to appear onscreen when the
+                // buffers flip at T2, then we can theoretically request any time value
+                // in [T1, T2).
+                mOutput.setPresentationTime(frameTimeNanos + (mFrameDiff * mFrameDelay));
+            }
+
+            drawFrame(mCurFrame, mFrameDelay);
+            Trace.beginSection("swapbuf " + mCurFrame);
+            mOutput.swapBuffers();
+            Trace.endSection();
+
+            if (++mCurFrame < FRAME_COUNT) {
+                mChocho.postFrameCallback(this);
+            } else {
+                mHandler.sendMessage(Message.obtain(mHandler, END_TEST));
+            }
+        }
+    }
+
+    /**
+     * Draws a frame with GLES in the current context.
+     */
+    private void drawFrame(int num, int mult) {
+        num %= 64;
+        float colorVal;
+
+        if (mult > 0) {
+            colorVal = 1.0f / mult;
+        } else {
+            colorVal = 0.1f;
+        }
+
+        int startX, startY;
+        startX = (num % 16) * (mWidth / 16);
+        startY = (num / 16) * (mHeight / 4);
+        if ((num >= 16 && num < 32) || (num >= 48)) {
+            // reverse direction
+            startX = (mWidth - mWidth/16) - startX;
+        }
+
+        // clear screen
+        GLES20.glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
+        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+
+        // draw rect
+        GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
+        GLES20.glScissor(startX, startY, mWidth / 16, mHeight / 4);
+        GLES20.glClearColor(colorVal, 1 - colorVal, 0.0f, 1.0f);
+        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+        GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
+    }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+        Log.d(TAG, "surfaceCreated");
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width,
+            int height) {
+        // This doesn't seem to happen in practice with current test framework -- Surface is
+        // already created before we start, and the orientation is locked.
+        Log.d(TAG, "surfaceChanged f=" + format + " w=" + width + " h=" + height);
+        mWidth = width;
+        mHeight = height;
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        Log.d(TAG, "surfaceDestroyed");
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_DumpFileProviderTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_DumpFileProviderTest.java
new file mode 100644
index 0000000..5c5afaa
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_DumpFileProviderTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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 android.provider.cts;
+
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.test.AndroidTestCase;
+
+import java.io.FileNotFoundException;
+
+public class ContactsContract_DumpFileProviderTest extends AndroidTestCase {
+
+    private static final String URI_PREFIX = "content://com.android.contacts.dumpfile/";
+
+    private static final String[] NOT_ALLOWED_FILES = {
+            "not_allowed.txt",
+            "../A-contacts-db.zip",   // ".." is not allowed.
+            "/A-contacts-db.zip",     // "/" is not allowed
+            "-contacts-db.zip",       // no name prefix
+            "asdf-contacts-db.zip"};
+
+    private static final String[] ALLOWED_FILES = {
+            "1234567890abcdefABCDEF-contacts-db.zip",
+            "a-contacts-db.zip",
+            "0-contacts-db.zip",
+            "A-contacts-db.zip",
+            "abcdefabcdefabcdefabcdef-contacts-db.zip"};
+
+    private ContentResolver mResolver;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mResolver = getContext().getContentResolver();
+    }
+
+    public void testOpenFileDescriptor_throwsErrorWithIllegalFileName() {
+        for (String fileName : NOT_ALLOWED_FILES) {
+            Uri uri = Uri.parse(URI_PREFIX + fileName);
+            assertOpenFileDescriptorThrowsError(uri);
+        }
+    }
+
+    public void testOpenFileDescriptor_worksWithValidFileName() {
+        for (String fileName : ALLOWED_FILES) {
+            final Uri uri = Uri.parse(URI_PREFIX + fileName);
+            try {
+                mResolver.openFileDescriptor(uri, "r");
+            } catch (FileNotFoundException e) {
+
+            }
+        }
+    }
+
+    public void testQuery_throwsErrorWithIllegalFileName() {
+        for (String fileName : NOT_ALLOWED_FILES) {
+            final Uri uri = Uri.parse(URI_PREFIX + fileName);
+            assertQueryThrowsError(uri);
+        }
+    }
+
+    public void testQuery_worksWithValidFileName() {
+        for (String fileName : ALLOWED_FILES) {
+            final Uri uri = Uri.parse(URI_PREFIX + fileName);
+            mResolver.query(uri, null, null, null, null);
+        }
+    }
+
+    private void assertQueryThrowsError(Uri uri) {
+        try {
+            mResolver.query(uri, null, null, null, null);
+        } catch (IllegalArgumentException e) {
+            // pass
+            return;
+        }
+
+        fail("IllegalArgumentException expected but not thrown.");
+    }
+
+    private void assertOpenFileDescriptorThrowsError(Uri uri) {
+        try {
+            mResolver.openFileDescriptor(uri, "r");
+        } catch (IllegalArgumentException e) {
+            // pass
+            return;
+        } catch (FileNotFoundException e) {
+
+        }
+
+        fail("IllegalArgumentException expected but not thrown.");
+    }
+}
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index ee185c5..5821ec0 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -23,7 +23,8 @@
 
 LOCAL_SRC_FILES := \
 		CtsSecurityJniOnLoad.cpp \
-		android_security_cts_CharDeviceTest.cpp
+		android_security_cts_CharDeviceTest.cpp \
+		android_security_cts_NativeCodeTest.cpp
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index 045581f..7244fc2 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -18,6 +18,7 @@
 #include <stdio.h>
 
 extern int register_android_security_cts_CharDeviceTest(JNIEnv*);
+extern int register_android_security_cts_NativeCodeTest(JNIEnv*);
 
 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
     JNIEnv *env = NULL;
@@ -30,5 +31,9 @@
         return JNI_ERR;
     }
 
+    if (register_android_security_cts_NativeCodeTest(env)) {
+        return JNI_ERR;
+    }
+
     return JNI_VERSION_1_4;
 }
diff --git a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
new file mode 100644
index 0000000..7af4298
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+#include <jni.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+/*
+ * Returns true iff this device is vulnerable to CVE-2013-2094.
+ * A patch for CVE-2013-2094 can be found at
+ * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8176cced706b5e5d15887584150764894e94e02f
+ */
+static jboolean android_security_cts_NativeCodeTest_doPerfEventTest(JNIEnv* env, jobject thiz)
+{
+    uint64_t attr[10] = { 0x4800000001, (uint32_t) -1, 0, 0, 0, 0x300 };
+
+    int fd = syscall(__NR_perf_event_open, attr, 0, -1, -1, 0);
+    jboolean result = (fd != -1);
+
+    if (fd != -1) {
+        close(fd);
+    }
+
+    return result;
+}
+
+static JNINativeMethod gMethods[] = {
+    {  "doPerfEventTest", "()Z",
+            (void *) android_security_cts_NativeCodeTest_doPerfEventTest },
+};
+
+int register_android_security_cts_NativeCodeTest(JNIEnv* env)
+{
+    jclass clazz = env->FindClass("android/security/cts/NativeCodeTest");
+    return env->RegisterNatives(clazz, gMethods,
+            sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/security/src/android/security/cts/KernelSettingsTest.java b/tests/tests/security/src/android/security/cts/KernelSettingsTest.java
index f8ee283..2a1f414 100644
--- a/tests/tests/security/src/android/security/cts/KernelSettingsTest.java
+++ b/tests/tests/security/src/android/security/cts/KernelSettingsTest.java
@@ -31,6 +31,17 @@
 public class KernelSettingsTest extends TestCase {
 
     /**
+     * Ensure that SELinux is in enforcing mode.
+     */
+    public void testSELinuxEnforcing() throws IOException {
+        try {
+            assertEquals("1", getFile("/sys/fs/selinux/enforce"));
+        } catch (FileNotFoundException e) {
+            fail("SELinux is not compiled into this kernel, or is disabled.");
+        }
+    }
+
+    /**
      * Protect against kernel based NULL pointer attacks by enforcing a
      * minimum (and maximum!) value of mmap_min_addr.
      *
diff --git a/tests/tests/security/src/android/security/cts/NativeCodeTest.java b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
new file mode 100644
index 0000000..2522ef5
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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 android.security.cts;
+
+import junit.framework.TestCase;
+
+public class NativeCodeTest extends TestCase {
+
+    static {
+        System.loadLibrary("ctssecurity_jni");
+    }
+
+    public void testPerfEvent() throws Exception {
+        assertFalse("Device is vulnerable to CVE-2013-2094. Please apply security patch "
+                    + "at http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/"
+                    + "commit/?id=8176cced706b5e5d15887584150764894e94e02f",
+                    doPerfEventTest());
+    }
+
+    /**
+     * Returns true iff this device is vulnerable to CVE-2013-2094.
+     * A patch for CVE-2013-2094 can be found at
+     * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8176cced706b5e5d15887584150764894e94e02f
+     */
+    private static native boolean doPerfEventTest();
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk b/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
index fe4342a..90bdb61 100644
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
@@ -28,4 +28,6 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
+LOCAL_DEX_PREOPT := false
+
 include $(BUILD_PACKAGE)
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/RootProcessScanner.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/RootProcessScanner.java
index 4763287..fefff99 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/RootProcessScanner.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/RootProcessScanner.java
@@ -31,7 +31,9 @@
             "debuggerd",
             "init",
             "installd",
+            "netd",
             "servicemanager",
+            "ueventd",
             "vold",
             "zygote"
     );
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/AccessibilityServiceTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/AccessibilityServiceTestRunner.java
new file mode 100644
index 0000000..4cfd263
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/AccessibilityServiceTestRunner.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.tradefed.testtype;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.util.FileUtil;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+
+/**
+ * Running the accessibility tests requires modification of secure
+ * settings. Secure settings cannot be changed from device CTS tests
+ * since system signature permission is required. Such settings can
+ * be modified by the shell user, so a host side test is used for
+ * installing a package with a delegating accessibility service, enabling
+ * this service, running these tests, disabling the service, and removing
+ * the delegating accessibility service package.
+ *
+ * @deprecated This class is not required in current CTS builds. Still
+ * maintained so cts-tradefed can run against older CTS builds that still
+ * require this class.
+ */
+public class AccessibilityServiceTestRunner extends InstrumentationApkTest {
+
+    private static final String DELEGATING_ACCESSIBLITY_SERVICE_PACKAGE_NAME =
+        "android.accessibilityservice.delegate";
+
+    private static final String DELEGATING_ACCESSIBLITY_SERVICE_NAME =
+        "android.accessibilityservice.delegate.DelegatingAccessibilityService";
+
+    private static final String DELEGATING_ACCESSIBLITY_SERVICE_APK =
+        "CtsDelegatingAccessibilityService.apk";
+
+    private CtsBuildHelper mCtsBuild;
+
+    @Override
+    public void setBuild(IBuildInfo build) {
+        super.setBuild(build);
+        mCtsBuild  = CtsBuildHelper.createBuildHelper(build);
+    }
+
+    @Override
+    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+        beforeTest();
+        super.run(listener);
+        afterTest();
+    }
+
+    private void beforeTest() throws DeviceNotAvailableException {
+        installApkAndAssert(DELEGATING_ACCESSIBLITY_SERVICE_APK);
+        enableAccessibilityAndDelegatingService();
+    }
+
+    private void afterTest() throws DeviceNotAvailableException {
+        AccessibilityTestRunner.disableAccessibilityAndServices(getDevice());
+        uninstallAndAssert(DELEGATING_ACCESSIBLITY_SERVICE_PACKAGE_NAME);
+    }
+
+    private void installApkAndAssert(String apkName) throws DeviceNotAvailableException {
+        File file = FileUtil.getFileForPath(mCtsBuild.getTestCasesDir(), apkName);
+        String errorMessage = getDevice().installPackage(file, true);
+        TestCase.assertNull("Error installing: " + apkName, errorMessage);
+    }
+
+    private void uninstallAndAssert(String packageName) throws DeviceNotAvailableException {
+        String errorMessage = getDevice().uninstallPackage(packageName);
+        TestCase.assertNull("Error uninstalling: " + packageName, errorMessage);
+    }
+
+    private void enableAccessibilityAndDelegatingService() throws DeviceNotAvailableException {
+        String componentName = DELEGATING_ACCESSIBLITY_SERVICE_PACKAGE_NAME + "/"
+            + DELEGATING_ACCESSIBLITY_SERVICE_NAME;
+        AccessibilityTestRunner.enableAccessibilityAndServices(getDevice(),
+                componentName);
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index 59babec..03e043b 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -48,6 +48,8 @@
     public static final String VM_HOST_TEST = "vmHostTest";
     public static final String ACCESSIBILITY_TEST =
         "com.android.cts.tradefed.testtype.AccessibilityTestRunner";
+    public static final String ACCESSIBILITY_SERVICE_TEST =
+        "com.android.cts.tradefed.testtype.AccessibilityServiceTestRunner";
     public static final String DISPLAY_TEST =
             "com.android.cts.tradefed.testtype.DisplayTestRunner";
     public static final String UIAUTOMATOR_TEST = "uiAutomator";
@@ -228,6 +230,9 @@
         } else if (ACCESSIBILITY_TEST.equals(mTestType)) {
             AccessibilityTestRunner test = new AccessibilityTestRunner();
             return setInstrumentationTest(test, testCaseDir);
+        } else if (ACCESSIBILITY_SERVICE_TEST.equals(mTestType)) {
+            AccessibilityServiceTestRunner test = new AccessibilityServiceTestRunner();
+            return setInstrumentationTest(test, testCaseDir);
         } else if (DISPLAY_TEST.equals(mTestType)) {
             DisplayTestRunner test = new DisplayTestRunner();
             return setInstrumentationTest(test, testCaseDir);