Merge "Test ContactsContract_StreamItems Insert"
diff --git a/Android.mk b/Android.mk
index 159bda0..4251262 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,6 +14,6 @@
# limitations under the License.
#
-include cts/CtsNativeTestCase.mk
-include cts/CtsTestCoverage.mk
+include cts/CtsBuild.mk
+include cts/CtsCoverage.mk
include $(call all-subdir-makefiles)
diff --git a/CtsBuild.mk b/CtsBuild.mk
new file mode 100644
index 0000000..b4273bd
--- /dev/null
+++ b/CtsBuild.mk
@@ -0,0 +1,66 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# CTS build rules that are needed to generate the corresponding XML
+# for a test package. CTS needs these XML files to know what tests
+# to run as well as detect which ones were not executed.
+#
+# 1. Replace the regular build command with the CTS variant:
+#
+# BUILD_EXECUTABLE -> BUILD_CTS_EXECUTABLE
+# BUILD_PACKAGE -> BUILD_CTS_PACKAGE
+# BUILD_HOST_JAVA_LIBRARY -> BUILD_HOST_JAVA_LIBRARY
+#
+# 2. Define LOCAL_CTS_TEST_PACKAGE if you are using
+# BUILD_EXECUTABLE or BUILD_HOST_JAVA_LIBRARY.
+#
+BUILD_CTS_EXECUTABLE := $(LOCAL_PATH)/tools/build/test_executable.mk
+BUILD_CTS_PACKAGE := $(LOCAL_PATH)/tools/build/test_package.mk
+BUILD_CTS_HOST_JAVA_LIBRARY := $(LOCAL_PATH)/tools/build/test_host_java_library.mk
+
+# Test XMLs, native executables, and packages will be placed in this
+# directory before creating the final CTS distribution.
+CTS_TESTCASES_OUT := $(HOST_OUT)/cts-testcases
+
+# Scanners of source files for tests which are then inputed into
+# the XML generator to produce test XMLs.
+CTS_NATIVE_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-native-scanner
+CTS_JAVA_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-java-scanner
+CTS_JAVA_TEST_SCANNER_DOCLET := $(HOST_OUT_JAVA_LIBRARIES)/cts-java-scanner-doclet.jar
+
+# Generator of test XMLs from scanner output.
+CTS_XML_GENERATOR := $(HOST_OUT_EXECUTABLES)/cts-xml-generator
+
+# File indicating which tests should be blacklisted due to problems.
+CTS_EXPECTATIONS := cts/tests/expectations/knownfailures.txt
+
+# Functions to get the paths of the build outputs.
+
+define cts-get-lib-paths
+ $(foreach lib,$(1),$(HOST_OUT_JAVA_LIBRARIES)/$(lib).jar)
+endef
+
+define cts-get-native-paths
+ $(foreach exe,$(1),$(call intermediates-dir-for,EXECUTABLES,$(exe))/$(exe))
+endef
+
+define cts-get-package-paths
+ $(foreach pkg,$(1),$(CTS_TESTCASES_OUT)/$(pkg).apk)
+endef
+
+define cts-get-test-xmls
+ $(foreach name,$(1),$(CTS_TESTCASES_OUT)/$(name).xml)
+endef
diff --git a/CtsTestCoverage.mk b/CtsCoverage.mk
similarity index 100%
rename from CtsTestCoverage.mk
rename to CtsCoverage.mk
diff --git a/CtsNativeTestCase.mk b/CtsNativeTestCase.mk
deleted file mode 100644
index cd027e6..0000000
--- a/CtsNativeTestCase.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Include this file to gain access to functions to build native CTS
-# test packages. Replace "include $(BUILD_EXECUTABLE)" with
-# "include $(BUILD_CTS_EXECUTABLE)".
-
-LOCAL_PATH := $(call my-dir)
-BUILD_CTS_EXECUTABLE := $(LOCAL_PATH)/tools/build/test_executable.mk
-
-CTS_NATIVE_XML_OUT := $(HOST_OUT)/cts-native-xml
-
-CTS_NATIVE_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-native-scanner
-
-CTS_XML_GENERATOR := $(HOST_OUT_EXECUTABLES)/cts-xml-generator
-
-CTS_EXPECTATIONS := cts/tests/expectations/knownfailures.txt
-
-define cts-get-native-paths
- $(foreach exe,$(1),$(call intermediates-dir-for,EXECUTABLES,$(exe))/$(exe))
-endef
-
-define cts-get-native-xmls
- $(foreach exe,$(1),$(CTS_NATIVE_XML_OUT)/$(exe).xml)
-endef
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 840d42b..70f3ef9 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -24,10 +24,22 @@
CtsTargetInstrumentationApp \
CtsUsePermissionDiffCert
-# These test cases will be analyzed by the CTS API coverage tools.
-CTS_COVERAGE_TEST_CASE_LIST := \
- CtsAccelerationTestCases \
+# Any APKs that need to be copied to the CTS distribution's testcases
+# directory but do not require an associated test package XML.
+CTS_TEST_CASE_LIST := \
+ TestDeviceSetup \
CtsAccelerationTestStubs \
+ CtsDelegatingAccessibilityService \
+ CtsDeviceAdmin \
+ CtsTestStubs \
+ SignatureTest \
+ ApiDemos \
+ ApiDemosReferenceTest \
+ $(CTS_SECURITY_APPS_LIST)
+
+# Test packages that require an associated test package XML.
+CTS_TEST_PACKAGES := \
+ CtsAccelerationTestCases \
CtsAccessibilityServiceTestCases \
CtsAccountManagerTestCases \
CtsAdminTestCases \
@@ -61,30 +73,37 @@
CtsSecurityTestCases \
CtsSpeechTestCases \
CtsTelephonyTestCases \
- CtsTestStubs \
CtsTextTestCases \
CtsUtilTestCases \
CtsViewTestCases \
CtsWebkitTestCases \
CtsWidgetTestCases
-CTS_TEST_CASE_LIST := \
- TestDeviceSetup \
- CtsDelegatingAccessibilityService \
- CtsDeviceAdmin \
- SignatureTest \
- ApiDemos \
- ApiDemosReferenceTest \
- $(CTS_COVERAGE_TEST_CASE_LIST) \
- $(CTS_SECURITY_APPS_LIST)
+# All APKs that need to be scanned by the coverage utilities.
+CTS_COVERAGE_TEST_CASE_LIST := \
+ $(CTS_TEST_CASE_LIST) \
+ $(CTS_TEST_PACKAGES)
+# Host side only tests
+CTS_HOST_LIBRARIES := \
+ CtsAppSecurityTests
+
+# Native test executables that need to have associated test XMLs.
CTS_NATIVE_EXES := \
NativeMediaTest_SL \
NativeMediaTest_XA
-CTS_TEST_CASES := $(call cts-get-native-paths,$(CTS_NATIVE_EXES))
+# All the files that will end up under the repository/testcases
+# directory of the final CTS distribution.
+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))
-CTS_TEST_XMLS := $(call cts-get-native-xmls,$(CTS_NATIVE_EXES))
+# All the XMLs that will end up under the repository/testcases
+# and that need to be created before making the final CTS distribution.
+CTS_TEST_XMLS := $(call cts-get-test-xmls,$(CTS_HOST_LIBRARIES)) \
+ $(call cts-get-test-xmls,$(CTS_TEST_PACKAGES)) \
+ $(call cts-get-test-xmls,$(CTS_NATIVE_EXES))
# The following files will be placed in the tools directory of the CTS distribution
CTS_TOOLS_LIST :=
diff --git a/apps/CtsVerifier/jni/audioquality/Android.mk b/apps/CtsVerifier/jni/audioquality/Android.mk
index 8e827f7..787128a 100644
--- a/apps/CtsVerifier/jni/audioquality/Android.mk
+++ b/apps/CtsVerifier/jni/audioquality/Android.mk
@@ -20,11 +20,13 @@
LOCAL_MODULE_TAGS := optional
-
+LOCAL_SHARED_LIBRARIES := \
+ libcutils
LOCAL_MODULE := libaudioquality
LOCAL_SRC_FILES := Fft.cpp Window.cpp GlitchTest.cpp MeasureRms.cpp \
OverflowCheck.cpp LinearityTest.cpp CompareSpectra.cpp \
- GenerateSinusoid.cpp Wrapper.cpp
+ GenerateSinusoid.cpp Wrapper.cpp LinearityTestRms.cpp
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/apps/CtsVerifier/jni/audioquality/LinearityTest.h b/apps/CtsVerifier/jni/audioquality/LinearityTest.h
index d92566a..1aac4b6 100644
--- a/apps/CtsVerifier/jni/audioquality/LinearityTest.h
+++ b/apps/CtsVerifier/jni/audioquality/LinearityTest.h
@@ -17,6 +17,22 @@
#ifndef LINEARITY_TEST_H
#define LINEARITY_TEST_H
+/* error codes returned */
+// The input signals or sample counts are missing.
+const int ERROR_INPUT_SIGNAL_MISSING = -1;
+// The number of input signals is < 2.
+const int ERROR_INPUT_SIGNAL_NUMBERS = -2;
+// The specified sample rate is <= 4000.0
+const int ERROR_SAMPLE_RATE_TOO_LOW = -3;
+// The dB step size for the increase in stimulus level is <= 0.0
+const int ERROR_NEGATIVE_STEP_SIZE = -4;
+// The specified reference stimulus number is out of range.
+const int ERROR_STIMULUS_NUMBER = -5;
+// One or more of the stimuli is too short in duration.
+const int ERROR_STIMULI_TOO_SHORT = -6;
+// cannot find linear fitting for the given data
+const int ERROR_LINEAR_FITTING = -7;
+
/* There are numSignals int16 signals in pcms. sampleCounts is an
integer array of length numSignals containing their respective
lengths in samples. They are all sampled at sampleRate. The pcms
@@ -27,16 +43,15 @@
normal speaking levels). The maximum deviation in linearity found
(in dB) is returned in maxDeviation. The function returns 1 if
the measurements could be made, or a negative number that
- indicates the error, as follows:
- -1 The input signals or sample counts are missing.
- -2 The number of input signals is < 2.
- -3 The specified sample rate is <= 4000.0
- -4 The dB step size for the increase in stimulus level is <= 0.0/
- -5 The specified reverence stimulus number is out of range.
- -6 One or more of the stimuli is too short in duration. */
+ indicates the error, as defined above. */
int linearityTest(short** pcms, int* sampleCounts, int numSignals,
float sampleRate, float dbStepSize,
int referenceStim, float* maxDeviation);
+/* a version using RMS of the whole signal and linear fitting */
+int linearityTestRms(short** pcms, int* sampleCounts, int numSignals,
+ float sampleRate, float dbStepSize,
+ float* maxDeviation);
+
#endif /* LINEARITY_TEST_H */
diff --git a/apps/CtsVerifier/jni/audioquality/LinearityTestRms.cpp b/apps/CtsVerifier/jni/audioquality/LinearityTestRms.cpp
new file mode 100644
index 0000000..d83b056
--- /dev/null
+++ b/apps/CtsVerifier/jni/audioquality/LinearityTestRms.cpp
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/* This test accepts a collection of N speech waveforms collected as
+ part of N recognition attempts. The waveforms are ordered by
+ increasing presentation level. The test determines the extent to
+ which the peak amplitudes in the waveforms track the change in
+ presentation level. Failure to track the presentation level within
+ some reasonable margin is an indication of clipping or of automatic
+ gain control in the signal path.
+
+ RMS of each level is used as a parameter for deciding lienairy.
+ For each level, RMS is calculated, and a line fitting into RMS vs level
+ will be calculated. Then for each level, residual error of measurement
+ vs line fitting will be calculated, and the residual error is normalized
+ with each measurement. The test failes if residual error is bigger than
+ 2dB.
+
+ This test will be robust to background noise as long as it is persistent.
+ But background noise which appears shortly with enough strength can
+ mess up the result.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <cutils/log.h>
+#include "LinearityTest.h"
+
+#define LOG_TAG "LinearityTestRms"
+
+// vectorDot, vectorNorm, and solveLeastSquares
+// copied from frameworks/base/libs/ui/Input.cpp
+
+static inline float vectorDot(const float* a, const float* b, uint32_t m) {
+ float r = 0;
+ while (m--) {
+ r += *(a++) * *(b++);
+ }
+ return r;
+}
+
+static inline float vectorNorm(const float* a, uint32_t m) {
+ float r = 0;
+ while (m--) {
+ float t = *(a++);
+ r += t * t;
+ }
+ return sqrtf(r);
+}
+
+/**
+ * Solves a linear least squares problem to obtain a N degree polynomial that fits
+ * the specified input data as nearly as possible.
+ *
+ * Returns true if a solution is found, false otherwise.
+ *
+ * The input consists of two vectors of data points X and Y with indices 0..m-1.
+ * The output is a vector B with indices 0..n-1 that describes a polynomial
+ * that fits the data, such the sum of abs(Y[i] - (B[0] + B[1] X[i] + B[2] X[i]^2 ... B[n] X[i]^n))
+ * for all i between 0 and m-1 is minimized.
+ *
+ * That is to say, the function that generated the input data can be approximated
+ * by y(x) ~= B[0] + B[1] x + B[2] x^2 + ... + B[n] x^n.
+ *
+ * The coefficient of determination (R^2) is also returned to describe the goodness
+ * of fit of the model for the given data. It is a value between 0 and 1, where 1
+ * indicates perfect correspondence.
+ *
+ * This function first expands the X vector to a m by n matrix A such that
+ * A[i][0] = 1, A[i][1] = X[i], A[i][2] = X[i]^2, ..., A[i][n] = X[i]^n.
+ *
+ * Then it calculates the QR decomposition of A yielding an m by m orthonormal matrix Q
+ * and an m by n upper triangular matrix R. Because R is upper triangular (lower
+ * part is all zeroes), we can simplify the decomposition into an m by n matrix
+ * Q1 and a n by n matrix R1 such that A = Q1 R1.
+ *
+ * Finally we solve the system of linear equations given by R1 B = (Qtranspose Y)
+ * to find B.
+ *
+ * For efficiency, we lay out A and Q column-wise in memory because we frequently
+ * operate on the column vectors. Conversely, we lay out R row-wise.
+ *
+ * http://en.wikipedia.org/wiki/Numerical_methods_for_linear_least_squares
+ * http://en.wikipedia.org/wiki/Gram-Schmidt
+ */
+static bool solveLeastSquares(const float* x, const float* y, uint32_t m, uint32_t n,
+ float* outB, float* outDet) {
+#if DEBUG_LEAST_SQUARES
+ LOGD("solveLeastSquares: m=%d, n=%d, x=%s, y=%s", int(m), int(n),
+ vectorToString(x, m).string(), vectorToString(y, m).string());
+#endif
+
+ // Expand the X vector to a matrix A.
+ float a[n][m]; // column-major order
+ for (uint32_t h = 0; h < m; h++) {
+ a[0][h] = 1;
+ for (uint32_t i = 1; i < n; i++) {
+ a[i][h] = a[i - 1][h] * x[h];
+ }
+ }
+#if DEBUG_LEAST_SQUARES
+ LOGD(" - a=%s", matrixToString(&a[0][0], m, n, false /*rowMajor*/).string());
+#endif
+
+ // Apply the Gram-Schmidt process to A to obtain its QR decomposition.
+ float q[n][m]; // orthonormal basis, column-major order
+ float r[n][n]; // upper triangular matrix, row-major order
+ for (uint32_t j = 0; j < n; j++) {
+ for (uint32_t h = 0; h < m; h++) {
+ q[j][h] = a[j][h];
+ }
+ for (uint32_t i = 0; i < j; i++) {
+ float dot = vectorDot(&q[j][0], &q[i][0], m);
+ for (uint32_t h = 0; h < m; h++) {
+ q[j][h] -= dot * q[i][h];
+ }
+ }
+
+ float norm = vectorNorm(&q[j][0], m);
+ if (norm < 0.000001f) {
+ // vectors are linearly dependent or zero so no solution
+#if DEBUG_LEAST_SQUARES
+ LOGD(" - no solution, norm=%f", norm);
+#endif
+ return false;
+ }
+
+ float invNorm = 1.0f / norm;
+ for (uint32_t h = 0; h < m; h++) {
+ q[j][h] *= invNorm;
+ }
+ for (uint32_t i = 0; i < n; i++) {
+ r[j][i] = i < j ? 0 : vectorDot(&q[j][0], &a[i][0], m);
+ }
+ }
+#if DEBUG_LEAST_SQUARES
+ LOGD(" - q=%s", matrixToString(&q[0][0], m, n, false /*rowMajor*/).string());
+ LOGD(" - r=%s", matrixToString(&r[0][0], n, n, true /*rowMajor*/).string());
+
+ // calculate QR, if we factored A correctly then QR should equal A
+ float qr[n][m];
+ for (uint32_t h = 0; h < m; h++) {
+ for (uint32_t i = 0; i < n; i++) {
+ qr[i][h] = 0;
+ for (uint32_t j = 0; j < n; j++) {
+ qr[i][h] += q[j][h] * r[j][i];
+ }
+ }
+ }
+ LOGD(" - qr=%s", matrixToString(&qr[0][0], m, n, false /*rowMajor*/).string());
+#endif
+
+ // Solve R B = Qt Y to find B. This is easy because R is upper triangular.
+ // We just work from bottom-right to top-left calculating B's coefficients.
+ for (uint32_t i = n; i-- != 0; ) {
+ outB[i] = vectorDot(&q[i][0], y, m);
+ for (uint32_t j = n - 1; j > i; j--) {
+ outB[i] -= r[i][j] * outB[j];
+ }
+ outB[i] /= r[i][i];
+ }
+#if DEBUG_LEAST_SQUARES
+ LOGD(" - b=%s", vectorToString(outB, n).string());
+#endif
+
+ // Calculate the coefficient of determination as 1 - (SSerr / SStot) where
+ // SSerr is the residual sum of squares (squared variance of the error),
+ // and SStot is the total sum of squares (squared variance of the data).
+ float ymean = 0;
+ for (uint32_t h = 0; h < m; h++) {
+ ymean += y[h];
+ }
+ ymean /= m;
+
+ float sserr = 0;
+ float sstot = 0;
+ for (uint32_t h = 0; h < m; h++) {
+ float err = y[h] - outB[0];
+ float term = 1;
+ for (uint32_t i = 1; i < n; i++) {
+ term *= x[h];
+ err -= term * outB[i];
+ }
+ sserr += err * err;
+ float var = y[h] - ymean;
+ sstot += var * var;
+ }
+ *outDet = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1;
+#if DEBUG_LEAST_SQUARES
+ LOGD(" - sserr=%f", sserr);
+ LOGD(" - sstot=%f", sstot);
+ LOGD(" - det=%f", *outDet);
+#endif
+ return true;
+}
+
+/* calculate RMS of given sample with numSamples of length */
+float calcRms(short* pcm, int numSamples)
+{
+ float energy = 0.0f;
+ for(int i = 0; i < numSamples; i++) {
+ float sample = (float)pcm[i];
+ energy += (sample * sample);
+ }
+ return sqrtf(energy);
+}
+
+/* There are numSignals int16 signals in pcms. sampleCounts is an
+ integer array of length numSignals containing their respective
+ lengths in samples. They are all sampled at sampleRate. The pcms
+ are ordered by increasing stimulus level. The level steps between
+ successive stimuli were of size dbStepSize dB.
+ The maximum deviation in linearity found
+ (in dB) is returned in maxDeviation. The function returns 1 if
+ the measurements could be made, or a negative number that
+ indicates the error, as defined in LinearityTest.h */
+int linearityTestRms(short** pcms, int* sampleCounts, int numSignals,
+ float sampleRate, float dbStepSize,
+ float* maxDeviation) {
+ if (!(pcms && sampleCounts)) {
+ return ERROR_INPUT_SIGNAL_MISSING;
+ }
+ if (numSignals < 2) {
+ return ERROR_INPUT_SIGNAL_NUMBERS;
+ }
+ if (sampleRate <= 4000.0) {
+ return ERROR_SAMPLE_RATE_TOO_LOW;
+ }
+ if (dbStepSize <= 0.0) {
+ return ERROR_NEGATIVE_STEP_SIZE;
+ }
+
+ float* levels = new float[numSignals];
+ levels[0] = 1.0f;
+ float stepInMag = powf(10.0f, dbStepSize/20.0f);
+ for(int i = 1; i < numSignals; i++) {
+ levels[i] = levels[i - 1] * stepInMag;
+ }
+
+ float* rmsValues = new float[numSignals];
+ for (int i = 0; i < numSignals; i++) {
+ rmsValues[i] = calcRms(pcms[i], sampleCounts[i]);
+ }
+ const int NO_COEFFS = 2; // only line fitting
+ float coeffs[NO_COEFFS];
+ float outDet;
+ if(!solveLeastSquares(levels, rmsValues, numSignals, NO_COEFFS,
+ coeffs, &outDet)) {
+ ALOGI(" solveLeastSquares fails with det %f", outDet);
+ return ERROR_LINEAR_FITTING;
+ }
+ ALOGI(" coeffs offset %f linear %f", coeffs[0], coeffs[1]);
+ float maxDev = 0.0f;
+ for(int i = 0; i < numSignals; i++) {
+ float residue = coeffs[0] + coeffs[1] * levels[i] - rmsValues[i];
+ // to make devInDb positive, add measured value itself
+ // then normalize
+ float devInDb = 20.0f * log10f((fabs(residue) + rmsValues[i])
+ / rmsValues[i]);
+ ALOGI(" %d-th residue %f dB", i, devInDb);
+ if (devInDb > maxDev) {
+ maxDev = devInDb;
+ }
+ }
+ *maxDeviation = maxDev;
+
+ delete[] levels;
+ delete[] rmsValues;
+
+ return 1;
+}
diff --git a/apps/CtsVerifier/jni/audioquality/Wrapper.cpp b/apps/CtsVerifier/jni/audioquality/Wrapper.cpp
index bee15c6..438f0d8 100644
--- a/apps/CtsVerifier/jni/audioquality/Wrapper.cpp
+++ b/apps/CtsVerifier/jni/audioquality/Wrapper.cpp
@@ -57,6 +57,12 @@
JNIEnv *env, jobject obj,
jobjectArray jpcms,
jfloat sampleRate, jfloat dbStepSize, jint referenceStim);
+
+ JNIEXPORT jfloat JNICALL
+ Java_com_android_cts_verifier_audioquality_Native_linearityTestRms(
+ JNIEnv *env, jobject obj,
+ jobjectArray jpcms,
+ jfloat sampleRate, jfloat dbStepSize);
};
/* Returns an array of sinusoidal samples.
@@ -241,3 +247,41 @@
return maxDeviation;
}
+
+
+/* Return maximum deviation from linearity in dB.
+ On failure returns:
+ -1.0 The input signals or sample counts are missing.
+ -2.0 The number of input signals is < 2.
+ -3.0 The specified sample rate is <= 4000.0
+ -4.0 The dB step size for the increase in stimulus level is <= 0.0
+ -6.0 One or more of the stimuli is too short in duration.
+*/
+JNIEXPORT jfloat JNICALL
+ Java_com_android_cts_verifier_audioquality_Native_linearityTestRms(
+ JNIEnv *env, jobject obj,
+ jobjectArray jpcms,
+ jfloat sampleRate, jfloat dbStepSize) {
+ int numSignals = env->GetArrayLength(jpcms);
+ int *sampleCounts = new int[numSignals];
+ short **pcms = new shortPtr[numSignals];
+ jshortArray ja;
+ for (int i = 0; i < numSignals; i++) {
+ ja = (jshortArray) env->GetObjectArrayElement(jpcms, i);
+ sampleCounts[i] = env->GetArrayLength(ja);
+ pcms[i] = new short[sampleCounts[i]];
+ env->GetShortArrayRegion(ja, 0, sampleCounts[i], pcms[i]);
+ }
+
+ float maxDeviation = -1.0;
+ int ret = linearityTestRms(pcms, sampleCounts, numSignals,
+ sampleRate, dbStepSize, &maxDeviation);
+ delete[] sampleCounts;
+ for (int i = 0; i < numSignals; i++) {
+ delete[] pcms[i];
+ }
+ delete[] pcms;
+ if (ret < 1) return ret;
+
+ return maxDeviation;
+}
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_CameraTests.cpp b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_CameraTests.cpp
index 51fd0c5..83f5c17 100644
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_CameraTests.cpp
+++ b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_CameraTests.cpp
@@ -36,7 +36,7 @@
AndroidBitmap_getInfo(env, inputBitmap, &inputInfo);
if (inputInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888 &&
inputInfo.format != ANDROID_BITMAP_FORMAT_RGB_565) {
- LOGE("Only RGBA_8888 and RGB_565 bitmaps are supported, type was %d.",
+ ALOGE("Only RGBA_8888 and RGB_565 bitmaps are supported, type was %d.",
inputInfo.format);
}
@@ -52,7 +52,7 @@
reinterpret_cast<void**>(&inputBuffer));
if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
- LOGE("Unable to lock input bitmap");
+ ALOGE("Unable to lock input bitmap");
}
uint8_t *outputImage = NULL;
@@ -107,7 +107,7 @@
result = AndroidBitmap_unlockPixels(env, inputBitmap);
if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
- LOGE("Unable to unlock input bitmap");
+ ALOGE("Unable to unlock input bitmap");
}
if (freeInputRGBA) {
@@ -201,14 +201,14 @@
reinterpret_cast<void**>(&outputBuffer) );
if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
- LOGE("Unable to lock output bitmap");
+ ALOGE("Unable to lock output bitmap");
}
memcpy(outputBuffer, outputImage, outputWidth * outputHeight * 4);
result = AndroidBitmap_unlockPixels(env, outputBitmap);
if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
- LOGE("Unable to unlock output bitmap");
+ ALOGE("Unable to unlock output bitmap");
}
// Write new Bitmap reference into mDebugOutput class member
diff --git a/apps/CtsVerifier/lib/colorchecker/colorcheckertest.cpp b/apps/CtsVerifier/lib/colorchecker/colorcheckertest.cpp
index 63bce63..46b8cc8 100644
--- a/apps/CtsVerifier/lib/colorchecker/colorcheckertest.cpp
+++ b/apps/CtsVerifier/lib/colorchecker/colorcheckertest.cpp
@@ -236,7 +236,7 @@
delete[] gradientDirection;
} else {
- LOGE("Not a color image!");
+ ALOGE("Not a color image!");
}
delete[] edgeMap;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/AudioQualityVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/AudioQualityVerifierActivity.java
index 755b62d..af389a6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/AudioQualityVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/AudioQualityVerifierActivity.java
@@ -134,7 +134,7 @@
fillAdapter();
mList.setAdapter(mAdapter);
mList.setOnItemClickListener(this);
- checkNotSilent();
+ adjustVolume();
}
@Override
@@ -142,18 +142,18 @@
super.onResume();
mAdapter.notifyDataSetChanged(); // Update List UI
setVolumeControlStream(AudioManager.STREAM_MUSIC);
- checkNotSilent();
+ adjustVolume();
}
- private void checkNotSilent() {
+ private void adjustVolume() {
AudioManager mgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mgr.setStreamMute(PLAYBACK_STREAM, false);
int volume = mgr.getStreamVolume(PLAYBACK_STREAM);
int max = mgr.getStreamMaxVolume(PLAYBACK_STREAM);
+ int target = (max * 2) / 3;
Log.i(TAG, "Volume " + volume + ", max " + max);
- if (volume <= max / 10) {
- // Volume level is silent or very quiet; increase to two-thirds
- mgr.setStreamVolume(PLAYBACK_STREAM, (max * 2) / 3, AudioManager.FLAG_SHOW_UI);
+ if (volume != target) {
+ mgr.setStreamVolume(PLAYBACK_STREAM, target, AudioManager.FLAG_SHOW_UI);
}
}
@@ -188,6 +188,7 @@
// Implements AdapterView.OnItemClickListener
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mRunningExperiment) return;
+ adjustVolume();
runExperiment(position, false);
}
@@ -207,6 +208,7 @@
// Implements View.OnClickListener:
public void onClick(View v) {
+ adjustVolume();
if (v == mCalibrateButton) {
Intent intent = new Intent(this, CalibrateVolumeActivity.class);
startActivity(intent);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/Native.java b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/Native.java
index 87b11d1..cdb3e25 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/Native.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/Native.java
@@ -31,6 +31,8 @@
float sampleRate);
public native float linearityTest(short[][] pcms,
float sampleRate, float dbStepSize, int referenceStim);
+ public native float linearityTestRms(short[][] pcms,
+ float sampleRate, float dbStepSize);
// The following indexes must match those in wrapper.cc
public static final int MEASURE_RMS_RMS = 0;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/GainLinearityExperiment.java b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/GainLinearityExperiment.java
index 05f1602..225df1a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/GainLinearityExperiment.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/GainLinearityExperiment.java
@@ -66,9 +66,8 @@
for (int i = 0; i < LEVELS; i++) {
pcms[i] = Utils.byteToShortArray(record[i]);
}
- // We specify the middle stimulus (LEVELS / 2) as the "reference":
- float deviation = mNative.linearityTest(pcms, AudioQualityVerifierActivity.SAMPLE_RATE,
- DB_STEP_SIZE, LEVELS / 2);
+ float deviation = mNative.linearityTestRms(pcms, AudioQualityVerifierActivity.SAMPLE_RATE,
+ DB_STEP_SIZE);
if (deviation < 0.0f) {
setScore(getString(R.string.aq_fail));
setReport(String.format(getString(R.string.aq_linearity_report_error), deviation));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/SpectrumShapeExperiment.java b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/SpectrumShapeExperiment.java
index 148fb47..df7919e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/SpectrumShapeExperiment.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/SpectrumShapeExperiment.java
@@ -33,7 +33,7 @@
private static final int DURATION = 3;
public SpectrumShapeExperiment() {
- super(true);
+ super(false); // disable temporarily
}
@Override
diff --git a/development/ide/eclipse/.classpath b/development/ide/eclipse/.classpath
index 47e0025..c76f293 100644
--- a/development/ide/eclipse/.classpath
+++ b/development/ide/eclipse/.classpath
@@ -58,6 +58,8 @@
<classpathentry kind="src" path="cts/tests/tests/webkit/src"/>
<classpathentry kind="src" path="cts/tests/tests/widget/src"/>
<classpathentry kind="src" path="cts/tools/cts-api-coverage/src"/>
+ <classpathentry kind="src" path="cts/tools/cts-java-scanner/src"/>
+ <classpathentry kind="src" path="cts/tools/cts-java-scanner-doclet/src"/>
<classpathentry kind="src" path="cts/tools/cts-native-scanner/src"/>
<classpathentry kind="src" path="cts/tools/cts-reference-app-lib/src"/>
<classpathentry kind="src" path="cts/tools/cts-xml-generator/src"/>
diff --git a/tests/appsecurity-tests/Android.mk b/tests/appsecurity-tests/Android.mk
index b5ce83c..4dd8d5c 100644
--- a/tests/appsecurity-tests/Android.mk
+++ b/tests/appsecurity-tests/Android.mk
@@ -16,8 +16,6 @@
include $(CLEAR_VARS)
-#LOCAL_TEST_TYPE := hostSideOnly
-
# Only compile source java files in this apk.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
@@ -25,8 +23,9 @@
LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt ddmlib-prebuilt junit
-include $(BUILD_HOST_JAVA_LIBRARY)
+LOCAL_CTS_TEST_PACKAGE := android.tests.appsecurity
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
# Build the test APKs using their own makefiles
include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/tests/assets/webkit/jsform.html b/tests/assets/webkit/jsform.html
index 1781194..ce55498 100644
--- a/tests/assets/webkit/jsform.html
+++ b/tests/assets/webkit/jsform.html
@@ -24,7 +24,7 @@
}
}
</script>
- <body onload="window.setTimeout(function() { fireSubmit(); }, 0);">
+ <body onload="window.setTimeout(function() { fireSubmit(); }, 500);">
javascript form test
<form id="formId" action="test.html#result" method="post">
<input type="hidden" name="foo" value="bar" />
diff --git a/tests/config_demo/data/case_rep/APICheckTest_java5.apk b/tests/config_demo/data/case_rep/APICheckTest_java5.apk
deleted file mode 100644
index fcb51c4..0000000
--- a/tests/config_demo/data/case_rep/APICheckTest_java5.apk
+++ /dev/null
Binary files differ
diff --git a/tests/config_demo/data/case_rep/APICheckTest_java6.apk b/tests/config_demo/data/case_rep/APICheckTest_java6.apk
deleted file mode 100644
index 76c8f74..0000000
--- a/tests/config_demo/data/case_rep/APICheckTest_java6.apk
+++ /dev/null
Binary files differ
diff --git a/tests/config_demo/data/case_rep/DeviceInforCollector.apk b/tests/config_demo/data/case_rep/DeviceInforCollector.apk
deleted file mode 100644
index 24de83f..0000000
--- a/tests/config_demo/data/case_rep/DeviceInforCollector.apk
+++ /dev/null
Binary files differ
diff --git a/tests/config_demo/data/host_config.xml b/tests/config_demo/data/host_config.xml
deleted file mode 100644
index 4e4cb9a..0000000
--- a/tests/config_demo/data/host_config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<HostConfiguration version="1.0">
- <Repository>
- <!-- Specific OEM test plan directory (optional) -->
- <TestPlan path="plan_rep" />
- <!-- Specific OEM test case directory (optional) -->
- <TestCase path="case_rep" />
- <!-- Specific OEM test result directory (optional) -->
- <TestResult path="result_rep" />
- </Repository>
-</HostConfiguration>
diff --git a/tests/config_demo/data/plan_rep/README b/tests/config_demo/data/plan_rep/README
deleted file mode 100644
index 2f36f40..0000000
--- a/tests/config_demo/data/plan_rep/README
+++ /dev/null
@@ -1,17 +0,0 @@
-Copyright (C) 2008 The Android Open Source Project
-
-Licensed under the Apache Licence, 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.
-
-This directory would be the repository of the test plans.
-
-For detailed descriptions, please refer to the architecture document.
diff --git a/tests/config_demo/data/result_rep/cts_result.xsl b/tests/config_demo/data/result_rep/cts_result.xsl
deleted file mode 100644
index 9c9c82a..0000000
--- a/tests/config_demo/data/result_rep/cts_result.xsl
+++ /dev/null
@@ -1,339 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
- <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
- <xsl:template match="/">
-
- <html>
- <STYLE type="text/css">
- .plan { background-color : #9acd32 }
- .head { font-size : 30; background-color : #A8A6A6 }
- .head1 { font-size : 20; background-color : #A8A6A6 }
- .lgreen {background-color : #9acd32}
- .pass {background-color : #00ff00}
- .failed {background-color : #ff0000}
- .timeout {background-color : #febf00}
- .notrun {background-color : #C6C3C3}
- .gray {background-color : #C6C3C3}
- </STYLE>
- <body>
- <p class="head">CTS Test result</p>
-
- <!-- plan information -->
- <TABLE >
- <TR class="plan">
- <TD>Plan name</TD>
- <TD>Start time</TD>
- <TD>End time</TD>
- <TD>Version</TD>
- </TR>
- <TR>
- <TD>
- <xsl:value-of select="TestResult/@testPlan"/>
- </TD>
- <TD>
- <xsl:value-of select="TestResult/@starttime"/>
- </TD>
- <TD>
- <xsl:value-of select="TestResult/@endtime"/>
- </TD>
- <TD>
- <xsl:value-of select="TestResult/@version"/>
- </TD>
- </TR>
- </TABLE>
- <!-- Device infor -->
- <p class="head1">Test Device information</p>
- <TABLE >
- <TR>
- <TD class="lgreen">Device Make</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@buildName"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Build model</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@deviceID"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Firmware Version</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@buildVersion"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Firmware Build Number</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@buildID"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Android Platform Version</TD>
- <TD>
- <xsl:value-of
- select="TestResult/DeviceInfo/BuildInfo/@androidPlatformVersion"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Supported Locales</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@locales"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Screen size</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/Screen/@resolution"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Phone number</TD>
- <TD>
- <xsl:value-of
- select="TestResult/DeviceInfo/PhoneSubInfo/@subscriberId"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">x dpi</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@Xdpi"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">y dpi</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@Ydpi"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Touch</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@touch"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Navigation</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@navigation"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Keypad</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@keypad"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">Network</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@network"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">IMEI</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@imei"/>
- </TD>
- </TR>
- <TR>
- <TD class="lgreen">IMSI</TD>
- <TD>
- <xsl:value-of select="TestResult/DeviceInfo/BuildInfo/@imsi"/>
- </TD>
- </TR>
- </TABLE>
- <!-- Summary -->
- <p class="head1">Summary</p>
- <TABLE >
- <TR>
- <TD class="pass">pass</TD>
- <TD>
- <xsl:value-of select="TestResult/Summary/@pass"/>
- </TD>
- </TR>
- <TR>
- <TD class="failed">failed</TD>
- <TD>
- <xsl:value-of select="TestResult/Summary/@failed"/>
- </TD>
- </TR>
- <TR>
- <TD class="timeout">timeout</TD>
- <TD>
- <xsl:value-of select="TestResult/Summary/@timeout"/>
- </TD>
- </TR>
- <TR>
- <TD class="notrun">notrun</TD>
- <TD>
- <xsl:value-of select="TestResult/Summary/@notrun"/>
- </TD>
- </TR>
- </TABLE>
- <!-- test package -->
- <xsl:for-each select="TestResult/TestPackage">
- <p class="head1">
- TestPackage:
- <xsl:value-of select="@name"/>
- </p>
-
- <TABLE border="0.1">
- <!-- level 1 test suite -->
- <xsl:for-each select="TestSuite">
- <TR>
- <TD class="gray">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="gray"></TD>
- <TD class="gray"></TD>
- <TD class="gray"></TD>
- <TD class="gray"></TD>
- </TR>
- <xsl:for-each select="TestCase">
- <TR>
- <TD></TD>
- <TD class="gray">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="gray"></TD>
- <TD class="gray"></TD>
- <TD class="gray"></TD>
- </TR>
- <xsl:for-each select="Test">
- <TR>
- <TD></TD>
- <TD></TD>
-
- <xsl:if test="@result='pass'">
- <TD class="pass">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="pass">
- <xsl:value-of select="@result"/>
- </TD>
- </xsl:if>
-
- <xsl:if test="@result='fail'">
- <TD class="failed">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="failed">
- <xsl:value-of select="@result"/>
- </TD>
- </xsl:if>
-
- <xsl:if test="@result='timeout'">
- <TD class="timeout">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="timeout">
- <xsl:value-of select="@result"/>
- </TD>
- </xsl:if>
-
- <xsl:if test="@result='notrun'">
- <TD class="notrun">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="notrun">
- <xsl:value-of select="@result"/>
- </TD>
- </xsl:if>
-
- <TD></TD>
- </TR>
- </xsl:for-each>
- </xsl:for-each>
- <!-- level 2 test suite -->
- <xsl:for-each select="TestSuite">
- <TR>
- <TD></TD>
- <TD class="gray">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="gray"></TD>
- <TD class="gray"></TD>
- <TD class="gray"></TD>
- </TR>
- <xsl:for-each select="TestCase">
- <TR>
- <TD></TD>
- <TD></TD>
- <TD class="gray">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="gray"></TD>
- <TD class="gray"></TD>
- </TR>
- <xsl:for-each select="Test">
- <TR>
- <TD></TD>
- <TD></TD>
- <TD></TD>
-
- <xsl:if test="@result='pass'">
- <TD class="pass">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="pass">
- <xsl:value-of select="@result"/>
- </TD>
- </xsl:if>
-
- <xsl:if test="@result='fail'">
- <TD class="failed">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="failed">
- <xsl:value-of select="@result"/>
- </TD>
- </xsl:if>
-
- <xsl:if test="@result='timeout'">
- <TD class="timeout">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="timeout">
- <xsl:value-of select="@result"/>
- </TD>
- </xsl:if>
-
- <xsl:if test="@result='notrun'">
- <TD class="notrun">
- <xsl:value-of select="@name"/>
- </TD>
- <TD class="notrun">
- <xsl:value-of select="@result"/>
- </TD>
- </xsl:if>
-
- </TR>
- </xsl:for-each>
- </xsl:for-each>
-
- </xsl:for-each>
- </xsl:for-each>
- </TABLE>
- </xsl:for-each>
- <!-- end test package -->
- </body>
- </html>
- </xsl:template>
-</xsl:stylesheet>
diff --git a/tests/jni/android_net_cts_NetlinkSocket.cpp b/tests/jni/android_net_cts_NetlinkSocket.cpp
index 1e671c6..f2fc38f 100644
--- a/tests/jni/android_net_cts_NetlinkSocket.cpp
+++ b/tests/jni/android_net_cts_NetlinkSocket.cpp
@@ -31,7 +31,7 @@
{
int sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
if (sock == -1) {
- LOGE("Can't create socket %s", strerror(errno));
+ ALOGE("Can't create socket %s", strerror(errno));
jclass SocketException = env->FindClass("java/net/SocketException");
env->ThrowNew(SocketException, "Can't create socket");
return;
diff --git a/tests/src/android/webkit/cts/CtsTestServer.java b/tests/src/android/webkit/cts/CtsTestServer.java
index 6d3bfe6..69be105 100755
--- a/tests/src/android/webkit/cts/CtsTestServer.java
+++ b/tests/src/android/webkit/cts/CtsTestServer.java
@@ -554,15 +554,20 @@
" <head>" +
" <title>Waiting</title>" +
" <script>" +
- " function updateTitle() { document.title = \"Done\"; }" +
- " window.applicationCache.onnoupdate = updateTitle;" +
- " window.applicationCache.oncached = updateTitle;" +
- " window.applicationCache.onupdateready = updateTitle;" +
- " window.applicationCache.onobsolete = updateTitle;" +
- " window.applicationCache.onerror = updateTitle;" +
+ " function updateTitle(x) { document.title = x; }" +
+ " window.applicationCache.onnoupdate = " +
+ " function() { updateTitle(\"onnoupdate Callback\"); };" +
+ " window.applicationCache.oncached = " +
+ " function() { updateTitle(\"oncached Callback\"); };" +
+ " window.applicationCache.onupdateready = " +
+ " function() { updateTitle(\"onupdateready Callback\"); };" +
+ " window.applicationCache.onobsolete = " +
+ " function() { updateTitle(\"onobsolete Callback\"); };" +
+ " window.applicationCache.onerror = " +
+ " function() { updateTitle(\"onerror Callback\"); };" +
" </script>" +
" </head>" +
- " <body>AppCache test</body>" +
+ " <body onload=\"updateTitle('Loaded');\">AppCache test</body>" +
"</html>"));
} else if (path.equals(APPCACHE_MANIFEST_PATH)) {
response = createResponse(HttpStatus.SC_OK);
diff --git a/tests/src/android/webkit/cts/WaitForLoadUrl.java b/tests/src/android/webkit/cts/WaitForLoadUrl.java
deleted file mode 100644
index 7ccd6d2..0000000
--- a/tests/src/android/webkit/cts/WaitForLoadUrl.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit.cts;
-
-import android.cts.util.PollingCheck;
-import android.graphics.Bitmap;
-import android.graphics.Picture;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.test.InstrumentationTestCase;
-import android.webkit.WebChromeClient;
-import android.webkit.WebView;
-import android.webkit.WebView.PictureListener;
-import android.webkit.WebViewClient;
-
-import junit.framework.Assert;
-
-/**
- * This class is used to determine when a page has finished loading.
- *
- * initializeWebView sets a WebViewClient, WebChromeClient, and a
- * PictureListener. If a tests provides its own handler, it must call
- * the corresponding WaitForLoadUrl.on* function.
- *
- * This class only really works correctly with a single WebView active because
- * it acts as a singleton.
- */
-class WaitForLoadUrl extends WebViewClient {
- private static final WaitForLoadUrl sInstance = new WaitForLoadUrl();
-
- /**
- * The maximum time, in milliseconds (10 seconds) to wait for a load
- * to be triggered.
- */
- private static final long LOAD_TIMEOUT = 10000;
-
- /**
- * Set to true after onPageFinished is called.
- */
- private boolean mLoaded;
-
- /**
- * Set to true after onNewPicture is called. Reset when onPageFinished
- * is called.
- */
- private boolean mNewPicture;
-
- /**
- * The progress, in percentage, of the page load. Valid values are between
- * 0 and 100.
- */
- private int mProgress;
-
- /**
- * Private constructor enforces singleton behavior.
- */
- private WaitForLoadUrl() {
- }
-
- /**
- * Returns the singleton instance.
- */
- public static WaitForLoadUrl getInstance() {
- return sInstance;
- }
-
- /**
- * Called from WaitForNewPicture, this is used to indicate that
- * the page has been drawn.
- */
- synchronized public void onNewPicture() {
- mNewPicture = true;
- this.notifyAll();
- }
-
- /**
- * Called from WaitForLoadedClient, this is used to clear the picture
- * draw state so that draws before the URL begins loading don't count.
- */
- synchronized public void onPageStarted() {
- mNewPicture = false; // Earlier paints won't count.
- }
-
- /**
- * Called from WaitForLoadedClient, this is used to indicate that
- * the page is loaded, but not drawn yet.
- */
- synchronized public void onPageFinished() {
- mLoaded = true;
- this.notifyAll();
- }
-
- /**
- * Called from the WebChrome client, this sets the current progress
- * for a page.
- * @param progress The progress made so far between 0 and 100.
- */
- synchronized public void onProgressChanged(int progress) {
- mProgress = progress;
- this.notifyAll();
- }
-
- /**
- * Sets the WebViewClient, WebChromeClient, and PictureListener for a
- * WebView to prepare it for the waitForLoadComplete call. If one
- * of these handlers needs to be changed, the onPageFinished,
- * onProgressChanged, or onNewPicture must be called from the callback
- * class.
- */
- public void initializeWebView(InstrumentationTestCase test,
- final WebView view) {
- Runnable setup = new Runnable() {
- @Override
- public void run() {
- view.setWebViewClient(new WaitForLoadedClient());
- view.setPictureListener(new WaitForNewPicture());
- view.setWebChromeClient(new WaitForProgressClient());
- }
- };
- if (isUiThread()) {
- setup.run();
- } else {
- try {
- test.runTestOnUiThread(setup);
- } catch (Throwable t) {
- Assert.fail("Error initializing WebView for waitForLoadUrl");
- }
- }
- clearLoad();
- }
-
- /**
- * Called whenever a load has been completed so that a subsequent call to
- * waitForLoadComplete doesn't return immediately. This must be called only
- * after onPageFinished is received for a loadUrl call or else a callback
- * will change the state before a subsequent load begins and
- * waitForLoadComplete will not work properly. Normally this call is not
- * necessary as it is automatically called as part of waitFor.
- */
- synchronized public void clearLoad() {
- mLoaded = false;
- mNewPicture = false;
- mProgress = 0;
- }
-
- /**
- * Wait for a page onPageFinished, onNewPicture and
- * onProgressChange to reach 100. If that does not occur
- * before LOAD_TIMEOUT expires there will be a test failure.
- *
- * This call may be made on the UI thread or a test thread.
- * @see WaitForLoadUrl#initializeWebView
- */
- public void waitForLoadComplete(WebView webView) {
- waitFor(webView, new WaitCheck() {
- @Override
- public boolean isDone() {
- return mLoaded && mNewPicture && mProgress == 100;
- }
- });
- }
-
- /**
- * Waits for the waitCheck condition to be true or the test times out.
- * The load state is cleared after waiting.
- * @param webView The WebView for which the test is running.
- * @param waitCheck Contains the condition to be checked.
- */
- private void waitFor(WebView webView, WaitCheck waitCheck) {
- if (isUiThread()) {
- waitOnUiThread(webView, waitCheck);
- } else {
- waitOnTestThread(waitCheck);
- }
- clearLoad();
- }
-
- /**
- * Uses a polling mechanism, while pumping messages to check when the
- * waitCheck condition is true.
- * @param webView The WebView for which the test is running.
- * @param waitCheck Contains the condition to be checked.
- */
- private void waitOnUiThread(final WebView webView,
- final WaitCheck waitCheck) {
- new PollingCheck(LOAD_TIMEOUT) {
- @Override
- protected boolean check() {
- pumpMessages(webView);
- synchronized(this) {
- return waitCheck.isDone();
- }
- }
- }.run();
- }
-
- /**
- * Uses a wait/notify to check when the waitCheck condition is true.
- * @param webView The WebView for which the test is running.
- * @param waitCheck Contains the condition to be checked.
- */
- private synchronized void waitOnTestThread(WaitCheck waitCheck) {
- try {
- long waitEnd = SystemClock.uptimeMillis() + LOAD_TIMEOUT;
- long timeRemaining = LOAD_TIMEOUT;
- while (!waitCheck.isDone() && timeRemaining > 0) {
- this.wait(timeRemaining);
- timeRemaining = waitEnd - SystemClock.uptimeMillis();
- }
- } catch (InterruptedException e) {
- // We'll just drop out of the loop and fail
- }
- Assert.assertTrue("Load failed to complete before timeout",
- waitCheck.isDone());
- }
-
- /**
- * Pumps all currently-queued messages in the UI thread and then exits.
- * This is useful to force processing while running tests in the UI thread.
- */
- private static void pumpMessages(WebView webView) {
- class ExitLoopException extends RuntimeException {
- }
-
- // Force loop to exit when processing this. Loop.quit() doesn't
- // work because this is the main Loop.
- webView.getHandler().post(new Runnable() {
- @Override
- public void run() {
- throw new ExitLoopException(); // exit loop!
- }
- });
- try {
- // Pump messages until our message gets through.
- Looper.loop();
- } catch (ExitLoopException e) {
- }
- }
-
- /**
- * Returns true if the current thread is the UI thread based on the
- * Looper.
- */
- private static boolean isUiThread() {
- return (Looper.myLooper() == Looper.getMainLooper());
- }
-
- private interface WaitCheck {
- public boolean isDone();
- }
-
- /**
- * A WebChromeClient used to capture the onProgressChanged for use
- * in waitFor functions. If a test must override the WebChromeClient,
- * it can derive from this class or call WaitForLoadUrl.onProgressChanged
- * directly.
- */
- public static class WaitForProgressClient extends WebChromeClient {
- @Override
- public void onProgressChanged(WebView view, int newProgress) {
- super.onProgressChanged(view, newProgress);
- WaitForLoadUrl.getInstance().onProgressChanged(newProgress);
- }
- }
-
- /**
- * A WebViewClient that captures the onPageFinished for use in
- * waitFor functions. Using initializeWebView sets the WaitForLoadedClient
- * into the WebView. If a test needs to set a specific WebViewClient and
- * needs the waitForLoadComplete capability then it should derive from
- * WaitForLoadedClient or call WaitForLoadUrl.onPageFinished.
- */
- public static class WaitForLoadedClient extends WebViewClient {
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
- WaitForLoadUrl.getInstance().onPageFinished();
- }
-
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- super.onPageStarted(view, url, favicon);
- WaitForLoadUrl.getInstance().onPageStarted();
- }
- }
-
- /**
- * A PictureListener that captures the onNewPicture for use in
- * waitForLoadComplete. Using initializeWebView sets the PictureListener
- * into the WebView. If a test needs to set a specific PictureListener and
- * needs the waitForLoadComplete capability then it should call
- * WaitForLoadUrl.onNewPicture.
- */
- private static class WaitForNewPicture implements PictureListener {
- @Override
- public void onNewPicture(WebView view, Picture picture) {
- WaitForLoadUrl.getInstance().onNewPicture();
- }
- }
-}
\ No newline at end of file
diff --git a/tests/src/android/webkit/cts/WebViewOnUiThread.java b/tests/src/android/webkit/cts/WebViewOnUiThread.java
index 8b81463..c9dc914 100644
--- a/tests/src/android/webkit/cts/WebViewOnUiThread.java
+++ b/tests/src/android/webkit/cts/WebViewOnUiThread.java
@@ -16,43 +16,131 @@
package android.webkit.cts;
+import android.cts.util.PollingCheck;
import android.graphics.Bitmap;
+import android.graphics.Picture;
+import android.graphics.Rect;
+import android.os.Bundle;
import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
import android.test.InstrumentationTestCase;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.webkit.DownloadListener;
import android.webkit.WebBackForwardList;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
+import android.webkit.WebView.HitTestResult;
+import android.webkit.WebView.PictureListener;
import android.webkit.WebViewClient;
import junit.framework.Assert;
+import java.io.File;
+
/**
* Many tests need to run WebView code in the UI thread. This class
- * wraps a WebView so that calls are ensured to arrive on the UI Thread.
+ * wraps a WebView so that calls are ensured to arrive on the UI thread.
+ *
+ * All methods may be run on either the UI thread or test thread.
*/
public class WebViewOnUiThread {
+ /**
+ * The maximum time, in milliseconds (10 seconds) to wait for a load
+ * to be triggered.
+ */
+ private static final long LOAD_TIMEOUT = 10000;
+
+ /**
+ * Set to true after onPageFinished is called.
+ */
+ private boolean mLoaded;
+
+ /**
+ * Set to true after onNewPicture is called. Reset when onPageStarted
+ * is called.
+ */
+ private boolean mNewPicture;
+
+ /**
+ * The progress, in percentage, of the page load. Valid values are between
+ * 0 and 100.
+ */
+ private int mProgress;
+
+ /**
+ * The test that this class is being used in. Used for runTestOnUiThread.
+ */
private InstrumentationTestCase mTest;
+
+ /**
+ * The WebView that calls will be made on.
+ */
private WebView mWebView;
/**
* Initializes the webView with a WebViewClient, WebChromeClient,
- * and PictureListener as per WaitForLoadUrl.initializeWebView
- * to prepare for loadUrl.
+ * and PictureListener to prepare for loadUrlAndWaitForCompletion.
*
- * This method should be called during setUp so as to reinitialize
- * between calls.
+ * A new WebViewOnUiThread should be called during setUp so as to
+ * reinitialize between calls.
*
* @param test The test in which this is being run.
* @param webView The webView that the methods should call.
- * @see WaitForLoadUrl#initializeWebView
* @see loadUrlAndWaitForCompletion
*/
public WebViewOnUiThread(InstrumentationTestCase test, WebView webView) {
mTest = test;
mWebView = webView;
- WaitForLoadUrl.getInstance().initializeWebView(mTest, mWebView);
+ final WebViewClient webViewClient = new WaitForLoadedClient(this);
+ final WebChromeClient webChromeClient = new WaitForProgressClient(this);
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.setWebViewClient(webViewClient);
+ mWebView.setWebChromeClient(webChromeClient);
+ mWebView.setPictureListener(new WaitForNewPicture());
+ }
+ });
+ }
+
+ /**
+ * Called from WaitForNewPicture, this is used to indicate that
+ * the page has been drawn.
+ */
+ synchronized public void onNewPicture() {
+ mNewPicture = true;
+ this.notifyAll();
+ }
+
+ /**
+ * Called from WaitForLoadedClient, this is used to clear the picture
+ * draw state so that draws before the URL begins loading don't count.
+ */
+ synchronized public void onPageStarted() {
+ mNewPicture = false; // Earlier paints won't count.
+ }
+
+ /**
+ * Called from WaitForLoadedClient, this is used to indicate that
+ * the page is loaded, but not drawn yet.
+ */
+ synchronized public void onPageFinished() {
+ mLoaded = true;
+ this.notifyAll();
+ }
+
+ /**
+ * Called from the WebChrome client, this sets the current progress
+ * for a page.
+ * @param progress The progress made so far between 0 and 100.
+ */
+ synchronized public void onProgressChanged(int progress) {
+ mProgress = progress;
+ this.notifyAll();
}
public void setWebViewClient(final WebViewClient webViewClient) {
@@ -73,6 +161,33 @@
});
}
+ public void setPictureListener(final PictureListener pictureListener) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.setPictureListener(pictureListener);
+ }
+ });
+ }
+
+ public void setDownloadListener(final DownloadListener listener) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.setDownloadListener(listener);
+ }
+ });
+ }
+
+ public void setBackgroundColor(final int color) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.setBackgroundColor(color);
+ }
+ });
+ }
+
public void clearCache(final boolean includeDiskFiles) {
runOnUiThread(new Runnable() {
@Override
@@ -109,20 +224,92 @@
});
}
- public void reload() {
+ public void removeJavascriptInterface(final String interfaceName) {
runOnUiThread(new Runnable() {
@Override
public void run() {
- mWebView.reload();
+ mWebView.removeJavascriptInterface(interfaceName);
}
});
}
- public void loadUrl(final String url) {
+ public void addJavascriptInterface(final Object object, final String name) {
runOnUiThread(new Runnable() {
@Override
public void run() {
- mWebView.loadUrl(url);
+ mWebView.addJavascriptInterface(object, name);
+ }
+ });
+ }
+
+ public void flingScroll(final int vx, final int vy) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.flingScroll(vx, vy);
+ }
+ });
+ }
+
+ public void requestFocusNodeHref(final Message hrefMsg) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.requestFocusNodeHref(hrefMsg);
+ }
+ });
+ }
+
+ public void requestImageRef(final Message msg) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.requestImageRef(msg);
+ }
+ });
+ }
+
+ public void setInitialScale(final int scaleInPercent) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.setInitialScale(scaleInPercent);
+ }
+ });
+ }
+
+ public void clearSslPreferences() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.clearSslPreferences();
+ }
+ });
+ }
+
+ public void resumeTimers() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.resumeTimers();
+ }
+ });
+ }
+
+ public void findNext(final boolean forward) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.findNext(forward);
+ }
+ });
+ }
+
+ public void clearMatches() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.clearMatches();
}
});
}
@@ -134,125 +321,262 @@
* @param url The URL to load.
*/
public void loadUrlAndWaitForCompletion(final String url) {
- runOnUiThread(new Runnable() {
+ callAndWait(new Runnable() {
@Override
public void run() {
mWebView.loadUrl(url);
}
});
- WaitForLoadUrl.getInstance().waitForLoadComplete(mWebView);
}
- public String getTitle() {
- class TitleGetter implements Runnable {
- private String mTitle;
-
+ public void loadDataAndWaitForCompletion(final String data,
+ final String mimeType, final String encoding) {
+ callAndWait(new Runnable() {
@Override
public void run() {
- mTitle = mWebView.getTitle();
+ mWebView.loadData(data, mimeType, encoding);
}
-
- public String getTitle() {
- return mTitle;
- }
- }
- TitleGetter titleGetter = new TitleGetter();
- runOnUiThread(titleGetter);
- return titleGetter.getTitle();
+ });
}
- public WebSettings getSettings() {
- class SettingsGetter implements Runnable {
- private WebSettings mWebSettings;
-
+ public void loadDataWithBaseURLAndWaitForCompletion(final String baseUrl,
+ final String data, final String mimeType, final String encoding,
+ final String historyUrl) {
+ callAndWait(new Runnable() {
@Override
public void run() {
- mWebSettings = mWebView.getSettings();
+ mWebView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding,
+ historyUrl);
}
-
- public WebSettings getSettings() {
- return mWebSettings;
- }
- }
-
- SettingsGetter settingsGetter = new SettingsGetter();
- runOnUiThread(settingsGetter);
- return settingsGetter.getSettings();
- }
-
- public WebBackForwardList copyBackForwardList() {
- class BackForwardCopier implements Runnable {
- private WebBackForwardList mBackForwardList;
-
- @Override
- public void run() {
- mBackForwardList = mWebView.copyBackForwardList();
- }
-
- public WebBackForwardList getBackForwardList() {
- return mBackForwardList;
- }
- }
- BackForwardCopier backForwardCopier = new BackForwardCopier();
- runOnUiThread(backForwardCopier);
- return backForwardCopier.getBackForwardList();
+ });
}
/**
- * @see android.webkit.WebView.WebView#
+ * Reloads a page and waits for it to complete reloading. Use reload
+ * if it is a form resubmission and the onFormResubmission responds
+ * by telling WebView not to resubmit it.
*/
- public Bitmap getFavicon() {
- class FaviconGetter implements Runnable {
- private Bitmap mFavicon;
-
+ public void reloadAndWaitForCompletion() {
+ callAndWait(new Runnable() {
@Override
public void run() {
- mFavicon = mWebView.getFavicon();
+ mWebView.reload();
}
+ });
+ }
- public Bitmap getFavicon() {
- return mFavicon;
+ /**
+ * Reload the previous URL. Use reloadAndWaitForCompletion unless
+ * it is a form resubmission and the onFormResubmission responds
+ * by telling WebView not to resubmit it.
+ */
+ public void reload() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mWebView.reload();
}
+ });
+ }
+
+ /**
+ * Use this only when JavaScript causes a page load to wait for the
+ * page load to complete. Otherwise use loadUrlAndWaitForCompletion or
+ * similar functions.
+ */
+ public void waitForLoadCompletion() {
+ if (isUiThread()) {
+ waitOnUiThread();
+ } else {
+ waitOnTestThread();
}
- FaviconGetter favIconGetter = new FaviconGetter();
- runOnUiThread(favIconGetter);
- return favIconGetter.getFavicon();
+ clearLoad();
+ }
+
+ public String getTitle() {
+ return getValue(new ValueGetter<String>() {
+ @Override
+ public String capture() {
+ return mWebView.getTitle();
+ }
+ });
+ }
+
+ public WebSettings getSettings() {
+ return getValue(new ValueGetter<WebSettings>() {
+ @Override
+ public WebSettings capture() {
+ return mWebView.getSettings();
+ }
+ });
+ }
+
+ public WebBackForwardList copyBackForwardList() {
+ return getValue(new ValueGetter<WebBackForwardList>() {
+ @Override
+ public WebBackForwardList capture() {
+ return mWebView.copyBackForwardList();
+ }
+ });
+ }
+
+ public Bitmap getFavicon() {
+ return getValue(new ValueGetter<Bitmap>() {
+ @Override
+ public Bitmap capture() {
+ return mWebView.getFavicon();
+ }
+ });
}
public String getUrl() {
- class UrlGetter implements Runnable {
- private String mUrl;
-
+ return getValue(new ValueGetter<String>() {
@Override
- public void run() {
- mUrl = mWebView.getUrl();
+ public String capture() {
+ return mWebView.getUrl();
}
-
- public String getUrl() {
- return mUrl;
- }
- }
- UrlGetter urlGetter = new UrlGetter();
- runOnUiThread(urlGetter);
- return urlGetter.getUrl();
+ });
}
public int getProgress() {
- class ProgressGetter implements Runnable {
- private int mProgress;
-
+ return getValue(new ValueGetter<Integer>() {
@Override
- public void run() {
- mProgress = mWebView.getProgress();
+ public Integer capture() {
+ return mWebView.getProgress();
}
+ });
+ }
- public int getProgress() {
- return mProgress;
+ public int getHeight() {
+ return getValue(new ValueGetter<Integer>() {
+ @Override
+ public Integer capture() {
+ return mWebView.getHeight();
}
- }
- ProgressGetter progressGetter = new ProgressGetter();
- runOnUiThread(progressGetter);
- return progressGetter.getProgress();
+ });
+ }
+
+ public int getContentHeight() {
+ return getValue(new ValueGetter<Integer>() {
+ @Override
+ public Integer capture() {
+ return mWebView.getContentHeight();
+ }
+ });
+ }
+
+ public boolean savePicture(final Bundle b, final File dest) {
+ return getValue(new ValueGetter<Boolean>() {
+ @Override
+ public Boolean capture() {
+ return mWebView.savePicture(b, dest);
+ }
+ });
+ }
+
+ public boolean pageUp(final boolean top) {
+ return getValue(new ValueGetter<Boolean>() {
+ @Override
+ public Boolean capture() {
+ return mWebView.pageUp(top);
+ }
+ });
+ }
+
+ public boolean pageDown(final boolean bottom) {
+ return getValue(new ValueGetter<Boolean>() {
+ @Override
+ public Boolean capture() {
+ return mWebView.pageDown(bottom);
+ }
+ });
+ }
+
+ public int[] getLocationOnScreen() {
+ final int[] location = new int[2];
+ return getValue(new ValueGetter<int[]>() {
+ @Override
+ public int[] capture() {
+ mWebView.getLocationOnScreen(location);
+ return location;
+ }
+ });
+ }
+
+ public float getScale() {
+ return getValue(new ValueGetter<Float>() {
+ @Override
+ public Float capture() {
+ return mWebView.getScale();
+ }
+ });
+ }
+
+ public boolean requestFocus(final int direction,
+ final Rect previouslyFocusedRect) {
+ return getValue(new ValueGetter<Boolean>() {
+ @Override
+ public Boolean capture() {
+ return mWebView.requestFocus(direction, previouslyFocusedRect);
+ }
+ });
+ }
+
+ public HitTestResult getHitTestResult() {
+ return getValue(new ValueGetter<HitTestResult>() {
+ @Override
+ public HitTestResult capture() {
+ return mWebView.getHitTestResult();
+ }
+ });
+ }
+
+ public int getScrollX() {
+ return getValue(new ValueGetter<Integer>() {
+ @Override
+ public Integer capture() {
+ return mWebView.getScrollX();
+ }
+ });
+ }
+
+ public int getScrollY() {
+ return getValue(new ValueGetter<Integer>() {
+ @Override
+ public Integer capture() {
+ return mWebView.getScrollY();
+ }
+ });
+ }
+
+ public final DisplayMetrics getDisplayMetrics() {
+ return getValue(new ValueGetter<DisplayMetrics>() {
+ @Override
+ public DisplayMetrics capture() {
+ return mWebView.getContext().getResources().getDisplayMetrics();
+ }
+ });
+ }
+
+ public boolean requestChildRectangleOnScreen(final View child,
+ final Rect rect,
+ final boolean immediate) {
+ return getValue(new ValueGetter<Boolean>() {
+ @Override
+ public Boolean capture() {
+ return mWebView.requestChildRectangleOnScreen(child, rect,
+ immediate);
+ }
+ });
+ }
+
+ public int findAll(final String find) {
+ return getValue(new ValueGetter<Integer>() {
+ @Override
+ public Integer capture() {
+ return mWebView.findAll(find);
+ }
+ });
}
/**
@@ -271,7 +595,8 @@
mTest.runTestOnUiThread(r);
}
} catch (Throwable t) {
- Assert.fail("Unexpected error while running on UI thread.");
+ Assert.fail("Unexpected error while running on UI thread: "
+ + t.getMessage());
}
}
@@ -283,6 +608,26 @@
return mWebView;
}
+ private <T> T getValue(ValueGetter<T> getter) {
+ runOnUiThread(getter);
+ return getter.getValue();
+ }
+
+ private abstract class ValueGetter<T> implements Runnable {
+ private T mValue;
+
+ @Override
+ public void run() {
+ mValue = capture();
+ }
+
+ protected abstract T capture();
+
+ public T getValue() {
+ return mValue;
+ }
+ }
+
/**
* Returns true if the current thread is the UI thread based on the
* Looper.
@@ -290,4 +635,150 @@
private static boolean isUiThread() {
return (Looper.myLooper() == Looper.getMainLooper());
}
+
+ /**
+ * @return Whether or not the load has finished.
+ */
+ private synchronized boolean isLoaded() {
+ return mLoaded && mNewPicture && mProgress == 100;
+ }
+
+ /**
+ * Makes a WebView call, waits for completion and then resets the
+ * load state in preparation for the next load call.
+ * @param call The call to make on the UI thread prior to waiting.
+ */
+ private void callAndWait(Runnable call) {
+ Assert.assertTrue("WebViewOnUiThread.load*AndWaitForCompletion calls "
+ + "may not be mixed with load* calls directly on WebView "
+ + "without calling waitForLoadCompletion after the load",
+ !mLoaded);
+ runOnUiThread(call);
+ waitForLoadCompletion();
+ }
+
+ /**
+ * Called whenever a load has been completed so that a subsequent call to
+ * waitForLoadCompletion doesn't return immediately.
+ */
+ synchronized private void clearLoad() {
+ mLoaded = false;
+ mNewPicture = false;
+ mProgress = 0;
+ }
+
+ /**
+ * Uses a polling mechanism, while pumping messages to check when the
+ * load completes.
+ */
+ private void waitOnUiThread() {
+ new PollingCheck(LOAD_TIMEOUT) {
+ @Override
+ protected boolean check() {
+ pumpMessages();
+ return isLoaded();
+ }
+ }.run();
+ }
+
+ /**
+ * Uses a wait/notify to check when the load completes.
+ */
+ private synchronized void waitOnTestThread() {
+ try {
+ long waitEnd = SystemClock.uptimeMillis() + LOAD_TIMEOUT;
+ long timeRemaining = LOAD_TIMEOUT;
+ while (!isLoaded() && timeRemaining > 0) {
+ this.wait(timeRemaining);
+ timeRemaining = waitEnd - SystemClock.uptimeMillis();
+ }
+ } catch (InterruptedException e) {
+ // We'll just drop out of the loop and fail
+ }
+ Assert.assertTrue("Load failed to complete before timeout", isLoaded());
+ }
+
+ /**
+ * Pumps all currently-queued messages in the UI thread and then exits.
+ * This is useful to force processing while running tests in the UI thread.
+ */
+ private void pumpMessages() {
+ class ExitLoopException extends RuntimeException {
+ }
+
+ // Force loop to exit when processing this. Loop.quit() doesn't
+ // work because this is the main Loop.
+ mWebView.getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ throw new ExitLoopException(); // exit loop!
+ }
+ });
+ try {
+ // Pump messages until our message gets through.
+ Looper.loop();
+ } catch (ExitLoopException e) {
+ }
+ }
+
+ /**
+ * A WebChromeClient used to capture the onProgressChanged for use
+ * in waitFor functions. If a test must override the WebChromeClient,
+ * it can derive from this class or call onProgressChanged
+ * directly.
+ */
+ public static class WaitForProgressClient extends WebChromeClient {
+ private WebViewOnUiThread mOnUiThread;
+
+ public WaitForProgressClient(WebViewOnUiThread onUiThread) {
+ mOnUiThread = onUiThread;
+ }
+
+ @Override
+ public void onProgressChanged(WebView view, int newProgress) {
+ super.onProgressChanged(view, newProgress);
+ mOnUiThread.onProgressChanged(newProgress);
+ }
+ }
+
+ /**
+ * A WebViewClient that captures the onPageFinished for use in
+ * waitFor functions. Using initializeWebView sets the WaitForLoadedClient
+ * into the WebView. If a test needs to set a specific WebViewClient and
+ * needs the waitForCompletion capability then it should derive from
+ * WaitForLoadedClient or call WebViewOnUiThread.onPageFinished.
+ */
+ public static class WaitForLoadedClient extends WebViewClient {
+ private WebViewOnUiThread mOnUiThread;
+
+ public WaitForLoadedClient(WebViewOnUiThread onUiThread) {
+ mOnUiThread = onUiThread;
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
+ mOnUiThread.onPageFinished();
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ super.onPageStarted(view, url, favicon);
+ mOnUiThread.onPageStarted();
+ }
+ }
+
+ /**
+ * A PictureListener that captures the onNewPicture for use in
+ * waitForLoadCompletion. Using initializeWebView sets the PictureListener
+ * into the WebView. If a test needs to set a specific PictureListener and
+ * needs the waitForCompletion capability then it should call
+ * WebViewOnUiThread.onNewPicture.
+ */
+ private class WaitForNewPicture implements PictureListener {
+ @Override
+ public void onNewPicture(WebView view, Picture picture) {
+ WebViewOnUiThread.this.onNewPicture();
+ }
+ }
}
diff --git a/tests/tests/acceleration/Android.mk b/tests/tests/acceleration/Android.mk
index 3e2acac..93c4d51 100644
--- a/tests/tests/acceleration/Android.mk
+++ b/tests/tests/acceleration/Android.mk
@@ -30,4 +30,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/accessibilityservice/Android.mk b/tests/tests/accessibilityservice/Android.mk
index 71b7537..4cac305 100644
--- a/tests/tests/accessibilityservice/Android.mk
+++ b/tests/tests/accessibilityservice/Android.mk
@@ -34,4 +34,4 @@
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/accounts/Android.mk b/tests/tests/accounts/Android.mk
index d9e142b..2806bbe 100644
--- a/tests/tests/accounts/Android.mk
+++ b/tests/tests/accounts/Android.mk
@@ -29,5 +29,4 @@
LOCAL_PACKAGE_NAME := CtsAccountManagerTestCases
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/admin/Android.mk b/tests/tests/admin/Android.mk
index 3228d85..8c71e0c 100644
--- a/tests/tests/admin/Android.mk
+++ b/tests/tests/admin/Android.mk
@@ -30,4 +30,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/animation/Android.mk b/tests/tests/animation/Android.mk
index ed9874e..95cc614 100644
--- a/tests/tests/animation/Android.mk
+++ b/tests/tests/animation/Android.mk
@@ -30,5 +30,5 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/app/Android.mk b/tests/tests/app/Android.mk
index a9b75df..b3aae14 100644
--- a/tests/tests/app/Android.mk
+++ b/tests/tests/app/Android.mk
@@ -29,4 +29,4 @@
LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/bluetooth/Android.mk b/tests/tests/bluetooth/Android.mk
index d1bb4ec..94c6c19 100644
--- a/tests/tests/bluetooth/Android.mk
+++ b/tests/tests/bluetooth/Android.mk
@@ -32,4 +32,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/content/Android.mk b/tests/tests/content/Android.mk
index a2f0e0f..ae2aee8 100644
--- a/tests/tests/content/Android.mk
+++ b/tests/tests/content/Android.mk
@@ -29,5 +29,4 @@
LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/database/Android.mk b/tests/tests/database/Android.mk
index b565854..85cbe1b 100644
--- a/tests/tests/database/Android.mk
+++ b/tests/tests/database/Android.mk
@@ -31,5 +31,4 @@
LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/dpi/Android.mk b/tests/tests/dpi/Android.mk
index ffbe8a3..2f256c4 100644
--- a/tests/tests/dpi/Android.mk
+++ b/tests/tests/dpi/Android.mk
@@ -30,7 +30,7 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
# ============================================================
diff --git a/tests/tests/dpi/AndroidManifest.xml b/tests/tests/dpi/AndroidManifest.xml
index 562579a..6e141ac 100644
--- a/tests/tests/dpi/AndroidManifest.xml
+++ b/tests/tests/dpi/AndroidManifest.xml
@@ -21,7 +21,7 @@
<application>
<uses-library android:name="android.test.runner" />
- <activity android:name="android.dpi.cts.ConfigurationScreenLayoutActivity"
+ <activity android:name="android.dpi.cts.OrientationActivity"
android:configChanges="orientation" />
</application>
diff --git a/tests/tests/dpi/src/android/dpi/cts/AspectRatioTest.java b/tests/tests/dpi/src/android/dpi/cts/AspectRatioTest.java
new file mode 100644
index 0000000..74a9f22
--- /dev/null
+++ b/tests/tests/dpi/src/android/dpi/cts/AspectRatioTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.dpi.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.WindowManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AspectRatioTest extends ActivityInstrumentationTestCase2<OrientationActivity> {
+
+ private static final int[] ORIENTATIONS = new int[] {
+ ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,
+ ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,
+ };
+
+ public AspectRatioTest() {
+ super(OrientationActivity.class);
+ }
+
+ /**
+ * Get all the aspect rations in different orientations. They could be
+ * different due to the system bar being different sizes. Test that
+ * one of the aspect ratios is within the range.
+ */
+ public void testAspectRatio() throws Exception {
+ List<Double> aspectRatios = getAllAspectRatios();
+ for (double aspectRatio : aspectRatios) {
+ if (aspectRatio >= 1.333 && aspectRatio <= 1.86) {
+ return;
+ }
+ }
+ fail("Aspect ratios were not between 1.333 and 1.86: " + aspectRatios);
+ }
+
+ private List<Double> getAllAspectRatios() throws Exception {
+ List<Double> aspectRatios = new ArrayList<Double>();
+ for (int i = 0; i < ORIENTATIONS.length; i++) {
+ Activity activity = startOrientationActivity(ORIENTATIONS[i]);
+ aspectRatios.add(getAspectRatio(activity));
+ tearDown();
+ }
+ return aspectRatios;
+ }
+
+ private double getAspectRatio(Context context) {
+ WindowManager windowManager =
+ (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ Display display = windowManager.getDefaultDisplay();
+ DisplayMetrics metrics = new DisplayMetrics();
+ display.getMetrics(metrics);
+
+ int max = Math.max(metrics.widthPixels, metrics.heightPixels);
+ int min = Math.min(metrics.widthPixels, metrics.heightPixels);
+ return (double) max / min;
+ }
+
+ private Activity startOrientationActivity(int orientation) {
+ Intent intent = new Intent();
+ intent.putExtra(OrientationActivity.EXTRA_ORIENTATION, orientation);
+ setActivityIntent(intent);
+ return getActivity();
+ }
+}
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java
index 9fce9f1..d4c3611 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutTest.java
@@ -27,7 +27,7 @@
import android.view.WindowManager;
public class ConfigurationScreenLayoutTest
- extends ActivityInstrumentationTestCase2<ConfigurationScreenLayoutActivity> {
+ extends ActivityInstrumentationTestCase2<OrientationActivity> {
private static final int[] ORIENTATIONS = new int[] {
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,
@@ -37,7 +37,7 @@
};
public ConfigurationScreenLayoutTest() {
- super(ConfigurationScreenLayoutActivity.class);
+ super(OrientationActivity.class);
}
public void testScreenLayout() throws Exception {
@@ -82,7 +82,7 @@
private Activity startOrientationActivity(int orientation) {
Intent intent = new Intent();
- intent.putExtra(ConfigurationScreenLayoutActivity.EXTRA_ORIENTATION, orientation);
+ intent.putExtra(OrientationActivity.EXTRA_ORIENTATION, orientation);
setActivityIntent(intent);
return getActivity();
}
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
index df254d2..937d8f8 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
@@ -46,12 +46,6 @@
double density = 160.0d * metrics.density;
assertTrue("Screen density must be at least 100 dpi: " + density, density >= 100.0d);
- int max = Math.max(metrics.widthPixels, metrics.heightPixels);
- int min = Math.min(metrics.widthPixels, metrics.heightPixels);
- double aspectRatio = (double) max / min;
- assertTrue("Aspect ratio must be between 1.333 and 1.86. It was " + aspectRatio,
- aspectRatio >= 1.333 && aspectRatio <= 1.86);
-
Set<Integer> allowedDensities = new HashSet<Integer>();
allowedDensities.add(DisplayMetrics.DENSITY_LOW);
allowedDensities.add(DisplayMetrics.DENSITY_MEDIUM);
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutActivity.java b/tests/tests/dpi/src/android/dpi/cts/OrientationActivity.java
similarity index 94%
rename from tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutActivity.java
rename to tests/tests/dpi/src/android/dpi/cts/OrientationActivity.java
index d4d268d..3bd76b6 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationScreenLayoutActivity.java
+++ b/tests/tests/dpi/src/android/dpi/cts/OrientationActivity.java
@@ -22,7 +22,7 @@
import android.view.WindowManager;
/** {@link Activity} that calls {@link #setRequestedOrientation(int)} with the extra value. */
-public class ConfigurationScreenLayoutActivity extends Activity {
+public class OrientationActivity extends Activity {
static final String EXTRA_ORIENTATION = "orientation";
diff --git a/tests/tests/dpi2/Android.mk b/tests/tests/dpi2/Android.mk
index 9dadcf9..cc11256 100644
--- a/tests/tests/dpi2/Android.mk
+++ b/tests/tests/dpi2/Android.mk
@@ -33,4 +33,4 @@
# doesn't currently support setting LOCAL_SDK_VERSION to anything but
# current.
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/drm/Android.mk b/tests/tests/drm/Android.mk
index 61e1f10..6e6ba56 100644
--- a/tests/tests/drm/Android.mk
+++ b/tests/tests/drm/Android.mk
@@ -32,4 +32,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/effect/Android.mk b/tests/tests/effect/Android.mk
index 990a86a..075dc82 100644
--- a/tests/tests/effect/Android.mk
+++ b/tests/tests/effect/Android.mk
@@ -31,4 +31,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/example/Android.mk b/tests/tests/example/Android.mk
index d32f59b..7e2d841 100644
--- a/tests/tests/example/Android.mk
+++ b/tests/tests/example/Android.mk
@@ -32,4 +32,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/gesture/Android.mk b/tests/tests/gesture/Android.mk
index 22aeaec..f4fa8b3 100755
--- a/tests/tests/gesture/Android.mk
+++ b/tests/tests/gesture/Android.mk
@@ -29,5 +29,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/graphics/Android.mk b/tests/tests/graphics/Android.mk
index d0ebd37..9575dd3 100644
--- a/tests/tests/graphics/Android.mk
+++ b/tests/tests/graphics/Android.mk
@@ -32,5 +32,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index 42c5f58..169fb56 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -1247,6 +1247,18 @@
assertMeasureText(text, textChars, textSpan, 4, 7, widths[4] + widths[5] + widths[6]);
}
+ public void testMeasureTextWithLongText() {
+ final int MAX_COUNT = 65535;
+ char[] longText = new char[MAX_COUNT];
+ for (int n = 0; n < MAX_COUNT; n++) {
+ longText[n] = 'm';
+ }
+
+ Paint p = new Paint();
+ float width = p.measureText(longText, 0, 1);
+ assertEquals(true, width > 0);
+ }
+
/** Tests that all four overloads of measureText are the same and match some value. */
private void assertMeasureText(String text, char[] textChars, SpannedString textSpan,
int start, int end, float expectedWidth) {
diff --git a/tests/tests/hardware/Android.mk b/tests/tests/hardware/Android.mk
index dd3b72f..dd769fa 100644
--- a/tests/tests/hardware/Android.mk
+++ b/tests/tests/hardware/Android.mk
@@ -29,5 +29,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/holo/Android.mk b/tests/tests/holo/Android.mk
index 22afc85..513fb20 100644
--- a/tests/tests/holo/Android.mk
+++ b/tests/tests/holo/Android.mk
@@ -32,4 +32,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view.png
index 99d23a7..74819ce 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view.png b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view.png
index bf1aaa5..355b200 100644
--- a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialog_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_dialog_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_dialog_minwidth_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_minwidth_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_inputmethod_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_inputmethod_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_inputmethod_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_inputmethod_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_darkactionbar_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_darkactionbar_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_darkactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_darkactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_minwidth_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_fullscreen_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_panel_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_light_panel_calendar_view.png
index 16deb8f..65d5ecb 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_light_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_fullscreen_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_notitlebar_calendar_view.png b/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_notitlebar_calendar_view.png
index 884bfc0..15c14ed 100644
--- a/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_notitlebar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_notitlebar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view.png
index 3b86863..551bd2e 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view.png b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view.png
index 50d00ab..89c37c5 100644
--- a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_minwidth_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_inputmethod_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_inputmethod_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_inputmethod_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_inputmethod_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_darkactionbar_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_darkactionbar_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_darkactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_darkactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_minwidth_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_fullscreen_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_panel_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_panel_calendar_view.png
index 4d4616b..f02a0f6 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_light_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_fullscreen_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_panel_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_panel_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_notitlebar_calendar_view.png b/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_notitlebar_calendar_view.png
index 9029d16..b3fc31e 100644
--- a/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_notitlebar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_notitlebar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_minwidth_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_inputmethod_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_inputmethod_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_inputmethod_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_inputmethod_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_darkactionbar_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_darkactionbar_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_darkactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_darkactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_minwidth_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_minwidth_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_fullscreen_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_panel_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_panel_calendar_view.png
index 0e2ee26..c076d50 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_light_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_fullscreen_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_fullscreen_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_fullscreen_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_fullscreen_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_panel_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_panel_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_panel_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_panel_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_calendar_view.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_notitlebar_calendar_view.png b/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_notitlebar_calendar_view.png
index 7fb7333..21585b3 100644
--- a/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_notitlebar_calendar_view.png
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_notitlebar_calendar_view.png
Binary files differ
diff --git a/tests/tests/jni/Android.mk b/tests/tests/jni/Android.mk
index 0f9f88b..c8c92fd 100644
--- a/tests/tests/jni/Android.mk
+++ b/tests/tests/jni/Android.mk
@@ -34,7 +34,7 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
# Include the associated library's makefile.
-include $(LOCAL_PATH)/libjnitest/Android.mk
\ No newline at end of file
+include $(LOCAL_PATH)/libjnitest/Android.mk
diff --git a/tests/tests/jni/libjnitest/helper.c b/tests/tests/jni/libjnitest/helper.c
index f974a59..831d5b5 100644
--- a/tests/tests/jni/libjnitest/helper.c
+++ b/tests/tests/jni/libjnitest/helper.c
@@ -58,7 +58,7 @@
JniTestFunction *function = va_arg(args, JniTestFunction *);
- LOGI("running %s", name);
+ ALOGI("running %s", name);
char *oneResult = function(env);
if (oneResult != NULL) {
diff --git a/tests/tests/jni/libjnitest/register.c b/tests/tests/jni/libjnitest/register.c
index d68b536..66eb265 100644
--- a/tests/tests/jni/libjnitest/register.c
+++ b/tests/tests/jni/libjnitest/register.c
@@ -32,25 +32,25 @@
extern int register_InstanceNonce(JNIEnv *);
if (register_InstanceNonce(env)) {
- LOGE("failed to register InstanceNonce");
+ ALOGE("failed to register InstanceNonce");
return JNI_ERR;
}
extern int register_StaticNonce(JNIEnv *);
if (register_StaticNonce(env)) {
- LOGE("failed to register StaticNonce");
+ ALOGE("failed to register StaticNonce");
return JNI_ERR;
}
extern int register_JniCTest(JNIEnv *);
if (register_JniCTest(env)) {
- LOGE("failed to register JniCTest");
+ ALOGE("failed to register JniCTest");
return JNI_ERR;
}
extern int register_JniCppTest(JNIEnv *);
if (register_JniCppTest(env)) {
- LOGE("failed to register JniCppTest");
+ ALOGE("failed to register JniCppTest");
return JNI_ERR;
}
diff --git a/tests/tests/location/Android.mk b/tests/tests/location/Android.mk
index d63d911..b53aaa0 100644
--- a/tests/tests/location/Android.mk
+++ b/tests/tests/location/Android.mk
@@ -32,5 +32,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index df1de12..1a14f83 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -32,5 +32,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/ndef/Android.mk b/tests/tests/ndef/Android.mk
index 4cb0b78..13e5624 100644
--- a/tests/tests/ndef/Android.mk
+++ b/tests/tests/ndef/Android.mk
@@ -31,4 +31,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/net/Android.mk b/tests/tests/net/Android.mk
index 1fd9ba0..1f1e387 100644
--- a/tests/tests/net/Android.mk
+++ b/tests/tests/net/Android.mk
@@ -32,5 +32,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/openglperf/Android.mk b/tests/tests/openglperf/Android.mk
index 0663c73..571bbd7 100644
--- a/tests/tests/openglperf/Android.mk
+++ b/tests/tests/openglperf/Android.mk
@@ -27,8 +27,6 @@
LOCAL_PACKAGE_NAME := CtsOpenGlPerfTestCases
-# uncomment when dalvik.annotation.Test* are removed or part of SDK
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index 35cafb9..54ebc4a 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -32,4 +32,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/permission/Android.mk b/tests/tests/permission/Android.mk
index c1f7f4d..5d251de 100644
--- a/tests/tests/permission/Android.mk
+++ b/tests/tests/permission/Android.mk
@@ -30,6 +30,6 @@
# uncomment when dalvik test annotations are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 96c6171..bdb4776 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -192,6 +192,8 @@
private static final Set<String> OTHER_RANDOM_DIRECTORIES = new HashSet<String>(
Arrays.asList(
"/app-cache/ciq/socket",
+ "/cache/fotapkg",
+ "/cache/fotapkg/tmp",
"/data/anr",
"/data/app",
"/data/app-private",
@@ -199,6 +201,7 @@
"/data/btips",
"/data/btips/TI",
"/data/btips/TI/opp",
+ "/data/calibration",
"/data/dalvik-cache",
"/data/data",
"/data/data/.drm",
@@ -221,8 +224,12 @@
"/data/data/recovery",
"/data/dontpanic",
"/data/drm",
+ "/data/drm/fwdlock",
+ "/data/drm/IDM",
+ "/data/drm/IDM/HTTP",
"/data/drm/rights",
"/data/dump",
+ "/data/hwvefs",
"/data/htcfs",
"/data/local",
"/data/local/tmp",
@@ -234,10 +241,17 @@
"/data/misc/dhcp",
"/data/misc/wifi",
"/data/misc/wifi/sockets",
+ "/data/misc/wpa_supplicant",
"/data/property",
+ "/data/radio",
"/data/secure",
+ "/data/sensors",
"/data/shared",
+ "/data/simcom",
+ "/data/simcom/btadd",
+ "/data/simcom/simlog",
"/data/system",
+ "/data/wapi",
"/data/wifi",
"/data/wiper",
"/data/wpstiles",
diff --git a/tests/tests/permission2/Android.mk b/tests/tests/permission2/Android.mk
index 9c62245..09fd104 100755
--- a/tests/tests/permission2/Android.mk
+++ b/tests/tests/permission2/Android.mk
@@ -27,5 +27,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/preference/Android.mk b/tests/tests/preference/Android.mk
index 886c166..7816c3b 100644
--- a/tests/tests/preference/Android.mk
+++ b/tests/tests/preference/Android.mk
@@ -30,4 +30,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/provider/Android.mk b/tests/tests/provider/Android.mk
index c33d98a..fba7cda 100644
--- a/tests/tests/provider/Android.mk
+++ b/tests/tests/provider/Android.mk
@@ -29,5 +29,4 @@
LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
index 717b468..7d78bd6 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
@@ -16,10 +16,6 @@
package android.provider.cts;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
@@ -27,7 +23,6 @@
import android.provider.MediaStore;
import android.test.InstrumentationTestCase;
-@TestTargetClass(MediaStore.class)
public class MediaStoreTest extends InstrumentationTestCase {
private static final String TEST_VOLUME_NAME = "volume_for_cts";
@@ -62,11 +57,7 @@
super.tearDown();
}
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getMediaScannerUri",
- args = {}
- )
+
public void testGetMediaScannerUri() {
ContentValues values = new ContentValues();
String selection = MediaStore.MEDIA_SCANNER_VOLUME + "=?";
@@ -93,4 +84,9 @@
assertEquals(1, mContentResolver.delete(mScannerUri, null, null));
assertNull(mContentResolver.query(mScannerUri, PROJECTION, null, null, null));
}
+
+ public void testGetVersion() {
+ // Could be a version string or null...just check it doesn't blow up.
+ MediaStore.getVersion(getInstrumentation().getTargetContext());
+ }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
index 4e343cc..1138233 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
@@ -16,20 +16,18 @@
package android.provider.cts;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.ToBeFixed;
-
import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.net.Uri;
import android.provider.MediaStore.Audio.Genres;
+import android.provider.MediaStore.Audio.Media;
+import android.provider.MediaStore.Audio.Genres.Members;
+import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
import android.test.InstrumentationTestCase;
-@TestTargetClass(Genres.class)
public class MediaStore_Audio_GenresTest extends InstrumentationTestCase {
private ContentResolver mContentResolver;
@@ -40,14 +38,6 @@
mContentResolver = getInstrumentation().getContext().getContentResolver();
}
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getContentUri",
- args = {String.class}
- )
- @ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. There is no "
- + "document related to the possible values of param volumeName. @throw clause "
- + "should be added in to javadoc when getting uri for internal volume.")
public void testGetContentUri() {
assertNotNull(mContentResolver.query(
Genres.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME), null, null,
@@ -103,4 +93,44 @@
Uri uri = mContentResolver.insert(Genres.INTERNAL_CONTENT_URI, values);
assertNull(uri);
}
+
+ public void testGetContentUriForAudioId() {
+ // Insert an audio file into the content provider.
+ ContentValues values = Audio1.getInstance().getContentValues(true);
+ Uri audioUri = mContentResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
+ long audioId = ContentUris.parseId(audioUri);
+ assertTrue(audioId != -1);
+
+ // Insert a genre into the content provider.
+ values.clear();
+ values.put(Genres.NAME, "Soda Pop");
+ Uri genreUri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
+ long genreId = ContentUris.parseId(genreUri);
+ assertTrue(genreId != -1);
+
+ Cursor cursor = null;
+ try {
+ String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
+
+ // Check that the audio file has no genres yet.
+ Uri audioGenresUri = Genres.getContentUriForAudioId(volumeName, (int) audioId);
+ cursor = mContentResolver.query(audioGenresUri, null, null, null, null);
+ assertFalse(cursor.moveToNext());
+
+ // Link the audio file to the genre.
+ values.clear();
+ values.put(Members.AUDIO_ID, audioId);
+ Uri membersUri = Members.getContentUri(volumeName, genreId);
+ assertNotNull(mContentResolver.insert(membersUri, values));
+
+ // Check that the audio file has the genre it was linked to.
+ cursor = mContentResolver.query(audioGenresUri, null, null, null, null);
+ assertTrue(cursor.moveToNext());
+ assertEquals(genreId, cursor.getLong(cursor.getColumnIndex(Genres._ID)));
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
new file mode 100644
index 0000000..9432066
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.cts;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.MediaStore;
+import android.provider.MediaStore.MediaColumns;
+import android.test.AndroidTestCase;
+
+public class MediaStore_FilesTest extends AndroidTestCase {
+
+ private ContentResolver mResolver;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResolver = mContext.getContentResolver();
+ }
+
+ public void testGetContentUri() {
+ String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
+ Uri allFilesUri = MediaStore.Files.getContentUri(volumeName);
+
+ // Get the current file count. We will check if this increases after
+ // adding a file to the provider.
+ int fileCount = getFileCount(allFilesUri);
+
+ // Check that inserting empty values causes an exception.
+ ContentValues values = new ContentValues();
+ try {
+ mResolver.insert(allFilesUri, values);
+ fail("Should throw an exception");
+ } catch (IllegalArgumentException e) {
+ // Expecting an exception
+ }
+
+ // Add a path for a file and check that the returned uri appends a
+ // path properly.
+ String dataPath = "does_not_really_exist.txt";
+ values.put(MediaColumns.DATA, dataPath);
+ Uri fileUri = mResolver.insert(allFilesUri, values);
+ long fileId = ContentUris.parseId(fileUri);
+ assertEquals(fileUri, ContentUris.withAppendedId(allFilesUri, fileId));
+
+ // Check that getContentUri with the file id produces the same url
+ Uri rowUri = MediaStore.Files.getContentUri(volumeName, fileId);
+ assertEquals(fileUri, rowUri);
+
+ // Check that the file count has increased.
+ int newFileCount = getFileCount(allFilesUri);
+ assertEquals(fileCount + 1, newFileCount);
+
+ // Check that the path we inserted was stored properly.
+ assertStringColumn(fileUri, MediaColumns.DATA, dataPath);
+
+ // Update the path and check that the database changed.
+ String updatedPath = "still_does_not_exist.txt";
+ values.put(MediaColumns.DATA, updatedPath);
+ assertEquals(1, mResolver.update(fileUri, values, null, null));
+ assertStringColumn(fileUri, MediaColumns.DATA, updatedPath);
+
+ // Delete the file and observe that the file count decreased.
+ assertEquals(1, mResolver.delete(fileUri, null, null));
+ assertEquals(fileCount, getFileCount(allFilesUri));
+
+ // Make sure the deleted file is not returned by the cursor.
+ Cursor cursor = mResolver.query(fileUri, null, null, null, null);
+ try {
+ assertFalse(cursor.moveToNext());
+ } finally {
+ cursor.close();
+ }
+ }
+
+ private int getFileCount(Uri uri) {
+ Cursor cursor = mResolver.query(uri, null, null, null, null);
+ try {
+ return cursor.getCount();
+ } finally {
+ cursor.close();
+ }
+ }
+
+ private void assertStringColumn(Uri fileUri, String columnName, String expectedValue) {
+ Cursor cursor = mResolver.query(fileUri, null, null, null, null);
+ try {
+ assertTrue(cursor.moveToNext());
+ int index = cursor.getColumnIndexOrThrow(columnName);
+ assertEquals(expectedValue, cursor.getString(index));
+ } finally {
+ cursor.close();
+ }
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/SearchRecentSuggestionsTest.java b/tests/tests/provider/src/android/provider/cts/SearchRecentSuggestionsTest.java
index 13ef4c8..a17bcdd 100644
--- a/tests/tests/provider/src/android/provider/cts/SearchRecentSuggestionsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SearchRecentSuggestionsTest.java
@@ -16,11 +16,6 @@
package android.provider.cts;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
@@ -30,7 +25,6 @@
import android.provider.SearchRecentSuggestions;
import android.test.ProviderTestCase2;
-@TestTargetClass(android.provider.SearchRecentSuggestions.class)
public class SearchRecentSuggestionsTest extends
ProviderTestCase2<TestSearchRecentSuggestionsProvider> {
private final static String AUTHORITY_HEAD = "content://"
@@ -38,14 +32,14 @@
private Uri mTestUri;
private TestSearchRecentSuggestionsProvider mTestSRSProvider;
- private Context mContext;
+ private Context mProviderContext;
@Override
public void setUp() throws Exception {
super.setUp();
mTestUri = Uri.parse(AUTHORITY_HEAD + "/suggestions");
mTestSRSProvider = getProvider();
- mContext = mTestSRSProvider.getContext();
+ mProviderContext = mTestSRSProvider.getContext();
}
public SearchRecentSuggestionsTest() {
@@ -53,40 +47,13 @@
TestSearchRecentSuggestionsProvider.AUTHORITY);
}
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "SearchRecentSuggestions",
- args = {android.content.Context.class, java.lang.String.class, int.class}
- )
public void testConstructor() {
- new SearchRecentSuggestions(mContext, TestSearchRecentSuggestionsProvider.AUTHORITY,
+ new SearchRecentSuggestions(mProviderContext, TestSearchRecentSuggestionsProvider.AUTHORITY,
TestSearchRecentSuggestionsProvider.MODE);
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "SearchRecentSuggestions",
- args = {android.content.Context.class, java.lang.String.class, int.class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "saveRecentQuery",
- args = {java.lang.String.class, java.lang.String.class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "clearHistory",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "truncateHistory",
- args = {android.content.ContentResolver.class, int.class}
- )
- })
public void testSearchRecentSuggestions() {
- MySearchRecentSuggestions srs = new MySearchRecentSuggestions(mContext,
+ SearchRecentSuggestions srs = new MySearchRecentSuggestions(mProviderContext,
TestSearchRecentSuggestionsProvider.AUTHORITY,
TestSearchRecentSuggestionsProvider.MODE);
Cursor c = mTestSRSProvider.query(mTestUri, null, null, null, null);
@@ -123,8 +90,8 @@
waitForCursorCount(mTestUri, null, 3);
// truncateHistory will delete the oldest one record
- ContentResolver cr = mContext.getContentResolver();
- srs.truncateHistory(cr, 2);
+ ContentResolver cr = mProviderContext.getContentResolver();
+ ((MySearchRecentSuggestions) srs).truncateHistory(cr, 2);
waitForCursorCount(mTestUri, SearchRecentSuggestions.QUERIES_PROJECTION_2LINE, 2);
@@ -220,6 +187,7 @@
super(context, authority, mode);
}
+ @Override
protected void truncateHistory(ContentResolver cr, int maxEntries) {
super.truncateHistory(cr, maxEntries);
}
@@ -228,6 +196,7 @@
private void waitForCursorCount(final Uri uri, final String[] projection,
final int expectedCount) {
new PollingCheck() {
+ @Override
protected boolean check() {
Cursor cursor = null;
try {
diff --git a/tests/tests/renderscript/Android.mk b/tests/tests/renderscript/Android.mk
index fc64614..d2137e2 100644
--- a/tests/tests/renderscript/Android.mk
+++ b/tests/tests/renderscript/Android.mk
@@ -34,4 +34,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/sax/Android.mk b/tests/tests/sax/Android.mk
index 749588a..9dc1847 100644
--- a/tests/tests/sax/Android.mk
+++ b/tests/tests/sax/Android.mk
@@ -29,4 +29,4 @@
LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index 6ea5e1b..ef13886 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -28,4 +28,4 @@
LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/speech/Android.mk b/tests/tests/speech/Android.mk
index 932c564..225acf3 100755
--- a/tests/tests/speech/Android.mk
+++ b/tests/tests/speech/Android.mk
@@ -31,5 +31,4 @@
LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/telephony/Android.mk b/tests/tests/telephony/Android.mk
index 6ccc9b3..de5c2ac 100644
--- a/tests/tests/telephony/Android.mk
+++ b/tests/tests/telephony/Android.mk
@@ -33,5 +33,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
# #LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/text/Android.mk b/tests/tests/text/Android.mk
index 5c44027..1ffeee9 100644
--- a/tests/tests/text/Android.mk
+++ b/tests/tests/text/Android.mk
@@ -32,5 +32,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/util/Android.mk b/tests/tests/util/Android.mk
index cc65d12..d66e5e4 100644
--- a/tests/tests/util/Android.mk
+++ b/tests/tests/util/Android.mk
@@ -32,5 +32,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/view/Android.mk b/tests/tests/view/Android.mk
index 037ae9a..4d82d91 100644
--- a/tests/tests/view/Android.mk
+++ b/tests/tests/view/Android.mk
@@ -29,5 +29,4 @@
LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/webkit/Android.mk b/tests/tests/webkit/Android.mk
index f739b42..1426dbb 100644
--- a/tests/tests/webkit/Android.mk
+++ b/tests/tests/webkit/Android.mk
@@ -32,5 +32,4 @@
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
index 6b4e93f..9a54ace 100644
--- a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
@@ -19,7 +19,7 @@
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.HttpAuthHandler;
import android.webkit.WebView;
-import android.webkit.cts.WaitForLoadUrl.WaitForLoadedClient;
+import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -126,7 +126,7 @@
CtsTestServer.getReasonString(HttpStatus.SC_UNAUTHORIZED), mOnUiThread.getTitle());
}
- private static class MyWebViewClient extends WaitForLoadedClient {
+ private class MyWebViewClient extends WaitForLoadedClient {
String realm;
boolean useHttpAuthUsernamePassword;
@@ -136,6 +136,7 @@
private int mAuthCount;
MyWebViewClient(boolean proceed, String user, String password) {
+ super(mOnUiThread);
mProceed = proceed;
mUser = user;
mPassword = password;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
index 0c66fac..c0a597b 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
@@ -25,7 +25,7 @@
import android.webkit.WebIconDatabase;
import android.webkit.WebSettings;
import android.webkit.WebView;
-import android.webkit.cts.WaitForLoadUrl.WaitForProgressClient;
+import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -77,7 +77,7 @@
mOnUiThread.setWebChromeClient(webChromeClient);
assertFalse(webChromeClient.hadOnProgressChanged());
- mOnUiThread.loadUrl(TestHtmlConstants.HELLO_WORLD_URL);
+ mOnUiThread.loadUrlAndWaitForCompletion(TestHtmlConstants.HELLO_WORLD_URL);
new PollingCheck(TEST_TIMEOUT) {
@Override
@@ -100,7 +100,7 @@
assertFalse(webChromeClient.hadOnReceivedTitle());
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- mOnUiThread.loadUrl(url);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
new PollingCheck(TEST_TIMEOUT) {
@Override
@@ -138,7 +138,7 @@
assertFalse(webChromeClient.hadOnReceivedIcon());
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- mOnUiThread.loadUrl(url);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
new PollingCheck(TEST_TIMEOUT) {
@Override
@@ -178,7 +178,8 @@
// load a page that opens a child window, requests focus for the child and sets a timeout
// after which the child will be closed
- mOnUiThread.loadUrl(mWebServer.getAssetUrl(TestHtmlConstants.JS_WINDOW_URL));
+ mOnUiThread.loadUrlAndWaitForCompletion(mWebServer.
+ getAssetUrl(TestHtmlConstants.JS_WINDOW_URL));
new PollingCheck(TEST_TIMEOUT) {
@Override
@@ -243,7 +244,7 @@
assertFalse(webChromeClient.hadOnJsAlert());
String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_ALERT_URL);
- mOnUiThread.loadUrl(url);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
new PollingCheck(TEST_TIMEOUT) {
@Override
@@ -272,7 +273,7 @@
assertFalse(webChromeClient.hadOnJsConfirm());
String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_CONFIRM_URL);
- mOnUiThread.loadUrl(url);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
new PollingCheck(TEST_TIMEOUT) {
@Override
@@ -303,7 +304,7 @@
final String promptResult = "CTS";
webChromeClient.setPromptResult(promptResult);
String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_PROMPT_URL);
- mOnUiThread.loadUrl(url);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
new PollingCheck(TEST_TIMEOUT) {
@Override
@@ -336,6 +337,10 @@
private boolean mHadOnRequestFocus;
private boolean mHadOnReceivedIcon;
+ public MockWebChromeClient() {
+ super(mOnUiThread);
+ }
+
public void setPromptResult(String promptResult) {
mPromptResult = promptResult;
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 668a767..386b214 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -1014,11 +1014,46 @@
args = {}
)
})
- public void testSetAppCacheEnabled() throws Exception {
- // Tests that when AppCache is enabled and used, but the database path
- // is not set or is set to an inaccessible path, the WebView does not crash.
+ public void testAppCacheDisabled() throws Throwable {
+ // Test that when AppCache is disabled, we don't get any AppCache
+ // callbacks.
startWebServer();
- String url = mWebServer.getAppCacheUrl();
+ final String url = mWebServer.getAppCacheUrl();
+ mSettings.setJavaScriptEnabled(true);
+
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
+ new PollingCheck(WEBVIEW_TIMEOUT) {
+ protected boolean check() {
+ return "Loaded".equals(mOnUiThread.getTitle());
+ }
+ }.run();
+ // The page is now loaded. Wait for a further 1s to check no AppCache
+ // callbacks occur.
+ Thread.sleep(1000);
+ assertEquals("Loaded", mOnUiThread.getTitle());
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setAppCacheEnabled",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "setAppCachePath",
+ args = {}
+ )
+ })
+ public void testAppCacheEnabled() throws Throwable {
+ // Note that the AppCache path can only be set once. This limits the
+ // amount of testing we can do, and means that we must test all aspects
+ // of setting the AppCache path in a single test to guarantee ordering.
+
+ // Test that when AppCache is enabled but no valid path is provided,
+ // we don't get any AppCache callbacks.
+ startWebServer();
+ final String url = mWebServer.getAppCacheUrl();
mSettings.setAppCacheEnabled(true);
mSettings.setJavaScriptEnabled(true);
@@ -1026,16 +1061,23 @@
new PollingCheck(WEBVIEW_TIMEOUT) {
@Override
protected boolean check() {
- return mOnUiThread.getTitle() != null && mOnUiThread.getTitle().equals("Done");
+ return "Loaded".equals(mOnUiThread.getTitle());
}
}.run();
+ // The page is now loaded. Wait for a further 1s to check no AppCache
+ // callbacks occur.
+ Thread.sleep(1000);
+ assertEquals("Loaded", mOnUiThread.getTitle());
- mSettings.setAppCachePath("/data/foo");
+ // Test that when AppCache is enabled and a valid path is provided, we
+ // get an AppCache callback of some kind.
+ mSettings.setAppCachePath(getActivity().getDir("appcache", 0).getPath());
mOnUiThread.loadUrlAndWaitForCompletion(url);
new PollingCheck(WEBVIEW_TIMEOUT) {
@Override
protected boolean check() {
- return mOnUiThread.getTitle() != null && mOnUiThread.getTitle().equals("Done");
+ return mOnUiThread.getTitle() != null
+ && mOnUiThread.getTitle().endsWith("Callback");
}
}.run();
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index c448aad..9d65200 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -25,7 +25,7 @@
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.webkit.cts.WaitForLoadUrl.WaitForLoadedClient;
+import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
@@ -95,7 +95,7 @@
assertFalse(webViewClient.hasOnPageStartedCalled());
assertFalse(webViewClient.hasOnLoadResourceCalled());
assertFalse(webViewClient.hasOnPageFinishedCalled());
- mOnUiThread.loadUrl(url);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
new PollingCheck(TEST_TIMEOUT) {
@Override
@@ -151,7 +151,8 @@
String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_FORM_URL);
// this loads a form, which automatically posts itself
mOnUiThread.loadUrlAndWaitForCompletion(url);
- Thread.sleep(1000); // allow for javascript to post the form
+ // wait for JavaScript to post the form
+ mOnUiThread.waitForLoadCompletion();
// the URL should have changed when the form was posted
assertFalse(url.equals(mOnUiThread.getUrl()));
// reloading the current URL should trigger the callback
@@ -264,6 +265,10 @@
private boolean mOnUnhandledKeyEventCalled;
private boolean mOnScaleChangedCalled;
+ public MockWebViewClient() {
+ super(mOnUiThread);
+ }
+
public boolean hasOnPageStartedCalled() {
return mOnPageStartedCalled;
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index b95c448..f121f2a 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -38,7 +38,6 @@
import android.test.UiThreadTest;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -55,8 +54,8 @@
import android.webkit.WebView.PictureListener;
import android.webkit.WebViewClient;
import android.webkit.WebViewDatabase;
-import android.webkit.cts.WaitForLoadUrl.WaitForLoadedClient;
-import android.webkit.cts.WaitForLoadUrl.WaitForProgressClient;
+import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
import android.widget.LinearLayout;
import dalvik.annotation.TestLevel;
@@ -79,19 +78,13 @@
private WebView mWebView;
private CtsTestServer mWebServer;
- private boolean mIsUiThreadDone;
+ private WebViewOnUiThread mOnUiThread;
public WebViewTest() {
super("com.android.cts.stub", WebViewStubActivity.class);
}
@Override
- public void runTestOnUiThread(Runnable runnable) throws Throwable {
- mIsUiThreadDone = false;
- super.runTestOnUiThread(runnable);
- }
-
- @Override
protected void setUp() throws Exception {
super.setUp();
mWebView = getActivity().getWebView();
@@ -99,22 +92,13 @@
if (f.exists()) {
f.delete();
}
- WaitForLoadUrl.getInstance().initializeWebView(this, mWebView);
+ mOnUiThread = new WebViewOnUiThread(this, mWebView);
}
@Override
protected void tearDown() throws Exception {
- try {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.clearHistory();
- mWebView.clearCache(true);
- }
- });
- } catch(Throwable t) {
- Log.w(LOGTAG, "tearDown(): Caught exception when posting Runnable to UI thread");
- }
+ mOnUiThread.clearHistory();
+ mOnUiThread.clearCache(true);
if (mWebServer != null) {
mWebServer.shutdown();
}
@@ -217,7 +201,7 @@
assertTrue(settings.supportZoom());
startWebServer(false);
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- assertLoadUrlSuccessfully(url);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
mWebView.invokeZoomPicker();
}
@@ -406,8 +390,7 @@
startWebServer(false);
String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- mWebView.loadUrl(url);
- waitForLoadComplete();
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
assertEquals(100, mWebView.getProgress());
assertEquals(url, mWebView.getUrl());
assertEquals(url, mWebView.getOriginalUrl());
@@ -426,39 +409,25 @@
args = {}
)
})
+ @UiThreadTest
public void testGetOriginalUrl() throws Throwable {
startWebServer(false);
final String finalUrl = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final String redirectUrl =
mWebServer.getRedirectingAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertNull(mWebView.getUrl());
- assertNull(mWebView.getOriginalUrl());
+ assertNull(mWebView.getUrl());
+ assertNull(mWebView.getOriginalUrl());
- // By default, WebView sends an intent to ask the system to
- // handle loading a new URL. We set a WebViewClient as
- // WebViewClient.shouldOverrideUrlLoading() returns false, so
- // the WebView will load the new URL.
- mWebView.setWebViewClient(new WaitForLoadedClient());
- mWebView.setWebChromeClient(new LoadCompleteWebChromeClient());
- mWebView.loadUrl(redirectUrl);
- }
- });
+ // By default, WebView sends an intent to ask the system to
+ // handle loading a new URL. We set a WebViewClient as
+ // WebViewClient.shouldOverrideUrlLoading() returns false, so
+ // the WebView will load the new URL.
+ mOnUiThread.setWebViewClient(new WaitForLoadedClient(mOnUiThread));
+ mOnUiThread.loadUrlAndWaitForCompletion(redirectUrl);
- // We need to yield the UI thread to allow the callback to
- // WebViewClient.shouldOverrideUrlLoading() to be made.
- waitForUiThreadDone();
-
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertEquals(finalUrl, mWebView.getUrl());
- assertEquals(redirectUrl, mWebView.getOriginalUrl());
- }
- });
+ assertEquals(finalUrl, mWebView.getUrl());
+ assertEquals(redirectUrl, mWebView.getOriginalUrl());
}
@TestTargetNew(
@@ -526,17 +495,17 @@
String url2 = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL2);
String url3 = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL3);
- assertLoadUrlSuccessfully(url1);
+ mOnUiThread.loadUrlAndWaitForCompletion(url1);
pollingCheckWebBackForwardList(url1, 0, 1);
assertGoBackOrForwardBySteps(false, -1);
assertGoBackOrForwardBySteps(false, 1);
- assertLoadUrlSuccessfully(url2);
+ mOnUiThread.loadUrlAndWaitForCompletion(url2);
pollingCheckWebBackForwardList(url2, 1, 2);
assertGoBackOrForwardBySteps(true, -1);
assertGoBackOrForwardBySteps(false, 1);
- assertLoadUrlSuccessfully(url3);
+ mOnUiThread.loadUrlAndWaitForCompletion(url3);
pollingCheckWebBackForwardList(url3, 2, 3);
assertGoBackOrForwardBySteps(true, -2);
assertGoBackOrForwardBySteps(false, 1);
@@ -608,7 +577,7 @@
startWebServer(false);
String url = mWebServer.getAssetUrl(TestHtmlConstants.ADD_JAVA_SCRIPT_INTERFACE_URL);
- assertLoadUrlSuccessfully(url);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
assertEquals("Original title", obj.waitForResult());
}
@@ -625,27 +594,27 @@
"<body onload=\"document.title = typeof window.injectedObject;\"></body></html>";
// Test that the property is initially undefined.
- mWebView.loadData(setTitleToPropertyTypeHtml, "text/html", null);
- waitForLoadComplete();
+ mOnUiThread.loadDataAndWaitForCompletion(setTitleToPropertyTypeHtml,
+ "text/html", null);
assertEquals("undefined", mWebView.getTitle());
// Test that adding a null object has no effect.
mWebView.addJavascriptInterface(null, "injectedObject");
- mWebView.loadData(setTitleToPropertyTypeHtml, "text/html", null);
- waitForLoadComplete();
+ mOnUiThread.loadDataAndWaitForCompletion(setTitleToPropertyTypeHtml,
+ "text/html", null);
assertEquals("undefined", mWebView.getTitle());
// Test that adding an object gives an object type.
final Object obj = new Object();
mWebView.addJavascriptInterface(obj, "injectedObject");
- mWebView.loadData(setTitleToPropertyTypeHtml, "text/html", null);
- waitForLoadComplete();
+ mOnUiThread.loadDataAndWaitForCompletion(setTitleToPropertyTypeHtml,
+ "text/html", null);
assertEquals("object", mWebView.getTitle());
// Test that trying to replace with a null object has no effect.
mWebView.addJavascriptInterface(null, "injectedObject");
- mWebView.loadData(setTitleToPropertyTypeHtml, "text/html", null);
- waitForLoadComplete();
+ mOnUiThread.loadDataAndWaitForCompletion(setTitleToPropertyTypeHtml,
+ "text/html", null);
assertEquals("object", mWebView.getTitle());
}
@@ -680,13 +649,13 @@
"</head><body onload=\"updateTitle();\"></body></html>";
mWebView.addJavascriptInterface(obj, name);
- mWebView.loadData(Uri.encode(setTitleToPropertyTypeHtml), "text/html", null);
- waitForLoadComplete();
+ mOnUiThread.loadDataAndWaitForCompletion(
+ Uri.encode(setTitleToPropertyTypeHtml), "text/html", null);
assertEquals("object", mWebView.getTitle());
mWebView.removeJavascriptInterface(name);
- mWebView.loadData(Uri.encode(setTitleToPropertyTypeHtml), "text/html", null);
- waitForLoadComplete();
+ mOnUiThread.loadDataAndWaitForCompletion(
+ Uri.encode(setTitleToPropertyTypeHtml), "text/html", null);
assertEquals("undefined", mWebView.getTitle());
}
}
@@ -705,14 +674,14 @@
// Test that adding an object gives an object type.
mWebView.addJavascriptInterface(new Object(), "injectedObject");
- mWebView.loadData(setTitleToPropertyTypeHtml, "text/html", null);
- waitForLoadComplete();
+ mOnUiThread.loadDataAndWaitForCompletion(setTitleToPropertyTypeHtml,
+ "text/html", null);
assertEquals("object", mWebView.getTitle());
// Test that reloading the page after removing the object leaves the property undefined.
mWebView.removeJavascriptInterface("injectedObject");
- mWebView.loadData(setTitleToPropertyTypeHtml, "text/html", null);
- waitForLoadComplete();
+ mOnUiThread.loadDataAndWaitForCompletion(setTitleToPropertyTypeHtml,
+ "text/html", null);
assertEquals("undefined", mWebView.getTitle());
}
@@ -728,13 +697,8 @@
return "removedObject";
}
public void remove() throws Throwable {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.removeJavascriptInterface("removedObject");
- System.gc();
- }
- });
+ mOnUiThread.removeJavascriptInterface("removedObject");
+ System.gc();
}
}
class ResultObject {
@@ -759,18 +723,13 @@
// Test that an object is still usable if removed while the page is in use, even if we have
// no external references to it.
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.getSettings().setJavaScriptEnabled(true);
- mWebView.addJavascriptInterface(new RemovedObject(), "removedObject");
- mWebView.addJavascriptInterface(resultObject, "resultObject");
- mWebView.loadData("<html><head></head>" +
- "<body onload=\"window.removedObject.remove();" +
- "resultObject.setResult(removedObject.toString());\"></body></html>",
- "text/html", null);
- }
- });
+ mOnUiThread.getSettings().setJavaScriptEnabled(true);
+ mOnUiThread.addJavascriptInterface(new RemovedObject(), "removedObject");
+ mOnUiThread.addJavascriptInterface(resultObject, "resultObject");
+ mOnUiThread.loadDataAndWaitForCompletion("<html><head></head>" +
+ "<body onload=\"window.removedObject.remove();" +
+ "resultObject.setResult(removedObject.toString());\"></body></html>",
+ "text/html", null);
assertEquals("removedObject", resultObject.getResult());
}
@@ -794,14 +753,8 @@
public void testCapturePicture() throws Exception, Throwable {
startWebServer(false);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.BLANK_PAGE_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- // showing the blank page will make the picture filled with background color
- mWebView.loadUrl(url);
- waitForLoadComplete();
- }
- });
+ // showing the blank page will make the picture filled with background color
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
getInstrumentation().waitForIdleSync();
class PictureRunnable implements Runnable {
@@ -816,8 +769,7 @@
assertBitmapFillWithColor(b, Color.WHITE);
mWebView.setBackgroundColor(Color.CYAN);
- mWebView.reload();
- waitForLoadComplete();
+ mOnUiThread.reloadAndWaitForCompletion();
}
public Picture getPicture() {
return mPicture;
@@ -860,7 +812,7 @@
public void onNewPicture(WebView view, Picture picture) {
// Need to inform the listener tracking new picture
// for the "page loaded" knowledge since it has been replaced.
- WaitForLoadUrl.getInstance().onNewPicture();
+ mOnUiThread.onNewPicture();
this.callCount += 1;
this.webView = view;
this.picture = picture;
@@ -870,13 +822,8 @@
final MyPictureListener listener = new MyPictureListener();
startWebServer(false);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setPictureListener(listener);
- assertLoadUrlSuccessfully(url);
- }
- });
+ mOnUiThread.setPictureListener(listener);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
new PollingCheck(TEST_TIMEOUT) {
@Override
protected boolean check() {
@@ -888,12 +835,7 @@
final int oldCallCount = listener.callCount;
final String newUrl = mWebServer.getAssetUrl(TestHtmlConstants.SMALL_IMG_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertLoadUrlSuccessfully(newUrl);
- }
- });
+ mOnUiThread.loadUrlAndWaitForCompletion(newUrl);
new PollingCheck(TEST_TIMEOUT) {
@Override
protected boolean check() {
@@ -924,12 +866,7 @@
mWebView.setBackgroundColor(Color.CYAN);
startWebServer(false);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.BLANK_PAGE_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertLoadUrlSuccessfully(url);
- }
- });
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
getInstrumentation().waitForIdleSync();
final Bundle bundle = new Bundle();
@@ -941,12 +878,7 @@
try {
assertTrue(bundle.isEmpty());
assertEquals(0, f.length());
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertTrue(mWebView.savePicture(bundle, f));
- }
- });
+ assertTrue(mOnUiThread.savePicture(bundle, f));
// File saving is done in a separate thread.
new PollingCheck() {
@@ -963,14 +895,8 @@
p.draw(new Canvas(b));
assertBitmapFillWithColor(b, Color.CYAN);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setBackgroundColor(Color.WHITE);
- mWebView.reload();
- waitForLoadComplete();
- }
- });
+ mOnUiThread.setBackgroundColor(Color.WHITE);
+ mOnUiThread.reloadAndWaitForCompletion();
getInstrumentation().waitForIdleSync();
runTestOnUiThread(new Runnable() {
@@ -1115,22 +1041,23 @@
)
})
public void testLoadData() throws Throwable {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertNull(mWebView.getTitle());
- mWebView.loadData("<html><head><title>Hello,World!</title></head><body></body>" +
- "</html>",
- "text/html", null);
- waitForLoadComplete();
- assertEquals("Hello,World!", mWebView.getTitle());
- }
- });
+ final String HTML_CONTENT =
+ "<html><head><title>Hello,World!</title></head><body></body>" +
+ "</html>";
+ assertNull(mOnUiThread.getTitle());
+ mOnUiThread.loadDataAndWaitForCompletion(HTML_CONTENT,
+ "text/html", null);
+ assertEquals("Hello,World!", mOnUiThread.getTitle());
// Test that JavaScript can't access cross-origin content.
class ConsoleMessageWebChromeClient extends WaitForProgressClient {
private boolean mIsMessageLevelAvailable;
private ConsoleMessage.MessageLevel mMessageLevel;
+
+ public ConsoleMessageWebChromeClient() {
+ super(mOnUiThread);
+ }
+
@Override
public synchronized boolean onConsoleMessage(ConsoleMessage message) {
mMessageLevel = message.messageLevel();
@@ -1155,8 +1082,9 @@
@Override
public void run() {
mWebView.getSettings().setJavaScriptEnabled(true);
- mWebView.setWebChromeClient(webChromeClient);
- mWebView.loadData("<html><head></head><body onload=\"" +
+ mOnUiThread.setWebChromeClient(webChromeClient);
+ mOnUiThread.loadDataAndWaitForCompletion(
+ "<html><head></head><body onload=\"" +
"document.title = " +
"document.getElementById('frame').contentWindow.location.href;" +
"\"><iframe id=\"frame\" src=\"" + crossOriginUrl + "\"></body></html>",
@@ -1193,38 +1121,36 @@
startWebServer(false);
String baseUrl = mWebServer.getAssetUrl("foo.html");
String historyUrl = "random";
- mWebView.loadDataWithBaseURL(baseUrl,
+ mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(baseUrl,
"<html><body><img src=\"" + imgUrl + "\"/></body></html>",
"text/html", "UTF-8", historyUrl);
- waitForLoadComplete();
assertTrue(mWebServer.getLastRequestUrl().endsWith(imgUrl));
assertEquals(historyUrl, mWebView.getUrl());
// Check that reported URL is "about:blank" when supplied history URL
// is null.
imgUrl = TestHtmlConstants.LARGE_IMG_URL;
- mWebView.loadDataWithBaseURL(baseUrl,
+ mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(baseUrl,
"<html><body><img src=\"" + imgUrl + "\"/></body></html>",
"text/html", "UTF-8", null);
- waitForLoadComplete();
assertTrue(mWebServer.getLastRequestUrl().endsWith(imgUrl));
assertEquals("about:blank", mWebView.getUrl());
// Test that JavaScript can access content from the same origin as the base URL.
mWebView.getSettings().setJavaScriptEnabled(true);
final String crossOriginUrl = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- mWebView.loadDataWithBaseURL(baseUrl, "<html><head></head><body onload=\"" +
+ mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(baseUrl,
+ "<html><head></head><body onload=\"" +
"document.title = document.getElementById('frame').contentWindow.location.href;" +
"\"><iframe id=\"frame\" src=\"" + crossOriginUrl + "\"></body></html>",
"text/html", "UTF-8", null);
- waitForLoadComplete();
assertEquals(crossOriginUrl, mWebView.getTitle());
// Check that when the base URL uses the 'data' scheme, a 'data' scheme URL is used and the
// history URL is ignored.
- mWebView.loadDataWithBaseURL("data:foo", "<html><body>bar</body></html>",
- "text/html", "UTF-8", historyUrl);
- waitForLoadComplete();
+ mOnUiThread.loadDataWithBaseURLAndWaitForCompletion("data:foo",
+ "<html><body>bar</body></html>", "text/html", "UTF-8",
+ historyUrl);
assertTrue(mWebView.getUrl().indexOf("data:text/html,") == 0);
assertTrue(mWebView.getUrl().indexOf("bar") > 0);
}
@@ -1239,8 +1165,8 @@
public void testFindAll() {
String p = "<p>Find all instances of find on the page and highlight them.</p>";
- mWebView.loadData("<html><body>" + p + "</body></html>", "text/html", null);
- waitForLoadComplete();
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p
+ + "</body></html>", "text/html", null);
assertEquals(2, mWebView.findAll("find"));
}
@@ -1263,99 +1189,72 @@
)
})
public void testFindNext() throws Throwable {
- final ScrollRunnable runnable = new ScrollRunnable();
-
final class StopScrollingPollingCheck extends PollingCheck {
private int mPreviousScrollY = -1;
@Override
protected boolean check() {
getInstrumentation().waitForIdleSync();
- try {
- runTestOnUiThread(runnable);
- } catch (Throwable t) {}
+ int scrollY = mOnUiThread.getScrollY();
boolean hasStopped =
- (mPreviousScrollY == -1 ? false : (runnable.getScrollY() == mPreviousScrollY));
- mPreviousScrollY = runnable.getScrollY();
+ (mPreviousScrollY == -1 ? false : (scrollY == mPreviousScrollY));
+ mPreviousScrollY = scrollY;
return hasStopped;
}
}
- final class FindNextRunnable implements Runnable {
- private boolean mForward;
- FindNextRunnable(boolean forward) {
- mForward = forward;
- }
- @Override
- public void run() {
- mWebView.findNext(mForward);
- }
- }
+ // Reset the scaling so that finding the next "all" text will require scrolling.
+ mOnUiThread.setInitialScale(100);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- // Reset the scaling so that finding the next "all" text will require scrolling.
- mWebView.setInitialScale(100);
+ DisplayMetrics metrics = mOnUiThread.getDisplayMetrics();
+ int dimension = Math.max(metrics.widthPixels, metrics.heightPixels);
+ // create a paragraph high enough to take up the entire screen
+ String p = "<p style=\"height:" + dimension + "px;\">" +
+ "Find all instances of a word on the page and highlight them.</p>";
- DisplayMetrics metrics = mWebView.getContext().getResources().getDisplayMetrics();
- int dimension = Math.max(metrics.widthPixels, metrics.heightPixels);
- // create a paragraph high enough to take up the entire screen
- String p = "<p style=\"height:" + dimension + "px;\">" +
- "Find all instances of a word on the page and highlight them.</p>";
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p + p + "</body></html>", "text/html", null);
- mWebView.loadData("<html><body>" + p + p + "</body></html>", "text/html", null);
- waitForLoadComplete();
-
- // highlight all the strings found
- mWebView.findAll("all");
- }
- });
+ // highlight all the strings found
+ mOnUiThread.findAll("all");
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(runnable);
- int previousScrollY = runnable.getScrollY();
+ int previousScrollY = mOnUiThread.getScrollY();
// Focus "all" in the second page and assert that the view scrolls.
- runTestOnUiThread(new FindNextRunnable(true));
+ mOnUiThread.findNext(true);
new StopScrollingPollingCheck().run();
- assertTrue(runnable.getScrollY() > previousScrollY);
- previousScrollY = runnable.getScrollY();
+ assertTrue(mOnUiThread.getScrollY() > previousScrollY);
+ previousScrollY = mOnUiThread.getScrollY();
// Focus "all" in the first page and assert that the view scrolls.
- runTestOnUiThread(new FindNextRunnable(true));
+ mOnUiThread.findNext(true);
new StopScrollingPollingCheck().run();
- assertTrue(runnable.getScrollY() < previousScrollY);
- previousScrollY = runnable.getScrollY();
+ assertTrue(mOnUiThread.getScrollY() < previousScrollY);
+ previousScrollY = mOnUiThread.getScrollY();
// Focus "all" in the second page and assert that the view scrolls.
- runTestOnUiThread(new FindNextRunnable(false));
+ mOnUiThread.findNext(false);
new StopScrollingPollingCheck().run();
- assertTrue(runnable.getScrollY() > previousScrollY);
- previousScrollY = runnable.getScrollY();
+ assertTrue(mOnUiThread.getScrollY() > previousScrollY);
+ previousScrollY = mOnUiThread.getScrollY();
// Focus "all" in the first page and assert that the view scrolls.
- runTestOnUiThread(new FindNextRunnable(false));
+ mOnUiThread.findNext(false);
new StopScrollingPollingCheck().run();
- assertTrue(runnable.getScrollY() < previousScrollY);
- previousScrollY = runnable.getScrollY();
+ assertTrue(mOnUiThread.getScrollY() < previousScrollY);
+ previousScrollY = mOnUiThread.getScrollY();
// clear the result
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.clearMatches();
- }
- });
+ mOnUiThread.clearMatches();
getInstrumentation().waitForIdleSync();
// can not scroll any more
- runTestOnUiThread(new FindNextRunnable(false));
+ mOnUiThread.findNext(false);
new StopScrollingPollingCheck().run();
- assertTrue(runnable.getScrollY() == previousScrollY);
+ assertTrue(mOnUiThread.getScrollY() == previousScrollY);
- runTestOnUiThread(new FindNextRunnable(true));
+ mOnUiThread.findNext(true);
new StopScrollingPollingCheck().run();
- assertTrue(runnable.getScrollY() == previousScrollY);
+ assertTrue(mOnUiThread.getScrollY() == previousScrollY);
}
@TestTargetNew(
@@ -1395,9 +1294,8 @@
runTestOnUiThread(new Runnable() {
@Override
public void run() {
- mWebView.loadData("<html><body><img src=\"" + imgUrl + "\"/></body></html>",
- "text/html", null);
- waitForLoadComplete();
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body><img src=\""
+ + imgUrl + "\"/></body></html>", "text/html", null);
Message response = new Message();
response.setTarget(handler);
assertFalse(handler.hasCalledHandleMessage());
@@ -1426,97 +1324,41 @@
)
})
public void testPageScroll() throws Throwable {
- final class PageUpRunnable implements Runnable {
- private boolean mResult;
- @Override
- public void run() {
- mResult = mWebView.pageUp(false);
- }
- public boolean getResult() {
- return mResult;
- }
- }
-
- final class PageDownRunnable implements Runnable {
- private boolean mResult;
- @Override
- public void run() {
- mResult = mWebView.pageDown(false);
- }
- public boolean getResult() {
- return mResult;
- }
- }
-
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- DisplayMetrics metrics = mWebView.getContext().getResources().getDisplayMetrics();
- int dimension = 2 * Math.max(metrics.widthPixels, metrics.heightPixels);
- String p = "<p style=\"height:" + dimension + "px;\">" +
- "Scroll by half the size of the page.</p>";
- mWebView.loadData("<html><body>" + p + p + "</body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ DisplayMetrics metrics = mOnUiThread.getDisplayMetrics();
+ int dimension = 2 * Math.max(metrics.widthPixels, metrics.heightPixels);
+ String p = "<p style=\"height:" + dimension + "px;\">" +
+ "Scroll by half the size of the page.</p>";
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p
+ + p + "</body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertTrue(mWebView.pageDown(false));
- }
- });
+ assertTrue(mOnUiThread.pageDown(false));
- PageDownRunnable pageDownRunnable = new PageDownRunnable();
do {
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(pageDownRunnable);
- } while (pageDownRunnable.getResult());
+ } while (mOnUiThread.pageDown(false));
- ScrollRunnable scrollRunnable = new ScrollRunnable();
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(scrollRunnable);
- int bottomScrollY = scrollRunnable.getScrollY();
+ int bottomScrollY = mOnUiThread.getScrollY();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertTrue(mWebView.pageUp(false));
- }
- });
+ assertTrue(mOnUiThread.pageUp(false));
- PageUpRunnable pageUpRunnable = new PageUpRunnable();
do {
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(pageUpRunnable);
- } while (pageUpRunnable.getResult());
+ } while (mOnUiThread.pageUp(false));
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(scrollRunnable);
- int topScrollY = scrollRunnable.getScrollY();
+ int topScrollY = mOnUiThread.getScrollY();
// jump to the bottom
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertTrue(mWebView.pageDown(true));
- }
- });
+ assertTrue(mOnUiThread.pageDown(true));
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(scrollRunnable);
- assertEquals(bottomScrollY, scrollRunnable.getScrollY());
+ assertEquals(bottomScrollY, mOnUiThread.getScrollY());
// jump to the top
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertTrue(mWebView.pageUp(true));
- }
- });
+ assertTrue(mOnUiThread.pageUp(true));
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(scrollRunnable);
- assertEquals(topScrollY, scrollRunnable.getScrollY());
+ assertEquals(topScrollY, mOnUiThread.getScrollY());
}
@TestTargetNew(
@@ -1525,60 +1367,27 @@
args = {}
)
public void testGetContentHeight() throws Throwable {
- final class HeightRunnable implements Runnable {
- private int mHeight;
- private int mContentHeight;
- @Override
- public void run() {
- mHeight = mWebView.getHeight();
- mContentHeight = mWebView.getContentHeight();
- }
- public int getHeight() {
- return mHeight;
- }
- public int getContentHeight() {
- return mContentHeight;
- }
- }
-
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadData("<html><body></body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ mOnUiThread.loadDataAndWaitForCompletion(
+ "<html><body></body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
final int pageHeight = 600;
// set the margin to 0
final String p = "<p style=\"height:" + pageHeight
+ "px;margin:0px auto;\">Get the height of HTML content.</p>";
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertEquals(mWebView.getHeight(), mWebView.getContentHeight() * mWebView.getScale(), 2f);
- mWebView.loadData("<html><body>" + p + "</body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ assertEquals(mOnUiThread.getHeight(), mOnUiThread.getContentHeight() * mOnUiThread.getScale(), 2f);
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p
+ + "</body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
- HeightRunnable runnable = new HeightRunnable();
- runTestOnUiThread(runnable);
- assertTrue(runnable.getContentHeight() > pageHeight);
- int extraSpace = runnable.getContentHeight() - pageHeight;
+ assertTrue(mOnUiThread.getContentHeight() > pageHeight);
+ int extraSpace = mOnUiThread.getContentHeight() - pageHeight;
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadData("<html><body>" + p + p + "</body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p
+ + p + "</body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(runnable);
- assertEquals(pageHeight + pageHeight + extraSpace, runnable.getContentHeight());
+ assertEquals(pageHeight + pageHeight + extraSpace,
+ mOnUiThread.getContentHeight());
}
@TestTargetNew(
@@ -1594,8 +1403,7 @@
startWebServer(false);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- mWebView.loadUrl(url);
- waitForLoadComplete();
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
new PollingCheck(TEST_TIMEOUT) {
@Override
protected boolean check() {
@@ -1679,50 +1487,35 @@
args = {int.class, int.class}
)
public void testFlingScroll() throws Throwable {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- DisplayMetrics metrics = mWebView.getContext().getResources().getDisplayMetrics();
- int dimension = 2 * Math.max(metrics.widthPixels, metrics.heightPixels);
- String p = "<p style=\"height:" + dimension + "px;" +
- "width:" + dimension + "px\">Test fling scroll.</p>";
- mWebView.loadData("<html><body>" + p + "</body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ DisplayMetrics metrics = mOnUiThread.getDisplayMetrics();
+ int dimension = 2 * Math.max(metrics.widthPixels, metrics.heightPixels);
+ String p = "<p style=\"height:" + dimension + "px;" +
+ "width:" + dimension + "px\">Test fling scroll.</p>";
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p
+ + "</body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
- ScrollRunnable runnable = new ScrollRunnable();
- runTestOnUiThread(runnable);
- int previousScrollX = runnable.getScrollX();
- int previousScrollY = runnable.getScrollY();
+ int previousScrollX = mOnUiThread.getScrollX();
+ int previousScrollY = mOnUiThread.getScrollY();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.flingScroll(100, 100);
- }
- });
+ mOnUiThread.flingScroll(100, 100);
int timeSlice = 500;
Thread.sleep(timeSlice);
- runTestOnUiThread(runnable);
- assertTrue(runnable.getScrollX() > previousScrollX);
- assertTrue(runnable.getScrollY() > previousScrollY);
+ assertTrue(mOnUiThread.getScrollX() > previousScrollX);
+ assertTrue(mOnUiThread.getScrollY() > previousScrollY);
- previousScrollY = runnable.getScrollY();
- previousScrollX = runnable.getScrollX();
+ previousScrollY = mOnUiThread.getScrollY();
+ previousScrollX = mOnUiThread.getScrollX();
Thread.sleep(timeSlice);
- runTestOnUiThread(runnable);
- assertTrue(runnable.getScrollX() >= previousScrollX);
- assertTrue(runnable.getScrollY() >= previousScrollY);
+ assertTrue(mOnUiThread.getScrollX() >= previousScrollX);
+ assertTrue(mOnUiThread.getScrollY() >= previousScrollY);
- previousScrollY = runnable.getScrollY();
- previousScrollX = runnable.getScrollX();
+ previousScrollY = mOnUiThread.getScrollY();
+ previousScrollX = mOnUiThread.getScrollX();
Thread.sleep(timeSlice);
- runTestOnUiThread(runnable);
- assertTrue(runnable.getScrollX() >= previousScrollX);
- assertTrue(runnable.getScrollY() >= previousScrollY);
+ assertTrue(mOnUiThread.getScrollX() >= previousScrollX);
+ assertTrue(mOnUiThread.getScrollY() >= previousScrollY);
}
@TestTargetNew(
@@ -1734,13 +1527,7 @@
final String links = "<DL><p><DT><A HREF=\"" + TestHtmlConstants.HTML_URL1
+ "\">HTML_URL1</A><DT><A HREF=\"" + TestHtmlConstants.HTML_URL2
+ "\">HTML_URL2</A></DL><p>";
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadData("<html><body>" + links + "</body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + links + "</body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
final HrefCheckHandler handler = new HrefCheckHandler(mWebView.getHandler().getLooper());
@@ -1750,12 +1537,7 @@
// focus on first link
handler.reset();
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.requestFocusNodeHref(hrefMsg);
- }
- });
+ mOnUiThread.requestFocusNodeHref(hrefMsg);
new PollingCheck() {
@Override
protected boolean check() {
@@ -1769,12 +1551,7 @@
final Message hrefMsg2 = new Message();
hrefMsg2.setTarget(handler);
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.requestFocusNodeHref(hrefMsg2);
- }
- });
+ mOnUiThread.requestFocusNodeHref(hrefMsg2);
new PollingCheck() {
@Override
protected boolean check() {
@@ -1783,12 +1560,7 @@
}.run();
assertEquals(TestHtmlConstants.HTML_URL2, handler.getResultUrl());
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.requestFocusNodeHref(null);
- }
- });
+ mOnUiThread.requestFocusNodeHref(null);
}
@TestTargetNew(
@@ -1797,18 +1569,6 @@
args = {android.os.Message.class}
)
public void testRequestImageRef() throws Exception, Throwable {
- final class GetLocationRunnable implements Runnable {
- private int[] mLocation;
- @Override
- public void run() {
- mLocation = new int[2];
- mWebView.getLocationOnScreen(mLocation);
- }
- public int[] getLocation() {
- return mLocation;
- }
- }
-
AssetManager assets = getActivity().getAssets();
Bitmap bitmap = BitmapFactory.decodeStream(assets.open(TestHtmlConstants.LARGE_IMG_URL));
int imgWidth = bitmap.getWidth();
@@ -1816,14 +1576,9 @@
startWebServer(false);
final String imgUrl = mWebServer.getAssetUrl(TestHtmlConstants.LARGE_IMG_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadData("<html><title>Title</title><body><img src=\"" + imgUrl
- + "\"/></body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ mOnUiThread.loadDataAndWaitForCompletion(
+ "<html><title>Title</title><body><img src=\"" + imgUrl
+ + "\"/></body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
final HrefCheckHandler handler = new HrefCheckHandler(mWebView.getHandler().getLooper());
@@ -1832,9 +1587,7 @@
// touch the image
handler.reset();
- GetLocationRunnable runnable = new GetLocationRunnable();
- runTestOnUiThread(runnable);
- int[] location = runnable.getLocation();
+ int[] location = mOnUiThread.getLocationOnScreen();
long time = SystemClock.uptimeMillis();
getInstrumentation().sendPointerSync(
@@ -1842,12 +1595,7 @@
location[0] + imgWidth / 2,
location[1] + imgHeight / 2, 0));
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.requestImageRef(msg);
- }
- });
+ mOnUiThread.requestImageRef(msg);
new PollingCheck() {
@Override
protected boolean check() {
@@ -1873,17 +1621,6 @@
args = {}
)
public void testGetHitTestResult() throws Throwable {
- class HitTestResultRunnable implements Runnable {
- private HitTestResult mHitTestResult;
- @Override
- public void run() {
- mHitTestResult = mWebView.getHitTestResult();
- }
- public HitTestResult getHitTestResult() {
- return mHitTestResult;
- }
- }
-
final String anchor = "<p><a href=\"" + TestHtmlConstants.EXT_WEB_URL1
+ "\">normal anchor</a></p>";
final String blankAnchor = "<p><a href=\"\">blank anchor</a></p>";
@@ -1896,58 +1633,52 @@
String location = "shanghai";
final String geo = "<p><a href=\"geo:0,0?q=" + location + "\">Location</a></p>";
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadDataWithBaseURL("fake://home", "<html><body>" + anchor + blankAnchor + form
- + tel + mailto + geo + "</body></html>", "text/html", "UTF-8", null);
- waitForLoadComplete();
- }
- });
+ mOnUiThread.loadDataWithBaseURLAndWaitForCompletion("fake://home",
+ "<html><body>" + anchor + blankAnchor + form + tel + mailto +
+ geo + "</body></html>", "text/html", "UTF-8", null);
getInstrumentation().waitForIdleSync();
- HitTestResultRunnable runnable = new HitTestResultRunnable();
// anchor
moveFocusDown();
- runTestOnUiThread(runnable);
- assertEquals(HitTestResult.SRC_ANCHOR_TYPE, runnable.getHitTestResult().getType());
- assertEquals(TestHtmlConstants.EXT_WEB_URL1, runnable.getHitTestResult().getExtra());
+ HitTestResult hitTestResult = mOnUiThread.getHitTestResult();
+ assertEquals(HitTestResult.SRC_ANCHOR_TYPE, hitTestResult.getType());
+ assertEquals(TestHtmlConstants.EXT_WEB_URL1, hitTestResult.getExtra());
// blank anchor
moveFocusDown();
- runTestOnUiThread(runnable);
- assertEquals(HitTestResult.SRC_ANCHOR_TYPE, runnable.getHitTestResult().getType());
- assertEquals("fake://home", runnable.getHitTestResult().getExtra());
+ hitTestResult = mOnUiThread.getHitTestResult();
+ assertEquals(HitTestResult.SRC_ANCHOR_TYPE, hitTestResult.getType());
+ assertEquals("fake://home", hitTestResult.getExtra());
// text field
moveFocusDown();
- runTestOnUiThread(runnable);
- assertEquals(HitTestResult.EDIT_TEXT_TYPE, runnable.getHitTestResult().getType());
- assertNull(runnable.getHitTestResult().getExtra());
+ hitTestResult = mOnUiThread.getHitTestResult();
+ assertEquals(HitTestResult.EDIT_TEXT_TYPE, hitTestResult.getType());
+ assertNull(hitTestResult.getExtra());
// submit button
moveFocusDown();
- runTestOnUiThread(runnable);
- assertEquals(HitTestResult.UNKNOWN_TYPE, runnable.getHitTestResult().getType());
- assertNull(runnable.getHitTestResult().getExtra());
+ hitTestResult = mOnUiThread.getHitTestResult();
+ assertEquals(HitTestResult.UNKNOWN_TYPE, hitTestResult.getType());
+ assertNull(hitTestResult.getExtra());
// phone number
moveFocusDown();
- runTestOnUiThread(runnable);
- assertEquals(HitTestResult.PHONE_TYPE, runnable.getHitTestResult().getType());
- assertEquals(phoneNo, runnable.getHitTestResult().getExtra());
+ hitTestResult = mOnUiThread.getHitTestResult();
+ assertEquals(HitTestResult.PHONE_TYPE, hitTestResult.getType());
+ assertEquals(phoneNo, hitTestResult.getExtra());
// email
moveFocusDown();
- runTestOnUiThread(runnable);
- assertEquals(HitTestResult.EMAIL_TYPE, runnable.getHitTestResult().getType());
- assertEquals(email, runnable.getHitTestResult().getExtra());
+ hitTestResult = mOnUiThread.getHitTestResult();
+ assertEquals(HitTestResult.EMAIL_TYPE, hitTestResult.getType());
+ assertEquals(email, hitTestResult.getExtra());
// geo address
moveFocusDown();
- runTestOnUiThread(runnable);
- assertEquals(HitTestResult.GEO_TYPE, runnable.getHitTestResult().getType());
- assertEquals(location, runnable.getHitTestResult().getExtra());
+ hitTestResult = mOnUiThread.getHitTestResult();
+ assertEquals(HitTestResult.GEO_TYPE, hitTestResult.getType());
+ assertEquals(location, hitTestResult.getExtra());
}
@TestTargetNew(
@@ -1960,58 +1691,33 @@
final float defaultScale =
getInstrumentation().getTargetContext().getResources().getDisplayMetrics().density;
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadData("<html><body>" + p + "</body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p
+ + "</body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertEquals(defaultScale, mWebView.getScale(), .01f);
+ assertEquals(defaultScale, mOnUiThread.getScale(), .01f);
- mWebView.setInitialScale(0);
- // modify content to fool WebKit into re-loading
- mWebView.loadData("<html><body>" + p + "2" + "</body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ mOnUiThread.setInitialScale(0);
+ // modify content to fool WebKit into re-loading
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p
+ + "2" + "</body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertEquals(defaultScale, mWebView.getScale(), .01f);
+ assertEquals(defaultScale, mOnUiThread.getScale(), .01f);
- mWebView.setInitialScale(50);
- mWebView.loadData("<html><body>" + p + "3" + "</body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ mOnUiThread.setInitialScale(50);
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p
+ + "3" + "</body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertEquals(0.5f, mWebView.getScale(), .02f);
+ assertEquals(0.5f, mOnUiThread.getScale(), .02f);
- mWebView.setInitialScale(0);
- mWebView.loadData("<html><body>" + p + "4" + "</body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ mOnUiThread.setInitialScale(0);
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p
+ + "4" + "</body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertEquals(defaultScale, mWebView.getScale(), .01f);
- }
- });
+ assertEquals(defaultScale, mOnUiThread.getScale(), .01f);
}
@TestTargetNew(
@@ -2025,7 +1731,7 @@
public void testGetFavicon() throws Exception {
startWebServer(false);
String url = mWebServer.getAssetUrl(TestHtmlConstants.TEST_FAVICON_URL);
- assertLoadUrlSuccessfully(url);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
mWebView.getFavicon();
// ToBeFixed: Favicon is not loaded automatically.
// assertNotNull(mWebView.getFavicon());
@@ -2043,13 +1749,13 @@
String url2 = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL2);
String url3 = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL3);
- assertLoadUrlSuccessfully(url1);
+ mOnUiThread.loadUrlAndWaitForCompletion(url1);
pollingCheckWebBackForwardList(url1, 0, 1);
- assertLoadUrlSuccessfully(url2);
+ mOnUiThread.loadUrlAndWaitForCompletion(url2);
pollingCheckWebBackForwardList(url2, 1, 2);
- assertLoadUrlSuccessfully(url3);
+ mOnUiThread.loadUrlAndWaitForCompletion(url3);
pollingCheckWebBackForwardList(url3, 2, 3);
mWebView.clearHistory();
@@ -2087,11 +1793,11 @@
String url3 = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL3);
// make a history list
- assertLoadUrlSuccessfully(url1);
+ mOnUiThread.loadUrlAndWaitForCompletion(url1);
pollingCheckWebBackForwardList(url1, 0, 1);
- assertLoadUrlSuccessfully(url2);
+ mOnUiThread.loadUrlAndWaitForCompletion(url2);
pollingCheckWebBackForwardList(url2, 1, 2);
- assertLoadUrlSuccessfully(url3);
+ mOnUiThread.loadUrlAndWaitForCompletion(url3);
pollingCheckWebBackForwardList(url3, 2, 3);
// save the list
@@ -2148,6 +1854,9 @@
public void testSetWebViewClient() throws Throwable {
final class MockWebViewClient extends WaitForLoadedClient {
private boolean mOnScaleChangedCalled = false;
+ public MockWebViewClient() {
+ super(mOnUiThread);
+ }
@Override
public void onScaleChanged(WebView view, float oldScale, float newScale) {
super.onScaleChanged(view, oldScale, newScale);
@@ -2159,21 +1868,11 @@
}
final MockWebViewClient webViewClient = new MockWebViewClient();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebViewClient(webViewClient);
- }
- });
+ mOnUiThread.setWebViewClient(webViewClient);
getInstrumentation().waitForIdleSync();
assertFalse(webViewClient.onScaleChangedCalled());
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.zoomIn();
- }
- });
+ mOnUiThread.zoomIn();
getInstrumentation().waitForIdleSync();
assertTrue(webViewClient.onScaleChangedCalled());
}
@@ -2210,32 +1909,15 @@
args = {}
)
})
+ @UiThreadTest
public void testInsecureSiteClearsCertificate() throws Throwable {
final SslCertificate certificate =
new SslCertificate("foo", "bar", new Date(42), new Date(43));
startWebServer(false);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebChromeClient(new LoadCompleteWebChromeClient());
- mWebView.setCertificate(certificate);
- mWebView.loadUrl(url);
- }
- });
- waitForUiThreadDone();
-
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- new PollingCheck(TEST_TIMEOUT) {
- @Override
- protected boolean check() {
- return mWebView.getCertificate() == null;
- }
- }.run();
- }
- });
+ mWebView.setCertificate(certificate);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
+ assertNull(mWebView.getCertificate());
}
@TestTargets({
@@ -2250,8 +1932,12 @@
args = {}
)
})
+ @UiThreadTest
public void testSecureSiteSetsCertificate() throws Throwable {
final class MockWebViewClient extends WaitForLoadedClient {
+ public MockWebViewClient() {
+ super(mOnUiThread);
+ }
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
@@ -2260,31 +1946,12 @@
startWebServer(true);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebViewClient(new MockWebViewClient());
- mWebView.setWebChromeClient(new LoadCompleteWebChromeClient());
- mWebView.setCertificate(null);
- mWebView.loadUrl(url);
- }
- });
- waitForUiThreadDone();
-
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- new PollingCheck(TEST_TIMEOUT) {
- @Override
- protected boolean check() {
- return mWebView.getCertificate() != null;
- }
- }.run();
- SslCertificate cert = mWebView.getCertificate();
- assertNotNull(cert);
- assertEquals("Android", cert.getIssuedTo().getUName());
- }
- });
+ mOnUiThread.setWebViewClient(new MockWebViewClient());
+ mWebView.setCertificate(null);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
+ SslCertificate cert = mWebView.getCertificate();
+ assertNotNull(cert);
+ assertEquals("Android", cert.getIssuedTo().getUName());
}
@TestTargetNew(
@@ -2307,6 +1974,10 @@
final class MockWebViewClient extends WaitForLoadedClient {
private String mErrorUrl;
private WebView mWebView;
+
+ public MockWebViewClient() {
+ super(mOnUiThread);
+ }
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
mWebView = view;
@@ -2324,16 +1995,9 @@
startWebServer(true);
final String errorUrl = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
final MockWebViewClient webViewClient = new MockWebViewClient();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebViewClient(webViewClient);
- mWebView.setWebChromeClient(new LoadCompleteWebChromeClient());
- mWebView.clearSslPreferences();
- mWebView.loadUrl(errorUrl);
- }
- });
- waitForUiThreadDone();
+ mOnUiThread.setWebViewClient(webViewClient);
+ mOnUiThread.clearSslPreferences();
+ mOnUiThread.loadUrlAndWaitForCompletion(errorUrl);
assertEquals(mWebView, webViewClient.webView());
assertEquals(errorUrl, webViewClient.errorUrl());
@@ -2346,6 +2010,9 @@
)
public void testOnReceivedSslErrorProceed() throws Throwable {
final class MockWebViewClient extends WaitForLoadedClient {
+ public MockWebViewClient() {
+ super(mOnUiThread);
+ }
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
@@ -2354,21 +2021,9 @@
startWebServer(true);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebViewClient(new MockWebViewClient());
- mWebView.setWebChromeClient(new LoadCompleteWebChromeClient());
- mWebView.loadUrl(url);
- }
- });
- waitForUiThreadDone();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mWebView.getTitle());
- }
- });
+ mOnUiThread.setWebViewClient(new MockWebViewClient());
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
+ assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, mOnUiThread.getTitle());
}
@TestTargetNew(
@@ -2378,6 +2033,9 @@
)
public void testOnReceivedSslErrorCancel() throws Throwable {
final class MockWebViewClient extends WaitForLoadedClient {
+ public MockWebViewClient() {
+ super(mOnUiThread);
+ }
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.cancel();
@@ -2386,22 +2044,10 @@
startWebServer(true);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebViewClient(new MockWebViewClient());
- mWebView.setWebChromeClient(new LoadCompleteWebChromeClient());
- mWebView.clearSslPreferences();
- mWebView.loadUrl(url);
- }
- });
- waitForUiThreadDone();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertFalse(TestHtmlConstants.HELLO_WORLD_TITLE.equals(mWebView.getTitle()));
- }
- });
+ mOnUiThread.setWebViewClient(new MockWebViewClient());
+ mOnUiThread.clearSslPreferences();
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
+ assertFalse(TestHtmlConstants.HELLO_WORLD_TITLE.equals(mOnUiThread.getTitle()));
}
@TestTargetNew(
@@ -2415,36 +2061,18 @@
final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient();
startWebServer(true);
final String firstUrl = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebViewClient(webViewClient);
- mWebView.setWebChromeClient(new LoadCompleteWebChromeClient());
- mWebView.clearSslPreferences();
- mWebView.loadUrl(firstUrl);
- }
- });
- waitForUiThreadDone();
+ mOnUiThread.setWebViewClient(webViewClient);
+ mOnUiThread.clearSslPreferences();
+ mOnUiThread.loadUrlAndWaitForCompletion(firstUrl);
assertTrue(webViewClient.wasOnReceivedSslErrorCalled());
// Load the second page. We don't expect a call to
// WebViewClient.onReceivedSslError(), but the page should load.
webViewClient.resetWasOnReceivedSslErrorCalled();
final String sameHostUrl = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL2);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadUrl(sameHostUrl);
- }
- });
- waitForUiThreadDone();
+ mOnUiThread.loadUrlAndWaitForCompletion(sameHostUrl);
assertFalse(webViewClient.wasOnReceivedSslErrorCalled());
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertEquals("Second page", mWebView.getTitle());
- }
- });
+ assertEquals("Second page", mOnUiThread.getTitle());
}
@TestTargetNew(
@@ -2458,16 +2086,9 @@
final SslErrorWebViewClient webViewClient = new SslErrorWebViewClient();
startWebServer(true);
final String firstUrl = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebViewClient(webViewClient);
- mWebView.setWebChromeClient(new LoadCompleteWebChromeClient());
- mWebView.clearSslPreferences();
- mWebView.loadUrl(firstUrl);
- }
- });
- waitForUiThreadDone();
+ mOnUiThread.setWebViewClient(webViewClient);
+ mOnUiThread.clearSslPreferences();
+ mOnUiThread.loadUrlAndWaitForCompletion(firstUrl);
assertTrue(webViewClient.wasOnReceivedSslErrorCalled());
// Load the second page. We expect another call to
@@ -2477,20 +2098,9 @@
// alias, but will be considered unique by the WebView.
final String differentHostUrl = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL2).replace(
"localhost", "127.0.0.1");
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadUrl(differentHostUrl);
- }
- });
- waitForUiThreadDone();
+ mOnUiThread.loadUrlAndWaitForCompletion(differentHostUrl);
assertTrue(webViewClient.wasOnReceivedSslErrorCalled());
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertEquals("Second page", mWebView.getTitle());
- }
- });
+ assertEquals("Second page", mOnUiThread.getTitle());
}
@TestTargetNew(
@@ -2499,33 +2109,23 @@
args = {View.class, Rect.class, boolean.class}
)
public void testRequestChildRectangleOnScreen() throws Throwable {
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- DisplayMetrics metrics = mWebView.getContext().getResources().getDisplayMetrics();
- final int dimension = 2 * Math.max(metrics.widthPixels, metrics.heightPixels);
- String p = "<p style=\"height:" + dimension + "px;width:" + dimension + "px\"> </p>";
- mWebView.loadData("<html><body>" + p + "</body></html>", "text/html", null);
- waitForLoadComplete();
- }
- });
+ DisplayMetrics metrics = mOnUiThread.getDisplayMetrics();
+ int dimension = 2 * Math.max(metrics.widthPixels, metrics.heightPixels);
+ String p = "<p style=\"height:" + dimension + "px;width:" + dimension + "px\"> </p>";
+ mOnUiThread.loadDataAndWaitForCompletion("<html><body>" + p
+ + "</body></html>", "text/html", null);
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- int origX = mWebView.getScrollX();
- int origY = mWebView.getScrollY();
+ int origX = mOnUiThread.getScrollX();
+ int origY = mOnUiThread.getScrollY();
- DisplayMetrics metrics = mWebView.getContext().getResources().getDisplayMetrics();
- final int dimension = 2 * Math.max(metrics.widthPixels, metrics.heightPixels);
- int half = dimension / 2;
- Rect rect = new Rect(half, half, half + 1, half + 1);
- assertTrue(mWebView.requestChildRectangleOnScreen(mWebView, rect, true));
- assertTrue(mWebView.getScrollX() > origX);
- assertTrue(mWebView.getScrollY() > origY);
- }
- });
+ metrics = mOnUiThread.getDisplayMetrics();
+ dimension = 2 * Math.max(metrics.widthPixels, metrics.heightPixels);
+ int half = dimension / 2;
+ Rect rect = new Rect(half, half, half + 1, half + 1);
+ assertTrue(mOnUiThread.requestChildRectangleOnScreen(mWebView, rect, true));
+ assertTrue(mOnUiThread.getScrollX() > origX);
+ assertTrue(mOnUiThread.getScrollY() > origY);
}
@TestTargets({
@@ -2567,28 +2167,18 @@
startWebServer(false);
final String url = mWebServer.getBinaryUrl(mimeType, length);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- // By default, WebView sends an intent to ask the system to
- // handle loading a new URL. We set WebViewClient as
- // WebViewClient.shouldOverrideUrlLoading() returns false, so
- // the WebView will load the new URL.
- mWebView.setWebViewClient(new WaitForLoadedClient());
- mWebView.setDownloadListener(listener);
- mWebView.loadData("<html><body><a href=\"" + url + "\">link</a></body></html>",
- "text/html", null);
- waitForLoadComplete();
- }
- });
+ // By default, WebView sends an intent to ask the system to
+ // handle loading a new URL. We set WebViewClient as
+ // WebViewClient.shouldOverrideUrlLoading() returns false, so
+ // the WebView will load the new URL.
+ mOnUiThread.setDownloadListener(listener);
+ mOnUiThread.loadDataAndWaitForCompletion(
+ "<html><body><a href=\"" + url
+ + "\">link</a></body></html>",
+ "text/html", null);
// Wait for layout to complete before setting focus.
getInstrumentation().waitForIdleSync();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- assertTrue(mWebView.requestFocus(View.FOCUS_DOWN, null));
- }
- });
+ assertTrue(mOnUiThread.requestFocus(View.FOCUS_DOWN, null));
getInstrumentation().waitForIdleSync();
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
new PollingCheck(TEST_TIMEOUT) {
@@ -2639,17 +2229,15 @@
settings.setJavaScriptEnabled(true);
startWebServer(false);
String url = mWebServer.getAssetUrl(TestHtmlConstants.NETWORK_STATE_URL);
- assertLoadUrlSuccessfully(url);
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
assertEquals("ONLINE", mWebView.getTitle());
mWebView.setNetworkAvailable(false);
- mWebView.reload();
- waitForLoadComplete();
+ mOnUiThread.reloadAndWaitForCompletion();
assertEquals("OFFLINE", mWebView.getTitle());
mWebView.setNetworkAvailable(true);
- mWebView.reload();
- waitForLoadComplete();
+ mOnUiThread.reloadAndWaitForCompletion();
assertEquals("ONLINE", mWebView.getTitle());
}
@@ -2661,6 +2249,11 @@
public void testSetWebChromeClient() throws Throwable {
final class MockWebChromeClient extends WaitForProgressClient {
private boolean mOnProgressChanged = false;
+
+ public MockWebChromeClient() {
+ super(mOnUiThread);
+ }
+
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
@@ -2673,23 +2266,13 @@
final MockWebChromeClient webChromeClient = new MockWebChromeClient();
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.setWebChromeClient(webChromeClient);
- }
- });
+ mOnUiThread.setWebChromeClient(webChromeClient);
getInstrumentation().waitForIdleSync();
assertFalse(webChromeClient.onProgressChangedCalled());
startWebServer(false);
final String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadUrl(url);
- }
- });
+ mOnUiThread.loadUrlAndWaitForCompletion(url);
getInstrumentation().waitForIdleSync();
new PollingCheck(TEST_TIMEOUT) {
@@ -2737,7 +2320,7 @@
}
};
final Monitor monitor = new Monitor();
- final String updateMonitorHtml = "<html><head></head>" +
+ final String updateMonitorHtml = "<html>" +
"<body onload=\"monitor.update();\"></body></html>";
// Test that JavaScript is executed even with timers paused.
@@ -2747,27 +2330,20 @@
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(monitor, "monitor");
mWebView.pauseTimers();
- mWebView.loadData(updateMonitorHtml, "text/html", null);
+ mOnUiThread.loadDataAndWaitForCompletion(updateMonitorHtml,
+ "text/html", null);
}
});
assertTrue(monitor.waitForUpdate());
// Start a timer and test that it does not fire.
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.loadUrl("javascript:setTimeout(function(){monitor.update();},100)");
- }
- });
+ mOnUiThread.loadDataAndWaitForCompletion(
+ "<html><body onload='setTimeout(function(){monitor.update();},100)'>" +
+ "</body></html>", "text/html", null);
assertFalse(monitor.waitForUpdate());
// Resume timers and test that the timer fires.
- runTestOnUiThread(new Runnable() {
- @Override
- public void run() {
- mWebView.resumeTimers();
- }
- });
+ mOnUiThread.resumeTimers();
assertTrue(monitor.waitForUpdate());
}
@@ -2909,22 +2485,6 @@
Thread.sleep(500);
}
- private final class ScrollRunnable implements Runnable {
- private int mScrollX;
- private int mScrollY;
- @Override
- public void run() {
- mScrollX = mWebView.getScrollX();
- mScrollY = mWebView.getScrollY();
- }
- public int getScrollX() {
- return mScrollX;
- }
- public int getScrollY() {
- return mScrollY;
- }
- }
-
private void pollingCheckWebBackForwardList(final String currUrl, final int currIndex,
final int size) {
new PollingCheck() {
@@ -3017,46 +2577,13 @@
return true;
}
- private void assertLoadUrlSuccessfully(String url) {
- mWebView.loadUrl(url);
- waitForLoadComplete();
- }
-
- private void waitForLoadComplete() {
- WaitForLoadUrl.getInstance().waitForLoadComplete(mWebView);
- }
-
- private synchronized void notifyUiThreadDone() {
- mIsUiThreadDone = true;
- notify();
- }
-
- private synchronized void waitForUiThreadDone() throws InterruptedException {
- while (!mIsUiThreadDone) {
- try {
- wait(TEST_TIMEOUT);
- } catch (InterruptedException e) {
- continue;
- }
- if (!mIsUiThreadDone) {
- Assert.fail("Unexpected timeout");
- }
- }
- }
-
- final class LoadCompleteWebChromeClient extends WaitForProgressClient {
- @Override
- public void onProgressChanged(WebView webView, int progress) {
- super.onProgressChanged(webView, progress);
- if (progress == 100) {
- notifyUiThreadDone();
- }
- }
- }
-
// Note that this class is not thread-safe.
final class SslErrorWebViewClient extends WaitForLoadedClient {
private boolean mWasOnReceivedSslErrorCalled;
+
+ public SslErrorWebViewClient() {
+ super(mOnUiThread);
+ }
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
mWasOnReceivedSslErrorCalled = true;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java b/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
index 4bebf84..bbe1fd3 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebView_WebViewTransportTest.java
@@ -17,6 +17,7 @@
package android.webkit.cts;
import android.test.AndroidTestCase;
+import android.test.UiThreadTest;
import android.webkit.WebView;
import android.webkit.WebView.WebViewTransport;
@@ -39,6 +40,7 @@
args = {}
)
})
+ @UiThreadTest
public void testAccessWebView() {
WebView webView = new WebView(mContext);
WebViewTransport transport = webView.new WebViewTransport();
diff --git a/tests/tests/widget/Android.mk b/tests/tests/widget/Android.mk
index a35120e..628935c 100644
--- a/tests/tests/widget/Android.mk
+++ b/tests/tests/widget/Android.mk
@@ -31,5 +31,4 @@
LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
-include $(BUILD_PACKAGE)
-
+include $(BUILD_CTS_PACKAGE)
diff --git a/tools/build/test_executable.mk b/tools/build/test_executable.mk
index b1889a8..8b445a3 100644
--- a/tools/build/test_executable.mk
+++ b/tools/build/test_executable.mk
@@ -25,16 +25,18 @@
include $(BUILD_EXECUTABLE)
-cts_executable_xml := $(CTS_NATIVE_XML_OUT)/$(LOCAL_MODULE).xml
+cts_executable_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
$(cts_executable_xml): PRIVATE_PATH := $(LOCAL_PATH)
$(cts_executable_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
$(cts_executable_xml): PRIVATE_EXECUTABLE := $(LOCAL_MODULE)
-$(cts_executable_xml): $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) $(CTS_EXPECTATIONS) | $(CTS_NATIVE_TEST_SCANNER) $(CTS_XML_GENERATOR)
+$(cts_executable_xml): $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) $(CTS_EXPECTATIONS) $(CTS_NATIVE_TEST_SCANNER) $(CTS_XML_GENERATOR)
$(hide) echo Generating test description for native package $(PRIVATE_TEST_PACKAGE)
- $(hide) mkdir -p $(CTS_NATIVE_XML_OUT)
- $(hide) $(CTS_NATIVE_TEST_SCANNER) -s $(PRIVATE_PATH) | \
- $(CTS_XML_GENERATOR) -n $(PRIVATE_EXECUTABLE) \
+ $(hide) mkdir -p $(CTS_TESTCASES_OUT)
+ $(hide) $(CTS_NATIVE_TEST_SCANNER) -s $(PRIVATE_PATH) \
+ -t $(PRIVATE_TEST_PACKAGE) | \
+ $(CTS_XML_GENERATOR) -t native \
+ -n $(PRIVATE_EXECUTABLE) \
-p $(PRIVATE_TEST_PACKAGE) \
-e $(CTS_EXPECTATIONS) \
-o $@
diff --git a/tools/build/test_host_java_library.mk b/tools/build/test_host_java_library.mk
new file mode 100644
index 0000000..9512bfa
--- /dev/null
+++ b/tools/build/test_host_java_library.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Builds a host library and defines a rule to generate the associated test
+# package XML needed by CTS.
+#
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
+
+$(cts_library_xml): PRIVATE_PATH := $(LOCAL_PATH)/src
+$(cts_library_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
+$(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
+$(cts_library_xml): PRIVATE_JAR_PATH := $(LOCAL_MODULE).jar
+$(cts_library_xml): $(HOST_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE).jar $(CTS_EXPECTATIONS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+ $(hide) echo Generating test description for host library $(PRIVATE_LIBRARY)
+ $(hide) mkdir -p $(CTS_TESTCASES_OUT)
+ $(hide) $(CTS_JAVA_TEST_SCANNER) -s $(PRIVATE_PATH) \
+ -d $(CTS_JAVA_TEST_SCANNER_DOCLET) | \
+ $(CTS_XML_GENERATOR) -t hostSideOnly \
+ -j $(PRIVATE_JAR_PATH) \
+ -n $(PRIVATE_LIBRARY) \
+ -p $(PRIVATE_TEST_PACKAGE) \
+ -e $(CTS_EXPECTATIONS) \
+ -o $@
diff --git a/tools/build/test_package.mk b/tools/build/test_package.mk
new file mode 100644
index 0000000..1cf4ecc
--- /dev/null
+++ b/tools/build/test_package.mk
@@ -0,0 +1,47 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Builds a package and defines a rule to generate the associated test
+# package XML needed by CTS.
+#
+# Replace "include $(BUILD_PACKAGE)" with "include $(BUILD_CTS_PACKAGE)"
+#
+
+include $(BUILD_PACKAGE)
+
+cts_package_apk := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).apk
+cts_package_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).xml
+
+$(cts_package_apk): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
+$(cts_package_apk): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk | $(ACP)
+ $(hide) mkdir -p $(CTS_TESTCASES_OUT)
+ $(hide) $(ACP) -fp $(call intermediates-dir-for,APPS,$(PRIVATE_PACKAGE))/package.apk $@
+
+$(cts_package_xml): PRIVATE_PATH := $(LOCAL_PATH)
+$(cts_package_xml): PRIVATE_INSTRUMENTATION := $(LOCAL_INSTRUMENTATION_FOR)
+$(cts_package_xml): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
+$(cts_package_xml): PRIVATE_TEST_PACKAGE := android.$(notdir $(LOCAL_PATH))
+$(cts_package_xml): PRIVATE_MANIFEST := $(LOCAL_PATH)/AndroidManifest.xml
+$(cts_package_xml): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk $(CTS_EXPECTATIONS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+ $(hide) echo Generating test description for java package $(PRIVATE_PACKAGE)
+ $(hide) mkdir -p $(CTS_TESTCASES_OUT)
+ $(hide) $(CTS_JAVA_TEST_SCANNER) -s $(PRIVATE_PATH) \
+ -d $(CTS_JAVA_TEST_SCANNER_DOCLET) | \
+ $(CTS_XML_GENERATOR) -m $(PRIVATE_MANIFEST) \
+ -i "$(PRIVATE_INSTRUMENTATION)" \
+ -n $(PRIVATE_PACKAGE) \
+ -p $(PRIVATE_TEST_PACKAGE) \
+ -e $(CTS_EXPECTATIONS) \
+ -o $@
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
index de2e3eb..101be7f 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiClass.java
@@ -26,22 +26,31 @@
private final String mName;
+ private final boolean mDeprecated;
+
private final List<ApiConstructor> mApiConstructors = new ArrayList<ApiConstructor>();
private final List<ApiMethod> mApiMethods = new ArrayList<ApiMethod>();
- ApiClass(String name) {
- this.mName = name;
+ ApiClass(String name, boolean deprecated) {
+ mName = name;
+ mDeprecated = deprecated;
}
+ @Override
public int compareTo(ApiClass another) {
return mName.compareTo(another.mName);
}
+ @Override
public String getName() {
return mName;
}
+ public boolean isDeprecated() {
+ return mDeprecated;
+ }
+
public void addConstructor(ApiConstructor constructor) {
mApiConstructors.add(constructor);
}
@@ -97,6 +106,7 @@
return mApiConstructors.size() + mApiMethods.size();
}
+ @Override
public float getCoveragePercentage() {
return (float) getNumCoveredMethods() / getTotalMethods() * 100;
}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiConstructor.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiConstructor.java
index b38bd34..8d721e6 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiConstructor.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiConstructor.java
@@ -27,13 +27,17 @@
private final List<String> mParameterTypes;
+ private final boolean mDeprecated;
+
private boolean mIsCovered;
- ApiConstructor(String name, List<String> parameterTypes) {
- this.mName = name;
- this.mParameterTypes = new ArrayList<String>(parameterTypes);
+ ApiConstructor(String name, List<String> parameterTypes, boolean deprecated) {
+ mName = name;
+ mParameterTypes = new ArrayList<String>(parameterTypes);
+ mDeprecated = deprecated;
}
+ @Override
public int compareTo(ApiConstructor another) {
return mParameterTypes.size() - another.mParameterTypes.size();
}
@@ -46,6 +50,10 @@
return Collections.unmodifiableList(mParameterTypes);
}
+ public boolean isDeprecated() {
+ return mDeprecated;
+ }
+
public boolean isCovered() {
return mIsCovered;
}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiMethod.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiMethod.java
index eb67b8e..053cd12 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiMethod.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiMethod.java
@@ -29,14 +29,18 @@
private final String mReturnType;
+ private boolean mDeprecated;
+
private boolean mIsCovered;
- ApiMethod(String name, List<String> parameterTypes, String returnType) {
- this.mName = name;
- this.mParameterTypes = new ArrayList<String>(parameterTypes);
- this.mReturnType = returnType;
+ ApiMethod(String name, List<String> parameterTypes, String returnType, boolean deprecated) {
+ mName = name;
+ mParameterTypes = new ArrayList<String>(parameterTypes);
+ mReturnType = returnType;
+ mDeprecated = deprecated;
}
+ @Override
public int compareTo(ApiMethod another) {
return mName.compareTo(another.mName);
}
@@ -53,6 +57,10 @@
return mReturnType;
}
+ public boolean isDeprecated() {
+ return mDeprecated;
+ }
+
public boolean isCovered() {
return mIsCovered;
}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
index f0ca889..ddc6fb4 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
@@ -29,9 +29,10 @@
private final Map<String, ApiClass> mApiClassMap = new HashMap<String, ApiClass>();
ApiPackage(String name) {
- this.mName = name;
+ mName = name;
}
+ @Override
public String getName() {
return mName;
}
@@ -64,6 +65,7 @@
return total;
}
+ @Override
public float getCoveragePercentage() {
return (float) getNumCoveredMethods() / getTotalMethods() * 100;
}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
index 5768e6c..f3abd86 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
@@ -36,6 +36,8 @@
private String mCurrentMethodReturnType;
+ private boolean mDeprecated;
+
private List<String> mCurrentParameterTypes = new ArrayList<String>();
private ApiCoverage mApiCoverage = new ApiCoverage();
@@ -49,27 +51,30 @@
throws SAXException {
super.startElement(uri, localName, name, attributes);
if ("package".equalsIgnoreCase(localName)) {
- mCurrentPackageName = CurrentXmlHandler.getValue(attributes, "name");
+ mCurrentPackageName = getValue(attributes, "name");
ApiPackage apiPackage = new ApiPackage(mCurrentPackageName);
mApiCoverage.addPackage(apiPackage);
} else if ("class".equalsIgnoreCase(localName)
|| "interface".equalsIgnoreCase(localName)) {
- mCurrentClassName = CurrentXmlHandler.getValue(attributes, "name");
+ mCurrentClassName = getValue(attributes, "name");
+ mDeprecated = isDeprecated(attributes);
- ApiClass apiClass = new ApiClass(mCurrentClassName);
+ ApiClass apiClass = new ApiClass(mCurrentClassName, mDeprecated);
ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
apiPackage.addClass(apiClass);
} else if ("constructor".equalsIgnoreCase(localName)) {
+ mDeprecated = isDeprecated(attributes);
mCurrentParameterTypes.clear();
} else if ("method".equalsIgnoreCase(localName)) {
- mCurrentMethodName = CurrentXmlHandler.getValue(attributes, "name");
- mCurrentMethodReturnType = CurrentXmlHandler.getValue(attributes, "return");
+ mDeprecated = isDeprecated(attributes);
+ mCurrentMethodName = getValue(attributes, "name");
+ mCurrentMethodReturnType = getValue(attributes, "return");
mCurrentParameterTypes.clear();
} else if ("parameter".equalsIgnoreCase(localName)) {
- mCurrentParameterTypes.add(CurrentXmlHandler.getValue(attributes, "type"));
+ mCurrentParameterTypes.add(getValue(attributes, "type"));
}
}
@@ -82,13 +87,13 @@
return;
}
ApiConstructor apiConstructor = new ApiConstructor(mCurrentClassName,
- mCurrentParameterTypes);
+ mCurrentParameterTypes, mDeprecated);
ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
ApiClass apiClass = apiPackage.getClass(mCurrentClassName);
apiClass.addConstructor(apiConstructor);
} else if ("method".equalsIgnoreCase(localName)) {
ApiMethod apiMethod = new ApiMethod(mCurrentMethodName, mCurrentParameterTypes,
- mCurrentMethodReturnType);
+ mCurrentMethodReturnType, mDeprecated);
ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
ApiClass apiClass = apiPackage.getClass(mCurrentClassName);
apiClass.addMethod(apiMethod);
@@ -101,4 +106,8 @@
.replaceAll("<.+>", "")
.replace("$", ".");
}
+
+ private boolean isDeprecated(Attributes attributes) {
+ return "deprecated".equals(attributes.getValue("deprecated"));
+ }
}
\ No newline at end of file
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java
index de9b7a6..9243fe0 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java
@@ -37,11 +37,12 @@
class HtmlReport {
public static void printHtmlReport(final List<File> testApks, final ApiCoverage apiCoverage,
- final OutputStream out) throws IOException, TransformerException, InterruptedException {
+ final OutputStream out) throws IOException, TransformerException {
final PipedOutputStream xmlOut = new PipedOutputStream();
final PipedInputStream xmlIn = new PipedInputStream(xmlOut);
Thread t = new Thread(new Runnable() {
+ @Override
public void run() {
XmlReport.printXmlReport(testApks, apiCoverage, xmlOut);
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
index 68acf06..94ccbb4 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
@@ -72,12 +72,14 @@
out.println("<class name=\"" + apiClass.getName()
+ "\" numCovered=\"" + apiClass.getNumCoveredMethods()
+ "\" numTotal=\"" + apiClass.getTotalMethods()
+ + "\" deprecated=\"" + apiClass.isDeprecated()
+ "\" coveragePercentage=\""
+ Math.round(apiClass.getCoveragePercentage())
+ "\">");
for (ApiConstructor constructor : apiClass.getConstructors()) {
out.println("<constructor name=\"" + constructor.getName()
+ + "\" deprecated=\"" + constructor.isDeprecated()
+ "\" covered=\"" + constructor.isCovered() + "\">");
for (String parameterType : constructor.getParameterTypes()) {
@@ -90,6 +92,7 @@
for (ApiMethod method : apiClass.getMethods()) {
out.println("<method name=\"" + method.getName()
+ "\" returnType=\"" + method.getReturnType()
+ + "\" deprecated=\"" + method.isDeprecated()
+ "\" covered=\"" + method.isCovered() + "\">");
for (String parameterType : method.getParameterTypes()) {
diff --git a/tools/cts-api-coverage/src/res/api-coverage.xsl b/tools/cts-api-coverage/src/res/api-coverage.xsl
index 3743580..95994e2 100644
--- a/tools/cts-api-coverage/src/res/api-coverage.xsl
+++ b/tools/cts-api-coverage/src/res/api-coverage.xsl
@@ -71,6 +71,10 @@
.green {
background-color: #66FF66;
}
+
+ .deprecated {
+ text-decoration: line-through;
+ }
</style>
</head>
<body>
@@ -118,7 +122,7 @@
<xsl:template name="packageOrClassListItem">
<xsl:param name="bulletClass" />
-
+
<xsl:variable name="colorClass">
<xsl:choose>
<xsl:when test="@coveragePercentage <= 50">red</xsl:when>
@@ -127,8 +131,15 @@
</xsl:choose>
</xsl:variable>
+ <xsl:variable name="deprecatedClass">
+ <xsl:choose>
+ <xsl:when test="@deprecated = 'true'">deprecated</xsl:when>
+ <xsl:otherwise></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
<li class="{$bulletClass}" onclick="toggleVisibility('{@name}')">
- <span class="{$colorClass}">
+ <span class="{$colorClass} {$deprecatedClass}">
<b><xsl:value-of select="@name" /></b>
<xsl:value-of select="@coveragePercentage" />%
(<xsl:value-of select="@numCovered" />/<xsl:value-of select="@numTotal" />)
@@ -137,7 +148,15 @@
</xsl:template>
<xsl:template name="methodListItem">
- <span class="method">
+
+ <xsl:variable name="deprecatedClass">
+ <xsl:choose>
+ <xsl:when test="@deprecated = 'true'">deprecated</xsl:when>
+ <xsl:otherwise></xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <span class="method {$deprecatedClass}">
<xsl:choose>
<xsl:when test="@covered = 'true'">[X]</xsl:when>
<xsl:otherwise>[ ]</xsl:otherwise>
@@ -147,7 +166,7 @@
</span>
<br />
</xsl:template>
-
+
<xsl:template name="formatParameters">(<xsl:for-each select="parameter">
<xsl:value-of select="@type" />
<xsl:if test="not(position() = last())">, </xsl:if>
diff --git a/CtsHostLibraryList.mk b/tools/cts-java-scanner-doclet/Android.mk
similarity index 61%
rename from CtsHostLibraryList.mk
rename to tools/cts-java-scanner-doclet/Android.mk
index ac9a700..51b141e 100644
--- a/CtsHostLibraryList.mk
+++ b/tools/cts-java-scanner-doclet/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2010 The Android Open Source Project
+# Copyright (C) 2011 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,4 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-CTS_HOST_LIBRARY_JARS :=
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := cts-java-scanner-doclet
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR) cts/tools/utils/lib/junit.jar
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java b/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java
new file mode 100644
index 0000000..808473a
--- /dev/null
+++ b/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.javascannerdoclet;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.sun.javadoc.AnnotationDesc;
+import com.sun.javadoc.AnnotationTypeDoc;
+import com.sun.javadoc.AnnotationValue;
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.Doclet;
+import com.sun.javadoc.MethodDoc;
+import com.sun.javadoc.RootDoc;
+import com.sun.javadoc.AnnotationDesc.ElementValuePair;
+
+/**
+ * Doclet that outputs in the following format:
+ *
+ * suite:android.holo.cts
+ * case:HoloTest
+ * test:testHolo
+ * test:testHoloDialog
+ */
+public class CtsJavaScannerDoclet extends Doclet {
+
+ static final String JUNIT_TEST_CASE_CLASS_NAME = "junit.framework.testcase";
+
+ public static boolean start(RootDoc root) {
+ ClassDoc[] classes = root.classes();
+ if (classes == null) {
+ return false;
+ }
+
+ PrintWriter writer = new PrintWriter(System.out);
+
+ for (ClassDoc clazz : classes) {
+ if (clazz.isAbstract() || !isValidJUnitTestCase(clazz)) {
+ continue;
+ }
+ writer.append("suite:").println(clazz.containingPackage().name());
+ writer.append("case:").println(clazz.name());
+ for (; clazz != null; clazz = clazz.superclass()) {
+ for (MethodDoc method : clazz.methods()) {
+ if (!method.name().startsWith("test")) {
+ continue;
+ }
+ writer.append("test:").println(method.name());
+ }
+ }
+ }
+
+ writer.close();
+ return true;
+ }
+
+ private static boolean isValidJUnitTestCase(ClassDoc clazz) {
+ while((clazz = clazz.superclass()) != null) {
+ if (JUNIT_TEST_CASE_CLASS_NAME.equals(clazz.qualifiedName().toLowerCase())) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/tools/cts-java-scanner/Android.mk b/tools/cts-java-scanner/Android.mk
new file mode 100644
index 0000000..8b6c906
--- /dev/null
+++ b/tools/cts-java-scanner/Android.mk
@@ -0,0 +1,43 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+# We use copy-file-to-new-target so that the installed
+# script file's timestamp is at least as new as the
+# .jar file it wraps.
+
+# the hat script
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_IS_HOST_MODULE := true
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE := cts-java-scanner
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(HOST_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/$(LOCAL_MODULE) | $(ACP)
+ @echo "Copy: $(PRIVATE_MODULE) ($@)"
+ $(copy-file-to-new-target)
+ $(hide) chmod 755 $@
+
+# the other stuff
+# ============================================================
+subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
+ src \
+ ))
+
+include $(subdirs)
diff --git a/tools/cts-java-scanner/etc/cts-java-scanner b/tools/cts-java-scanner/etc/cts-java-scanner
new file mode 100644
index 0000000..378eee8
--- /dev/null
+++ b/tools/cts-java-scanner/etc/cts-java-scanner
@@ -0,0 +1,46 @@
+#!/bin/bash
+#
+# Copyright (C) 2011, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+ newProg=`/bin/ls -ld "${prog}"`
+ newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+ if expr "x${newProg}" : 'x/' >/dev/null; then
+ prog="${newProg}"
+ else
+ progdir=`dirname "${prog}"`
+ prog="${progdir}/${newProg}"
+ fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+libdir=`dirname $progdir`/framework
+
+javaOpts=""
+while expr "x$1" : 'x-J' >/dev/null; do
+ opt=`expr "$1" : '-J\(.*\)'`
+ javaOpts="${javaOpts} -${opt}"
+ shift
+done
+
+exec java $javaOpts -jar $libdir/cts-java-scanner.jar "$@"
diff --git a/tools/cts-java-scanner/src/Android.mk b/tools/cts-java-scanner/src/Android.mk
new file mode 100644
index 0000000..ec42bcf
--- /dev/null
+++ b/tools/cts-java-scanner/src/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+
+# cts-java-scanner java library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAR_MANIFEST := MANIFEST.mf
+
+LOCAL_MODULE := cts-java-scanner
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/cts-java-scanner/src/MANIFEST.mf b/tools/cts-java-scanner/src/MANIFEST.mf
new file mode 100644
index 0000000..642f226
--- /dev/null
+++ b/tools/cts-java-scanner/src/MANIFEST.mf
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: com.android.cts.javascanner.CtsJavaScanner
diff --git a/tools/cts-java-scanner/src/com/android/cts/javascanner/CtsJavaScanner.java b/tools/cts-java-scanner/src/com/android/cts/javascanner/CtsJavaScanner.java
new file mode 100644
index 0000000..a843fc6
--- /dev/null
+++ b/tools/cts-java-scanner/src/com/android/cts/javascanner/CtsJavaScanner.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.javascanner;
+
+import java.io.File;
+import java.util.Arrays;
+
+/**
+ * Class that searches a source directory for native gTests and outputs a
+ * list of test classes and methods.
+ */
+public class CtsJavaScanner {
+
+ private static void usage(String[] args) {
+ System.err.println("Arguments: " + Arrays.asList(args));
+ System.err.println("Usage: cts-java-scanner -s SOURCE_DIR -d DOCLET_PATH");
+ System.exit(1);
+ }
+
+ public static void main(String[] args) throws Exception {
+ File sourceDir = null;
+ File docletPath = null;
+
+ for (int i = 0; i < args.length; i++) {
+ if ("-s".equals(args[i])) {
+ sourceDir = new File(getArg(args, ++i, "Missing value for source directory"));
+ } else if ("-d".equals(args[i])) {
+ docletPath = new File(getArg(args, ++i, "Missing value for docletPath"));
+ } else {
+ System.err.println("Unsupported flag: " + args[i]);
+ usage(args);
+ }
+ }
+
+ if (sourceDir == null) {
+ System.err.println("Source directory is required");
+ usage(args);
+ }
+
+ if (docletPath == null) {
+ System.err.println("Doclet path is required");
+ usage(args);
+ }
+
+ DocletRunner runner = new DocletRunner(sourceDir, docletPath);
+ System.exit(runner.runJavaDoc());
+ }
+
+ private static String getArg(String[] args, int index, String message) {
+ if (index < args.length) {
+ return args[index];
+ } else {
+ System.err.println(message);
+ usage(args);
+ return null;
+ }
+ }
+}
diff --git a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
new file mode 100644
index 0000000..8a371fd
--- /dev/null
+++ b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.javascanner;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+class DocletRunner {
+
+ private final File mSourceDir;
+ private final File mDocletPath;
+
+ DocletRunner(File sourceDir, File docletPath) {
+ mSourceDir = sourceDir;
+ mDocletPath = docletPath;
+ }
+
+ int runJavaDoc() throws IOException, InterruptedException {
+ List<String> args = new ArrayList<String>();
+ args.add("javadoc");
+ args.add("-doclet");
+ args.add("com.android.cts.javascannerdoclet.CtsJavaScannerDoclet");
+ args.add("-docletpath");
+ args.add(mDocletPath.toString());
+ args.add("-sourcepath");
+ args.add(getSourcePath(mSourceDir));
+ args.add("-classpath");
+ args.add(getClassPath());
+ args.addAll(getSourceFiles(mSourceDir));
+
+ Process process = new ProcessBuilder(args).start();
+ Scanner scanner = null;
+ try {
+ scanner = new Scanner(process.getInputStream());
+ while (scanner.hasNextLine()) {
+ System.out.println(scanner.nextLine());
+ }
+ } finally {
+ if (scanner != null) {
+ scanner.close();
+ }
+ }
+
+ return process.waitFor();
+ }
+
+ private String getSourcePath(File sourceDir) {
+ List<String> sourcePath = new ArrayList<String>();
+ sourcePath.add("./frameworks/base/core/java");
+ sourcePath.add("./frameworks/base/test-runner/src");
+ sourcePath.add("./libcore/junit/src/main/java");
+ sourcePath.add("./development/tools/hosttestlib/src");
+ sourcePath.add("./libcore/dalvik/src/main/java");
+ sourcePath.add("./cts/tests/src");
+ sourcePath.add(sourceDir.toString());
+ return join(sourcePath, ":");
+ }
+
+ private String getClassPath() {
+ List<String> classPath = new ArrayList<String>();
+ classPath.add("./prebuilt/common/tradefed/tradefed-prebuilt.jar");
+ return join(classPath, ":");
+ }
+
+ private List<String> getSourceFiles(File sourceDir) {
+ List<String> sourceFiles = new ArrayList<String>();
+
+ File[] files = sourceDir.listFiles(new FileFilter() {
+ @Override
+ public boolean accept(File pathname) {
+ return pathname.isDirectory() || pathname.toString().endsWith(".java");
+ }
+ });
+
+ for (File file : files) {
+ if (file.isDirectory()) {
+ sourceFiles.addAll(getSourceFiles(file));
+ } else {
+ sourceFiles.add(file.toString());
+ }
+ }
+
+ return sourceFiles;
+ }
+
+ private String join(List<String> options, String delimiter) {
+ StringBuilder builder = new StringBuilder();
+ int numOptions = options.size();
+ for (int i = 0; i < numOptions; i++) {
+ builder.append(options.get(i));
+ if (i + 1 < numOptions) {
+ builder.append(delimiter);
+ }
+ }
+ return builder.toString();
+ }
+}
diff --git a/tools/cts-native-scanner/src/com/android/cts/nativescanner/CtsNativeScanner.java b/tools/cts-native-scanner/src/com/android/cts/nativescanner/CtsNativeScanner.java
index 0eb757e..a7599b0 100644
--- a/tools/cts-native-scanner/src/com/android/cts/nativescanner/CtsNativeScanner.java
+++ b/tools/cts-native-scanner/src/com/android/cts/nativescanner/CtsNativeScanner.java
@@ -27,21 +27,19 @@
private static void usage(String[] args) {
System.err.println("Arguments: " + Arrays.asList(args));
- System.err.println("Usage: cts-native-scanner -s SOURCE_DIR");
+ System.err.println("Usage: cts-native-scanner -s SOURCE_DIR -t TEST_SUITE");
System.exit(1);
}
public static void main(String[] args) throws Exception {
File sourceDir = null;
+ String testSuite = null;
for (int i = 0; i < args.length; i++) {
if ("-s".equals(args[i])) {
- if (i + 1 < args.length) {
- sourceDir = new File(args[++i]);
- } else {
- System.err.println("Missing value for source directory");
- usage(args);
- }
+ sourceDir = new File(getArg(args, ++i, "Missing value for source directory"));
+ } else if ("-t".equals(args[i])) {
+ testSuite = getArg(args, ++i, "Missing value for test suite");
} else {
System.err.println("Unsupported flag: " + args[i]);
usage(args);
@@ -53,10 +51,25 @@
usage(args);
}
- TestScanner scanner = new TestScanner(sourceDir);
+ if (testSuite == null) {
+ System.out.println("Test suite is required");
+ usage(args);
+ }
+
+ TestScanner scanner = new TestScanner(sourceDir, testSuite);
List<String> testNames = scanner.getTestNames();
for (String name : testNames) {
System.out.println(name);
}
}
+
+ private static String getArg(String[] args, int index, String message) {
+ if (index < args.length) {
+ return args[index];
+ } else {
+ System.err.println(message);
+ usage(args);
+ return null;
+ }
+ }
}
diff --git a/tools/cts-native-scanner/src/com/android/cts/nativescanner/TestScanner.java b/tools/cts-native-scanner/src/com/android/cts/nativescanner/TestScanner.java
index 8899111..9411566 100644
--- a/tools/cts-native-scanner/src/com/android/cts/nativescanner/TestScanner.java
+++ b/tools/cts-native-scanner/src/com/android/cts/nativescanner/TestScanner.java
@@ -43,8 +43,11 @@
/** Directory to recursively scan for gTest test declarations. */
private final File mSourceDir;
- TestScanner(File sourceDir) {
+ private final String mTestSuite;
+
+ TestScanner(File sourceDir, String testSuite) {
mSourceDir = sourceDir;
+ mTestSuite = testSuite;
}
public List<String> getTestNames() throws IOException {
@@ -90,13 +93,14 @@
String line = scanner.nextLine();
Matcher matcher = CLASS_REGEX.matcher(line);
if (matcher.matches()) {
- testNames.add("class:" + matcher.group(1));
+ testNames.add("suite:" + mTestSuite);
+ testNames.add("case:" + matcher.group(1));
continue;
}
matcher = METHOD_REGEX.matcher(line);
if (matcher.matches()) {
- testNames.add("method:" + matcher.group(1));
+ testNames.add("test:" + matcher.group(1));
continue;
}
}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
index 5d5d8ff..ce4fdd7 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
@@ -15,6 +15,10 @@
*/
package com.android.cts.xmlgenerator;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
import vogar.ExpectationStore;
import vogar.ModeId;
@@ -23,16 +27,16 @@
import java.util.HashSet;
import java.util.Set;
-/**
- * Class that searches a source directory for native gTests and outputs a
- * test package xml.
- */
+import javax.xml.parsers.DocumentBuilderFactory;
+
+/** Class that outputs a test package xml. */
public class CtsXmlGenerator {
private static void usage(String[] args) {
System.err.println("Arguments: " + Arrays.asList(args));
- System.err.println("Usage: cts-native-xml-generator -p PACKAGE_NAME -n EXECUTABLE_NAME "
- + " [-e EXPECTATION_FILE] [-o OUTPUT_FILE]");
+ System.err.println("Usage: cts-xml-generator -p PACKAGE_NAME -n NAME [-t TEST_TYPE]"
+ + " [-j JAR_PATH] [-i INSTRUMENTATION] [-m MANIFEST_FILE] [-e EXPECTATION_FILE]"
+ + " [-o OUTPUT_FILE]");
System.exit(1);
}
@@ -41,42 +45,50 @@
String name = null;
String outputPath = null;
Set<File> expectationFiles = new HashSet<File>();
+ File manifestFile = null;
+ String instrumentation = null;
+ String testType = null;
+ String jarPath = null;
for (int i = 0; i < args.length; i++) {
if ("-p".equals(args[i])) {
- if (i + 1 < args.length) {
- appPackageName = args[++i];
- } else {
- System.err.println("Missing value for test package");
- usage(args);
- }
+ appPackageName = getArg(args, ++i, "Missing value for test package");
} else if ("-n".equals(args[i])) {
- if (i + 1 < args.length) {
- name = args[++i];
- } else {
- System.err.println("Missing value for executable name");
- usage(args);
- }
+ name = getArg(args, ++i, "Missing value for executable name");
+ } else if ("-t".equals(args[i])) {
+ testType = getArg(args, ++i, "Missing value for test type");
+ } else if ("-j".equals(args[i])) {
+ jarPath = getArg(args, ++i, "Missing value for jar path");
+ } else if ("-m".equals(args[i])) {
+ manifestFile = new File(getArg(args, ++i, "Missing value for manifest"));
+ } else if ("-i".equals(args[i])) {
+ instrumentation = getArg(args, ++i, "Missing value for instrumentation");
} else if ("-e".equals(args[i])) {
- if (i + 1 < args.length) {
- expectationFiles.add(new File(args[++i]));
- } else {
- System.err.println("Missing value for expectation store");
- usage(args);
- }
+ expectationFiles.add(new File(getArg(args, ++i,
+ "Missing value for expectation store")));
} else if ("-o".equals(args[i])) {
- if (i + 1 < args.length) {
- outputPath = args[++i];
- } else {
- System.err.println("Missing value for output file");
- usage(args);
- }
+ outputPath = getArg(args, ++i, "Missing value for output file");
} else {
System.err.println("Unsupported flag: " + args[i]);
usage(args);
}
}
+ String appNameSpace = null;
+ String runner = null;
+ String targetNameSpace = null;
+
+ if (manifestFile != null) {
+ Document manifest = DocumentBuilderFactory.newInstance().newDocumentBuilder()
+ .parse(manifestFile);
+ Element documentElement = manifest.getDocumentElement();
+ appNameSpace = documentElement.getAttribute("package");
+ runner = getElementAttribute(documentElement, "instrumentation",
+ "android:name");
+ targetNameSpace = getElementAttribute(documentElement, "instrumentation",
+ "android:targetPackage");
+ }
+
if (appPackageName == null) {
System.out.println("Package name is required");
usage(args);
@@ -86,7 +98,28 @@
}
ExpectationStore store = ExpectationStore.parse(expectationFiles, ModeId.DEVICE);
- NativeXmlGenerator generator = new NativeXmlGenerator(store, appPackageName, name, outputPath);
+ XmlGenerator generator = new XmlGenerator(store, appNameSpace, appPackageName,
+ name, runner, instrumentation, targetNameSpace, jarPath, testType, outputPath);
generator.writePackageXml();
}
+
+ private static String getArg(String[] args, int index, String message) {
+ if (index < args.length) {
+ return args[index];
+ } else {
+ System.err.println(message);
+ usage(args);
+ return null;
+ }
+ }
+
+ private static String getElementAttribute(Element parentElement, String elementName,
+ String attributeName) {
+ NodeList nodeList = parentElement.getElementsByTagName(elementName);
+ if (nodeList.getLength() > 0) {
+ Element element = (Element) nodeList.item(0);
+ return element.getAttribute(attributeName);
+ }
+ return null;
+ }
}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/NativeXmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/NativeXmlGenerator.java
deleted file mode 100644
index 1692c10..0000000
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/NativeXmlGenerator.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.xmlgenerator;
-
-import vogar.Expectation;
-import vogar.ExpectationStore;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.Scanner;
-
-/**
- * Generator of TestPackage XML files for native tests.
- *
- * It takes in an input of the following form:
- *
- * class:TestClass1
- * method:testMethod1
- * method:testMethod2
- * class:TestClass2
- * method:testMethod1
- */
-class NativeXmlGenerator {
-
- /** Test package name like "android.nativemedia" to group the tests. */
- private final String mAppPackageName;
-
- /** Name of the native executable. */
- private final String mName;
-
- /** Path to output file or null to just dump to standard out. */
- private final String mOutputPath;
-
- /** ExpectationStore to filter out known failures. */
- private final ExpectationStore mExpectations;
-
- NativeXmlGenerator(ExpectationStore expectations, String appPackageName, String name,
- String outputPath) {
- mAppPackageName = appPackageName;
- mName = name;
- mOutputPath = outputPath;
- mExpectations = expectations;
- }
-
- public void writePackageXml() throws IOException {
- OutputStream output = System.out;
- if (mOutputPath != null) {
- File outputFile = new File(mOutputPath);
- output = new FileOutputStream(outputFile);
- }
-
- PrintWriter writer = null;
- try {
- writer = new PrintWriter(output);
- writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- writeTestPackage(writer);
- } finally {
- if (writer != null) {
- writer.close();
- }
- }
- }
-
- private void writeTestPackage(PrintWriter writer) {
- writer.append("<TestPackage appPackageName=\"")
- .append(mAppPackageName)
- .append("\" name=\"")
- .append(mName)
- .println("\" testType=\"native\" version=\"1.0\">");
- writeTestSuite(writer);
- writer.println("</TestPackage>");
- }
-
- private void writeTestSuite(PrintWriter writer) {
- /*
- * Given "android.foo.bar.baz"...
- *
- * <TestSuite name="android">
- * <TestSuite name="foo">
- * <TestSuite name="bar">
- * <TestSuite name="baz">
- */
- Scanner scanner = null;
- try {
- scanner = new Scanner(mAppPackageName);
- scanner.useDelimiter("\\.");
-
- int numLevels = 0;
- for (; scanner.hasNext(); numLevels++) {
- String packagePart = scanner.next();
- writer.append("<TestSuite name=\"").append(packagePart).println("\">");
- }
-
- writeTestCases(writer);
-
- for (; numLevels > 0; numLevels--) {
- writer.println("</TestSuite>");
- }
- } finally {
- if (scanner != null) {
- scanner.close();
- }
- }
- }
-
- private void writeTestCases(PrintWriter writer) {
- String currentClassName = null;
- Scanner scanner = new Scanner(System.in);
- while (scanner.hasNextLine()) {
- String line = scanner.nextLine();
- String[] tokens = line.split(":");
- if (tokens.length > 1) {
- String type = tokens[0];
- String value = tokens[1];
- if ("class".equals(type)) {
- if (currentClassName != null) {
- writer.append("</TestCase>");
- }
- currentClassName = value;
- writer.append("<TestCase name=\"").append(value).println("\">");
- } else if ("method".equals(type)) {
- String fullClassName = mAppPackageName + "." + currentClassName;
- if (!isKnownFailure(mExpectations, fullClassName, value)) {
- writer.append("<Test name=\"").append(value).println("\" />");
- }
- }
- }
- }
- if (currentClassName != null) {
- writer.println("</TestCase>");
- }
- }
-
- public static boolean isKnownFailure(ExpectationStore expectationStore,
- String className, String methodName) {
- String testName = String.format("%s#%s", className, methodName);
- return expectationStore != null && expectationStore.get(testName) != Expectation.SUCCESS;
- }
-}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java
new file mode 100644
index 0000000..bab3476
--- /dev/null
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.xmlgenerator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+class TestCase {
+
+ private final String mName;
+
+ private final List<String> mTests = new ArrayList<String>();
+
+ public TestCase(String name) {
+ mName = name;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void addTest(String test) {
+ mTests.add(test);
+ }
+
+ public Collection<String> getTests() {
+ return Collections.unmodifiableCollection(mTests);
+ }
+}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestListParser.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestListParser.java
new file mode 100644
index 0000000..76e1437
--- /dev/null
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestListParser.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.xmlgenerator;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Scanner;
+
+/**
+ * Parser of test lists that are in the format of:
+ *
+ * suite:android.holo.cts
+ * case:HoloTest
+ * test:testHolo
+ * test:testHoloDialog
+ */
+class TestListParser {
+
+ public Collection<TestSuite> parse(InputStream input) {
+ Map<String, TestSuite> suiteMap = new HashMap<String, TestSuite>();
+ TestSuite currentSuite = null;
+ TestCase currentCase = null;
+ Scanner scanner = null;
+ try {
+ scanner = new Scanner(input);
+ while(scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ String[] tokens = line.split(":");
+ if (tokens.length != 2) {
+ continue;
+ }
+
+ String key = tokens[0];
+ String value = tokens[1];
+ if ("suite".equals(key)) {
+ currentSuite = handleSuite(suiteMap, value);
+ } else if ("case".equals(key)) {
+ currentCase = handleCase(currentSuite, value);
+ } else if ("test".equals(key)) {
+ handleTest(currentCase, value);
+ }
+ }
+ } finally {
+ if (scanner != null) {
+ scanner.close();
+ }
+ }
+ return suiteMap.values();
+ }
+
+ private TestSuite handleSuite(Map<String, TestSuite> suiteMap, String fullSuite) {
+ String[] suites = fullSuite.split("\\.");
+ int numSuites = suites.length;
+ TestSuite lastSuite = null;
+
+ for (int i = 0; i < numSuites; i++) {
+ String name = suites[i];
+ if (lastSuite != null) {
+ if (lastSuite.hasSuite(name)) {
+ lastSuite = lastSuite.getSuite(name);
+ } else {
+ TestSuite newSuite = new TestSuite(name);
+ lastSuite.addSuite(newSuite);
+ lastSuite = newSuite;
+ }
+ } else if (suiteMap.containsKey(name)) {
+ lastSuite = suiteMap.get(name);
+ } else {
+ lastSuite = new TestSuite(name);
+ suiteMap.put(name, lastSuite);
+ }
+ }
+
+ return lastSuite;
+ }
+
+ private TestCase handleCase(TestSuite suite, String caseName) {
+ TestCase testCase = new TestCase(caseName);
+ suite.addCase(testCase);
+ return testCase;
+ }
+
+ private void handleTest(TestCase testCase, String test) {
+ testCase.addTest(test);
+ }
+}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestSuite.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestSuite.java
new file mode 100644
index 0000000..3c29603
--- /dev/null
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestSuite.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.xmlgenerator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+class TestSuite {
+
+ private final String mName;
+
+ private final Map<String, TestSuite> mSuites = new HashMap<String, TestSuite>();
+
+ private final List<TestCase> mCases = new ArrayList<TestCase>();
+
+ public TestSuite(String name) {
+ mName = name;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public boolean hasSuite(String name) {
+ return mSuites.containsKey(name);
+ }
+
+ public TestSuite getSuite(String name) {
+ return mSuites.get(name);
+ }
+
+ public void addSuite(TestSuite suite) {
+ mSuites.put(suite.mName, suite);
+ }
+
+ public Collection<TestSuite> getSuites() {
+ return Collections.unmodifiableCollection(mSuites.values());
+ }
+
+ public void addCase(TestCase testCase) {
+ mCases.add(testCase);
+ }
+
+ public Collection<TestCase> getCases() {
+ return Collections.unmodifiableCollection(mCases);
+ }
+}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
new file mode 100644
index 0000000..9951b8d
--- /dev/null
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.xmlgenerator;
+
+import vogar.Expectation;
+import vogar.ExpectationStore;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Collection;
+
+/**
+ * Generator of TestPackage XML files for native tests.
+ *
+ * It takes in an input of the following form:
+ *
+ * suite: x.y.z
+ * case:TestClass1
+ * test:testMethod1
+ * test:testMethod2
+ * case:TestClass2
+ * test:testMethod1
+ * suite: x.y
+ * case:TestClass3
+ * test:testMethod2
+ */
+class XmlGenerator {
+
+ /** Example: com.android.cts.holo */
+ private final String mAppNamespace;
+
+ /** Test package name like "android.nativemedia" to group the tests. */
+ private final String mAppPackageName;
+
+ /** Name of the native executable. */
+ private final String mName;
+
+ /** Test runner */
+ private final String mRunner;
+
+ private final String mTargetBinaryName;
+
+ private final String mTargetNameSpace;
+
+ private final String mJarPath;
+
+ private final String mTestType;
+
+ /** Path to output file or null to just dump to standard out. */
+ private final String mOutputPath;
+
+ /** ExpectationStore to filter out known failures. */
+ private final ExpectationStore mExpectations;
+
+ XmlGenerator(ExpectationStore expectations, String appNameSpace, String appPackageName,
+ String name, String runner, String targetBinaryName, String targetNameSpace,
+ String jarPath, String testType, String outputPath) {
+ mAppNamespace = appNameSpace;
+ mAppPackageName = appPackageName;
+ mName = name;
+ mRunner = runner;
+ mTargetBinaryName = targetBinaryName;
+ mTargetNameSpace = targetNameSpace;
+ mJarPath = jarPath;
+ mTestType = testType;
+ mOutputPath = outputPath;
+ mExpectations = expectations;
+ }
+
+ public void writePackageXml() throws IOException {
+ OutputStream output = System.out;
+ if (mOutputPath != null) {
+ File outputFile = new File(mOutputPath);
+ output = new FileOutputStream(outputFile);
+ }
+
+ PrintWriter writer = null;
+ try {
+ writer = new PrintWriter(output);
+ writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ writeTestPackage(writer);
+ } finally {
+ if (writer != null) {
+ writer.close();
+ }
+ }
+ }
+
+ private void writeTestPackage(PrintWriter writer) {
+ writer.append("<TestPackage");
+ if (mAppNamespace != null) {
+ writer.append(" appNameSpace=\"").append(mAppNamespace).append("\"");
+ }
+
+ writer.append(" appPackageName=\"").append(mAppPackageName).append("\"");
+ writer.append(" name=\"").append(mName).append("\"");
+
+ if (mRunner != null) {
+ writer.append(" runner=\"").append(mRunner).append("\"");
+ }
+
+ if (mAppNamespace != null && mTargetNameSpace != null
+ && !mAppNamespace.equals(mTargetNameSpace)) {
+ writer.append(" targetBinaryName=\"").append(mTargetBinaryName).append("\"");
+ writer.append(" targetNameSpace=\"").append(mTargetNameSpace).append("\"");
+ }
+
+ if (mTestType != null) {
+ writer.append(" testType=\"").append(mTestType).append("\"");
+ }
+
+ if (mJarPath != null) {
+ writer.append(" jarPath=\"").append(mJarPath).append("\"");
+ }
+
+ writer.println(" version=\"1.0\">");
+
+ TestListParser parser = new TestListParser();
+ Collection<TestSuite> suites = parser.parse(System.in);
+ StringBuilder nameCollector = new StringBuilder();
+ writeTestSuites(writer, suites, nameCollector);
+ writer.println("</TestPackage>");
+ }
+
+ private void writeTestSuites(PrintWriter writer, Collection<TestSuite> suites,
+ StringBuilder nameCollector) {
+ for (TestSuite suite : suites) {
+ writer.append("<TestSuite name=\"").append(suite.getName()).println("\">");
+
+ String namePart = suite.getName();
+ if (nameCollector.length() > 0) {
+ namePart = "." + namePart;
+ }
+ nameCollector.append(namePart);
+
+ writeTestSuites(writer, suite.getSuites(), nameCollector);
+ writeTestCases(writer, suite.getCases(), nameCollector);
+
+ nameCollector.delete(nameCollector.length() - namePart.length(),
+ nameCollector.length());
+ writer.println("</TestSuite>");
+ }
+ }
+
+ private void writeTestCases(PrintWriter writer, Collection<TestCase> cases,
+ StringBuilder nameCollector) {
+ for (TestCase testCase : cases) {
+ String name = testCase.getName();
+ writer.append("<TestCase name=\"").append(name).println("\">");
+ nameCollector.append('.').append(name);
+
+ writeTests(writer, testCase.getTests(), nameCollector);
+
+ nameCollector.delete(nameCollector.length() - name.length() - 1,
+ nameCollector.length());
+ writer.println("</TestCase>");
+ }
+ }
+
+ private void writeTests(PrintWriter writer, Collection<String> tests,
+ StringBuilder nameCollector) {
+ for (String test : tests) {
+ nameCollector.append('#').append(test);
+ if (!isKnownFailure(mExpectations, nameCollector.toString())) {
+ writer.append("<Test name=\"").append(test).println("\" />");
+ }
+ nameCollector.delete(nameCollector.length() - test.length() - 1,
+ nameCollector.length());
+ }
+ }
+
+ public static boolean isKnownFailure(ExpectationStore expectationStore, String testName) {
+ return expectationStore != null && expectationStore.get(testName) != Expectation.SUCCESS;
+ }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
index 855c209..686c90a 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
@@ -84,6 +84,9 @@
@Option(name = "quiet-output", description = "Mute display of test results.")
private boolean mQuietOutput = false;
+ @Option(name = "result-server", description = "Server to publish test results.")
+ private String mResultServer;
+
protected IBuildInfo mBuildInfo;
private String mStartTime;
private String mDeviceSerial;
@@ -254,9 +257,18 @@
CLog.w("Unable to create XML report");
return;
}
- createXmlResult(mReportDir, mStartTime, elapsedTime);
+
+ File reportFile = getResultFile(mReportDir);
+ createXmlResult(reportFile, mStartTime, elapsedTime);
copyFormattingFiles(mReportDir);
zipResults(mReportDir);
+
+ try {
+ ResultReporter reporter = new ResultReporter(mResultServer, reportFile);
+ reporter.reportResult();
+ } catch (IOException e) {
+ CLog.e(e);
+ }
}
private void logResult(String format, Object... args) {
@@ -281,12 +293,11 @@
/**
* Creates a report file and populates it with the report data from the completed tests.
*/
- private void createXmlResult(File reportDir, String startTimestamp, long elapsedTime) {
+ private void createXmlResult(File reportFile, String startTimestamp, long elapsedTime) {
String endTime = getTimestamp();
-
OutputStream stream = null;
try {
- stream = createOutputResultStream(reportDir);
+ stream = createOutputResultStream(reportFile);
KXmlSerializer serializer = new KXmlSerializer();
serializer.setOutput(stream, "UTF-8");
serializer.startDocument("UTF-8", false);
@@ -331,11 +342,14 @@
//serializer.endTag(ns, RESULT_TAG);
}
+ private File getResultFile(File reportDir) {
+ return new File(reportDir, TEST_RESULT_FILE_NAME);
+ }
+
/**
* Creates the output stream to use for test results. Exposed for mocking.
*/
- OutputStream createOutputResultStream(File reportDir) throws IOException {
- File reportFile = new File(reportDir, TEST_RESULT_FILE_NAME);
+ OutputStream createOutputResultStream(File reportFile) throws IOException {
logResult("Created xml report file at file://%s", reportFile.getAbsolutePath());
return new FileOutputStream(reportFile);
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/IssueReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/IssueReporter.java
index 8ee9c0f..9d903dd 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/IssueReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/IssueReporter.java
@@ -28,11 +28,6 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.net.HttpURLConnection;
-import java.net.URL;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
@@ -46,7 +41,6 @@
*/
public class IssueReporter implements ITestInvocationListener {
- private static final String FORM_DATA_BOUNDARY = "C75I55u3R3p0r73r";
private static final int BUGREPORT_SIZE = 500 * 1024;
private static final String PRODUCT_NAME_KEY = "buildName";
@@ -87,22 +81,42 @@
*/
private void setBugReport(InputStreamSource dataStream) throws IOException {
if (mCurrentIssue != null) {
- InputStream input = dataStream.createInputStream();
- ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(BUGREPORT_SIZE);
- GZIPOutputStream gzipOutput = new GZIPOutputStream(byteOutput);
- for (byte[] buffer = new byte[1024]; input.read(buffer) >= 0; ) {
- gzipOutput.write(buffer);
- }
- gzipOutput.close();
-
// Only one bug report can be stored at a time and they are gzipped to
// about 0.5 MB so there shoudn't be any memory leak bringing down CTS.
- mCurrentIssue.mBugReport = byteOutput.toByteArray();
+ InputStream input = null;
+ try {
+ input = dataStream.createInputStream();
+ mCurrentIssue.mBugReport = getBytes(input, BUGREPORT_SIZE);
+ } finally {
+ if (input != null) {
+ input.close();
+ }
+ }
} else {
CLog.e("setBugReport is getting called on an empty issue...");
}
}
+ /**
+ * @param input that will be gzipped and returne as a byte array
+ * @param size of the output expected
+ * @return the byte array with the input's data
+ * @throws IOException
+ */
+ static byte[] getBytes(InputStream input, int size) throws IOException {
+ ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(size);
+ GZIPOutputStream gzipOutput = new GZIPOutputStream(byteOutput);
+ for (byte[] buffer = new byte[1024]; ; ) {
+ int numRead = input.read(buffer);
+ if (numRead < 0) {
+ break;
+ }
+ gzipOutput.write(buffer, 0, numRead);
+ }
+ gzipOutput.close();
+ return byteOutput.toByteArray();
+ }
+
@Override
public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {
if (mCurrentIssue != null) {
@@ -158,32 +172,14 @@
return null;
}
- HttpURLConnection connection = null;
-
- try {
- URL url = new URL(mServerUrl);
- connection = (HttpURLConnection) url.openConnection();
- connection.setRequestMethod("POST");
- connection.setDoOutput(true);
- connection.setRequestProperty("Content-Type",
- "multipart/form-data; boundary=" + FORM_DATA_BOUNDARY);
-
- byte[] body = getContentBody();
- connection.setRequestProperty("Content-Length", Integer.toString(body.length));
-
- OutputStream output = connection.getOutputStream();
- output.write(body);
- output.close();
-
- // Open the stream to get a response. Otherwise request will be cancelled.
- InputStream input = connection.getInputStream();
- input.close();
-
- } finally {
- if (connection != null) {
- connection.disconnect();
- }
- }
+ new MultipartForm(mServerUrl)
+ .addFormValue("productName", mProductName)
+ .addFormValue("buildType", mBuildType)
+ .addFormValue("buildId", mBuildId)
+ .addFormValue("testName", mTestName)
+ .addFormValue("stackTrace", mStackTrace)
+ .addFormFile("bugReport", "bugreport.txt.gz", mBugReport)
+ .submit();
return null;
}
@@ -191,43 +187,6 @@
private boolean isEmpty(String value) {
return value == null || value.trim().isEmpty();
}
-
- private byte[] getContentBody() throws IOException {
- ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
- PrintWriter writer = new PrintWriter(new OutputStreamWriter(byteOutput));
- writer.println();
- writeFormField(writer, "productName", mProductName);
- writeFormField(writer, "buildType", mBuildType);
- writeFormField(writer, "buildId", mBuildId);
- writeFormField(writer, "testName", mTestName);
- writeFormField(writer, "stackTrace", mStackTrace);
- if (mBugReport != null) {
- writeFormFileHeader(writer, "bugReport", "bugReport.txt.gz");
- writer.flush(); // Must flush here before writing to the byte stream!
- byteOutput.write(mBugReport);
- writer.println();
- }
- writer.append("--").append(FORM_DATA_BOUNDARY).println("--");
- writer.flush();
- writer.close();
- return byteOutput.toByteArray();
- }
-
- private void writeFormField(PrintWriter writer, String name, String value) {
- writer.append("--").println(FORM_DATA_BOUNDARY);
- writer.append("Content-Disposition: form-data; name=\"").append(name).println("\"");
- writer.println();
- writer.println(value);
- }
-
- private void writeFormFileHeader(PrintWriter writer, String name, String fileName) {
- writer.append("--").println(FORM_DATA_BOUNDARY);
- writer.append("Content-Disposition: form-data; name=\"").append(name);
- writer.append("\"; filename=\"").append(fileName).println("\"");
- writer.println("Content-Type: application/x-gzip");
- writer.println("Content-Transfer-Encoding: binary");
- writer.println();
- }
}
@Override
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/MultipartForm.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/MultipartForm.java
new file mode 100644
index 0000000..f3ef0bb
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/MultipartForm.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.tradefed.result;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+/** MultipartForm builds a multipart form and submits it. */
+class MultipartForm {
+
+ private static final String FORM_DATA_BOUNDARY = "C75I55u3R3p0r73r";
+
+ private final String mServerUrl;
+
+ private final Map<String, String> mFormValues = new HashMap<String, String>();
+
+ private String mName;
+ private String mFileName;
+ private byte[] mData;
+
+ public MultipartForm(String serverUrl) {
+ mServerUrl = serverUrl;
+ }
+
+ public MultipartForm addFormValue(String name, String value) {
+ mFormValues.put(name, value);
+ return this;
+ }
+
+ public MultipartForm addFormFile(String name, String fileName, byte[] data) {
+ mName = name;
+ mFileName = fileName;
+ mData = data;
+ return this;
+ }
+
+ public void submit() throws IOException {
+ String redirectUrl = submitForm(mServerUrl);
+ if (redirectUrl != null) {
+ submitForm(redirectUrl);
+ }
+ }
+
+ /**
+ * @param serverUrl to post the data to
+ * @return a url if the server redirected to another url
+ * @throws IOException
+ */
+ private String submitForm(String serverUrl) throws IOException {
+ HttpURLConnection connection = null;
+ try {
+ URL url = new URL(serverUrl);
+ connection = (HttpURLConnection) url.openConnection();
+ connection.setInstanceFollowRedirects(false);
+ connection.setRequestMethod("POST");
+ connection.setDoOutput(true);
+ connection.setRequestProperty("Content-Type",
+ "multipart/form-data; boundary=" + FORM_DATA_BOUNDARY);
+
+ byte[] body = getContentBody();
+ connection.setRequestProperty("Content-Length", Integer.toString(body.length));
+
+ OutputStream output = connection.getOutputStream();
+ try {
+ output.write(body);
+ } finally {
+ output.close();
+ }
+
+ // Open the stream to get a response. Otherwise request will be cancelled.
+ InputStream input = connection.getInputStream();
+ input.close();
+
+ if (connection.getResponseCode() == 302) {
+ return connection.getHeaderField("Location");
+ }
+ } finally {
+ if (connection != null) {
+ connection.disconnect();
+ }
+ }
+
+ return null;
+ }
+
+ private byte[] getContentBody() throws IOException {
+ ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
+ PrintWriter writer = new PrintWriter(new OutputStreamWriter(byteOutput));
+ writer.println();
+
+ for (Map.Entry<String, String> formValue : mFormValues.entrySet()) {
+ writeFormField(writer, formValue.getKey(), formValue.getValue());
+ }
+
+ if (mData != null) {
+ writeFormFileHeader(writer, mName, mFileName);
+ writer.flush(); // Must flush here before writing to the byte stream!
+ byteOutput.write(mData);
+ writer.println();
+ }
+ writer.append("--").append(FORM_DATA_BOUNDARY).println("--");
+ writer.flush();
+ writer.close();
+ return byteOutput.toByteArray();
+ }
+
+ private void writeFormField(PrintWriter writer, String name, String value) {
+ writer.append("--").println(FORM_DATA_BOUNDARY);
+ writer.append("Content-Disposition: form-data; name=\"").append(name).println("\"");
+ writer.println();
+ writer.println(value);
+ }
+
+ private void writeFormFileHeader(PrintWriter writer, String name, String fileName) {
+ writer.append("--").println(FORM_DATA_BOUNDARY);
+ writer.append("Content-Disposition: form-data; name=\"").append(name);
+ writer.append("\"; filename=\"").append(fileName).println("\"");
+ writer.println("Content-Type: application/x-gzip");
+ writer.println("Content-Transfer-Encoding: binary");
+ writer.println();
+ }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java
new file mode 100644
index 0000000..05192c9
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/ResultReporter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.tradefed.result;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Class that sends a HTTP POST multipart/form-data request containing
+ * the test result XML.
+ */
+class ResultReporter {
+
+ private static final int RESULT_XML_BYTES = 500 * 1024;
+
+ private final String mServerUrl;
+
+ private final File mReportFile;
+
+ ResultReporter(String serverUrl, File reportFile) {
+ mServerUrl = serverUrl;
+ mReportFile = reportFile;
+ }
+
+ public void reportResult() throws IOException {
+ if (isEmpty(mServerUrl)) {
+ return;
+ }
+
+ InputStream input = new FileInputStream(mReportFile);
+ try {
+ byte[] data = IssueReporter.getBytes(input, RESULT_XML_BYTES);
+ new MultipartForm(mServerUrl)
+ .addFormFile("resultXml", "testResult.xml.gz", data)
+ .submit();
+ } finally {
+ input.close();
+ }
+ }
+
+ private boolean isEmpty(String value) {
+ return value == null || value.trim().isEmpty();
+ }
+}
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 8cccab0..4067e0a 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,7 +48,6 @@
private String mAppNameSpace = null;
private String mName = null;
private String mRunner = null;
- private boolean mIsHostSideTest = false;
private boolean mIsVMHostTest = false;
private String mTestType = null;
private String mJarPath = null;
@@ -112,15 +111,6 @@
return mRunner;
}
- void setIsHostSideTest(boolean hostSideTest) {
- mIsHostSideTest = hostSideTest;
-
- }
-
- boolean isHostSideTest() {
- return mIsHostSideTest;
- }
-
void setIsVMHostTest(boolean vmHostTest) {
mIsVMHostTest = vmHostTest;
@@ -219,7 +209,7 @@
mExcludedTestFilter.setTestInclusion(mClassName, mMethodName);
mTests = filterTests();
- if (mIsHostSideTest) {
+ if ("hostSideOnly".equals(mTestType)) {
CLog.d("Creating host test for %s", mName);
JarHostTest hostTest = new JarHostTest();
hostTest.setRunName(getUri());
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
index f1b6ed0..c8e0def 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
@@ -66,7 +66,6 @@
final String testPackageNameSpace = attributes.getValue("appNameSpace");
final String packageName = attributes.getValue("name");
final String runnerName = attributes.getValue("runner");
- final String hostSideTest = attributes.getValue("hostSideOnly");
final String vmHostTest = attributes.getValue("vmHostTest");
final String testType = attributes.getValue("testType");
final String jarPath = attributes.getValue("jarPath");
@@ -83,7 +82,6 @@
mPackageDef.setAppNameSpace(testPackageNameSpace);
mPackageDef.setName(packageName);
mPackageDef.setRunner(runnerName);
- mPackageDef.setIsHostSideTest(parseBoolean(hostSideTest));
mPackageDef.setIsVMHostTest(parseBoolean(vmHostTest));
mPackageDef.setTestType(testType);
mPackageDef.setJarPath(jarPath);
diff --git a/tools/tradefed-host/tests/run_unit_tests.sh b/tools/tradefed-host/tests/run_unit_tests.sh
new file mode 100755
index 0000000..fc19a02
--- /dev/null
+++ b/tools/tradefed-host/tests/run_unit_tests.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# 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.
+
+# helper script for running the cts-tradefed unit tests
+
+checkFile() {
+ if [ ! -f "$1" ]; then
+ echo "Unable to locate $1"
+ exit
+ fi;
+}
+
+# check if in Android build env
+if [ ! -z ${ANDROID_BUILD_TOP} ]; then
+ HOST=`uname`
+ if [ "$HOST" == "Linux" ]; then
+ OS="linux-x86"
+ elif [ "$HOST" == "Darwin" ]; then
+ OS="darwin-x86"
+ else
+ echo "Unrecognized OS"
+ exit
+ fi;
+fi;
+
+JAR_DIR=${ANDROID_BUILD_TOP}/out/host/$OS/framework
+JARS="ddmlib-prebuilt.jar tradefed-prebuilt.jar hosttestlib.jar cts-tradefed.jar cts-tradefed-tests.jar"
+
+for JAR in $JARS; do
+ checkFile ${JAR_DIR}/${JAR}
+ JAR_PATH=${JAR_PATH}:${JAR_DIR}/${JAR}
+done
+
+java $RDBG_FLAG \
+ -cp ${JAR_PATH} com.android.tradefed.command.Console run singleCommand host -n --class com.android.cts.tradefed.UnitTests "$@"
+
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
index b24c0e3..482844c 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
@@ -79,7 +79,7 @@
TestPackageXmlParser parser = new TestPackageXmlParser();
parser.parse(getStringAsStream(HOST_TEST_DATA));
TestPackageDef def = parser.getTestPackageDef();
- assertTrue(def.isHostSideTest());
+ // assertTrue(def.isHostSideTest());
assertEquals(3, def.getTests().size());
Iterator<TestIdentifier> iterator = def.getTests().iterator();
@@ -103,7 +103,7 @@
TestPackageXmlParser parser = new TestPackageXmlParser();
parser.parse(getStringAsStream(BAD_HOST_TEST_DATA));
TestPackageDef def = parser.getTestPackageDef();
- assertFalse(def.isHostSideTest());
+ // assertFalse(def.isHostSideTest());
}
/**
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 9eb26af..d5ca8ab 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -74,20 +74,14 @@
def GenerateTestDescriptions(self):
"""Generate test descriptions for all packages."""
- pool = Pool(processes=16)
+ pool = Pool(processes=2)
# individually generate descriptions not following conventions
pool.apply_async(GenerateSignatureCheckDescription, [self.test_repository])
pool.apply_async(GenerateReferenceAppDescription, [self.test_repository])
- pool.apply_async(GenerateAppSecurityDescription, [self.temp_dir,
- self.test_repository, self.android_root, self.doclet_path])
# generate test descriptions for android tests
results = []
- android_packages = GetSubDirectories(self.test_root)
- for package in android_packages:
- results.append(pool.apply_async(GenerateTestDescription, [self.test_root, self.temp_dir,
- self.test_repository, self.android_root, self.doclet_path, package]))
pool.close()
pool.join()
return sum(map(lambda result: result.get(), results))
@@ -165,153 +159,6 @@
package.WriteDescription(description)
description.close()
-def GenerateAppSecurityDescription(temp_dir, test_repository, android_root, doclet_path):
- """Generate the test description for the application security tests."""
- test_root = 'cts/tests/appsecurity-tests'
- makefile_name = os.path.join(test_root, 'Android.mk')
- makefile_vars = GetMakeFileVars(makefile_name)
- name = makefile_vars['LOCAL_MODULE']
- package_name = 'android.tests.appsecurity'
- LogGenerateDescription(package_name)
- temp_desc = os.path.join(temp_dir, 'description.xml')
- RunDescriptionGeneratorDoclet(android_root, doclet_path,
- os.path.join(test_root, 'src'), temp_desc)
- doc = dom.parse(temp_desc)
- test_description = doc.getElementsByTagName('TestPackage')[0]
- test_description.setAttribute('name', package_name)
- test_description.setAttribute('appPackageName', package_name)
- test_description.setAttribute('hostSideOnly', 'true')
- test_description.setAttribute('jarPath', name + '.jar')
- description = open(os.path.join(test_repository, package_name + '.xml'), 'w')
- doc.writexml(description, addindent=' ', encoding='UTF-8')
- description.close()
-
-
-def GenerateTestDescription(test_root, temp_dir, test_repository, android_root,
- doclet_path, package):
-
- app_package_name = 'android.' + package
- package_root = os.path.join(test_root, package)
-
- makefile_name = os.path.join(package_root, 'Android.mk')
- if not os.path.exists(makefile_name):
- print 'Skipping directory "%s" due to missing Android.mk' % package_root
- return 0
- makefile_vars = GetMakeFileVars(makefile_name)
-
- manifest_name = os.path.join(package_root, 'AndroidManifest.xml')
- if not os.path.exists(manifest_name):
- print 'Skipping directory "%s" due to missing AndroidManifest.xml' % package_root
- return 0
- manifest = tools.XmlFile(manifest_name)
-
- LogGenerateDescription(app_package_name)
-
- # Run the description generator doclet to get the test package structure
- # TODO: The Doclet does not currently add all required attributes. Instead of rewriting
- # the document below, additional attributes should be passed to the Doclet as arguments.
- temp_desc = os.path.join(temp_dir, app_package_name + '-description.xml')
-
- returncode = RunDescriptionGeneratorDoclet(android_root, doclet_path, package_root, temp_desc)
- if returncode != 0:
- print 'Error occurred while running description generator...'
- return 1
-
- # obtain missing attribute values from the makefile and manifest
- package_name = makefile_vars['LOCAL_PACKAGE_NAME']
- runner = manifest.GetAndroidAttr('instrumentation', 'name')
- target_package = manifest.GetAndroidAttr('instrumentation', 'targetPackage')
- target_binary_name = makefile_vars.get('LOCAL_INSTRUMENTATION_FOR')
-
- # add them to the document
- doc = dom.parse(temp_desc)
- test_description = doc.getElementsByTagName('TestPackage')[0]
- test_description.setAttribute('name', package_name)
- test_description.setAttribute('runner', runner)
- test_package = manifest.GetAttr('manifest', 'package')
- test_description.setAttribute('appNameSpace', test_package)
- test_description.setAttribute('appPackageName', app_package_name)
- if not test_package == target_package:
- test_description.setAttribute('targetNameSpace', target_package)
- test_description.setAttribute('targetBinaryName', target_binary_name)
- description = open(os.path.join(test_repository, package_name + '.xml'), 'w')
- doc.writexml(description, addindent=' ', encoding='UTF-8')
- description.close()
- return 0
-
-def RunDescriptionGeneratorDoclet(android_root, doclet_path, source_root, output_file):
- """Generate a test package description by running the DescriptionGenerator doclet.
-
- Args:
- android_root: Root directory of the Android source tree.
- doclet_path: Class path where the DescriptionGenerator doclet can be found.
- source_root: Directory under which tests should be searched.
- output_file: Name of the file where the description gets written.
-
- Returns:
- The exit code of the DescriptionGenerator doclet run.
- """
- # Make sure sourceRoot is relative to self.android_root
- source_root = RelPath(source_root, android_root)
-
- # To determine whether a class is a JUnit test, the Doclet needs to have all intermediate
- # subclasses of TestCase as well as the JUnit framework itself on the source path.
- # Annotation classes are also required, since test annotations go into the description.
- sourcepath = [
- 'frameworks/base/core/java', # android test classes
- 'frameworks/base/test-runner/src', # test runner
- 'libcore/junit/src/main/java', # junit classes
- 'development/tools/hosttestlib/src', # hosttestlib TestCase extensions
- 'libcore/dalvik/src/main/java', # test annotations
- 'cts/tests/src', # cts test stubs
- source_root # the source for this package
- ]
- sourcepath = [os.path.join(android_root, x) for x in sourcepath]
- classpath = [
- 'prebuilt/common/tradefed/tradefed-prebuilt.jar',
- ]
- classpath = [os.path.join(android_root, x) for x in classpath]
- cmd = ('javadoc -o %s -J-Xmx512m -quiet -doclet DescriptionGenerator -docletpath %s'
- ' -sourcepath %s -classpath %s ') % (output_file, doclet_path, ':'.join(sourcepath),
- ':'.join(classpath))
- sources = []
-
- def AddFile(sources, folder, names):
- """Find *.java."""
- sources.extend([os.path.join(folder, name) for name in names if name.endswith('.java')])
-
- os.path.walk(os.path.join(android_root, source_root), AddFile, sources)
- cmd += ' '.join(sources)
- proc = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
- # read and discard any output
- (outdata, errdata) = proc.communicate()
- if proc.returncode != 0:
- print '%s\n%s' % (outdata, errdata)
- # wait for process to terminate and return exit value
- return proc.wait()
-
-def RelPath(path, start=os.getcwd()):
- """Get a relative version of a path.
-
- This is equivalent to os.path.relpath, which is only available since Python 2.6.
-
- Args:
- path: The path to transform.
- start: The base path. Defaults to the current working directory.
-
- Returns:
- A transformed path that is relative to start.
- """
- path_dirs = os.path.abspath(path).split(os.path.sep)
- start_dirs = os.path.abspath(start).split(os.path.sep)
-
- num_common = len(os.path.commonprefix([start_dirs, path_dirs]))
-
- result_dirs = ['..'] * (len(start_dirs) - num_common) + path_dirs[num_common:]
- if result_dirs:
- return os.path.join(*result_dirs)
- return start
-
if __name__ == '__main__':
builder = CtsBuilder(sys.argv)
result = builder.GenerateTestDescriptions()