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);