Merge "fix CTS issue for case testSetOnScrollListener"
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 060e824..c4b892e 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -22,7 +22,9 @@
CtsSimpleAppInstall \
CtsSimpleAppInstallDiffCert \
CtsTargetInstrumentationApp \
- CtsUsePermissionDiffCert
+ CtsUsePermissionDiffCert \
+ CtsMonkeyApp \
+ CtsMonkeyApp2 \
# These test cases will be analyzed by the CTS API coverage tools.
CTS_COVERAGE_TEST_CASE_LIST := \
@@ -31,27 +33,34 @@
CtsAccessibilityServiceTestCases \
CtsAccountManagerTestCases \
CtsAdminTestCases \
+ CtsAnimationTestCases \
CtsAppTestCases \
CtsBluetoothTestCases \
CtsContentTestCases \
CtsDatabaseTestCases \
+ CtsDelegatingAccessibilityService \
+ CtsDeviceAdmin \
CtsDpiTestCases \
CtsDpiTestCases2 \
CtsDrmTestCases \
CtsExampleTestCases \
CtsGestureTestCases \
CtsGraphicsTestCases \
+ CtsGraphics2TestCases \
CtsHardwareTestCases \
CtsHoloTestCases \
CtsJniTestCases \
CtsLocationTestCases \
+ CtsMediaStressTestCases \
CtsMediaTestCases \
CtsNdefTestCases \
CtsNetTestCases \
+ CtsOpenGlPerfTestCases \
CtsOsTestCases \
CtsPermissionTestCases \
CtsPermission2TestCases \
CtsPreferenceTestCases \
+ CtsPreference2TestCases \
CtsProviderTestCases \
CtsRenderscriptTestCases \
CtsSaxTestCases \
@@ -60,20 +69,20 @@
CtsTelephonyTestCases \
CtsTestStubs \
CtsTextTestCases \
+ CtsTextureViewTestCases \
CtsUtilTestCases \
CtsViewTestCases \
CtsWebkitTestCases \
- CtsWidgetTestCases
+ CtsWidgetTestCases \
+ SignatureTest \
+ TestDeviceSetup \
+ $(CTS_SECURITY_APPS_LIST)
CTS_TEST_CASE_LIST := \
- TestDeviceSetup \
- CtsDelegatingAccessibilityService \
- CtsDeviceAdmin \
- SignatureTest \
+ com.replica.replicaisland \
ApiDemos \
ApiDemosReferenceTest \
$(CTS_COVERAGE_TEST_CASE_LIST) \
- $(CTS_SECURITY_APPS_LIST)
CTS_NATIVE_EXES := \
CtsNativeMediaTestCases
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index e5c52fb..945419b 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.verifier"
android:versionCode="1"
- android:versionName="4.0_r1">
+ android:versionName="4.0.3_r1">
<!-- Using 10 for more complete NFC support... -->
<uses-sdk android:minSdkVersion="10"></uses-sdk>
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..cf47ec7
--- /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)) {
+ LOGI(" solveLeastSquares fails with det %f", outDet);
+ return ERROR_LINEAR_FITTING;
+ }
+ LOGI(" 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]);
+ LOGI(" %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/res/layout/pass_fail_list.xml b/apps/CtsVerifier/res/layout/pass_fail_list.xml
index 3c1f9d0..0b247f4 100644
--- a/apps/CtsVerifier/res/layout/pass_fail_list.xml
+++ b/apps/CtsVerifier/res/layout/pass_fail_list.xml
@@ -28,6 +28,7 @@
<TextView android:id="@id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_weight="1"
/>
<include layout="@layout/pass_fail_buttons" />
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/Utils.java b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/Utils.java
index 704b1df..f2019c2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/Utils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/Utils.java
@@ -316,17 +316,17 @@
return data.length / AudioQualityVerifierActivity.BYTES_PER_SAMPLE;
}
- public static void playRawFile(String filename) {
+ public static AudioTrack playRawFile(String filename) {
byte[] data = readFile(filename);
if (data == null) {
Log.e(TAG, "Cannot read " + filename);
- return;
+ return null;
}
- playRaw(data);
+ return playRaw(data);
}
- public static void playStim(Context context, int stimNum) {
- Utils.playRaw(getStim(context, stimNum));
+ public static AudioTrack playStim(Context context, int stimNum) {
+ return Utils.playRaw(getStim(context, stimNum));
}
public static byte[] getStim(Context context, int stimNum) {
@@ -337,13 +337,15 @@
return AudioAssets.getPinkNoise(context, ampl, duration);
}
- public static void playRaw(byte[] data) {
+ public static AudioTrack playRaw(byte[] data) {
Log.i(TAG, "Playing " + data.length + " bytes of pre-recorded audio");
AudioTrack at = new AudioTrack(AudioQualityVerifierActivity.PLAYBACK_STREAM, AudioQualityVerifierActivity.SAMPLE_RATE,
AudioFormat.CHANNEL_OUT_MONO, AudioQualityVerifierActivity.AUDIO_FORMAT,
data.length, AudioTrack.MODE_STREAM);
writeAudio(at, data);
at.play();
+
+ return at;
}
/**
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/LoopbackExperiment.java b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/LoopbackExperiment.java
index a5c41be..0817860 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/LoopbackExperiment.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audioquality/experiments/LoopbackExperiment.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioRecord;
+import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.util.Log;
@@ -74,13 +75,15 @@
mRecorder.start();
Utils.delay(END_DELAY_MS);
- Utils.playRaw(playbackData);
+ AudioTrack track = Utils.playRaw(playbackData);
int timeout = duration + 2 * END_DELAY_MS;
try {
mRecorder.join(timeout);
} catch (InterruptedException e) {}
+ track.stop();
+ track.release();
return recordedData;
}
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/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
index d575e5f..d122dec 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
@@ -140,10 +140,10 @@
private TestListAdapter getStreamAdapter() {
ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
- adapter.add(TestListItem.newCategory("RTSP"));
- for (Stream stream : RTSP_STREAMS) {
- addStreamToTests(adapter, stream);
- }
+// adapter.add(TestListItem.newCategory("RTSP"));
+// for (Stream stream : RTSP_STREAMS) {
+// addStreamToTests(adapter, stream);
+// }
adapter.add(TestListItem.newCategory("HTTP Progressive"));
for (Stream stream : HTTP_STREAMS) {
diff --git a/development/ide/eclipse/.classpath b/development/ide/eclipse/.classpath
index 30c63d8..6f5bc69 100644
--- a/development/ide/eclipse/.classpath
+++ b/development/ide/eclipse/.classpath
@@ -4,6 +4,10 @@
<classpathentry kind="lib" path="prebuilt/common/tradefed/tradefed-prebuilt.jar"/>
<classpathentry kind="src" path="cts/apps/CtsVerifier/src"/>
<classpathentry kind="src" path="cts/apps/CtsVerifier/tests/src"/>
+ <classpathentry kind="src" path="cts/tests/appsecurity/src"/>
+ <classpathentry kind="src" path="cts/tests/appsecurity/test-apps/AppWithData/src"/>
+ <classpathentry kind="src" path="cts/tests/appsecurity/test-apps/CtsMonkeyApp/src"/>
+ <classpathentry kind="src" path="cts/tests/appsecurity/test-apps/CtsMonkeyApp2/src"/>
<classpathentry kind="src" path="cts/libs/vogar-expect/src"/>
<classpathentry kind="src" path="cts/tests/ApiDemosReferenceTest/src"/>
<classpathentry kind="src" path="cts/tests/ProcessTest/src"/>
@@ -13,8 +17,6 @@
<classpathentry kind="src" path="cts/tests/SignatureTest/tests/src"/>
<classpathentry kind="src" path="cts/tests/acceleration/src"/>
<classpathentry kind="src" path="cts/tests/accessibilityservice/src"/>
- <classpathentry kind="src" path="cts/tests/appsecurity-tests/src"/>
- <classpathentry kind="src" path="cts/tests/appsecurity-tests/test-apps/AppWithData/src"/>
<classpathentry kind="src" path="cts/tests/core/runner/src"/>
<classpathentry kind="src" path="cts/tests/deviceadmin/src"/>
<classpathentry kind="src" path="cts/tests/src"/>
@@ -32,12 +34,15 @@
<classpathentry kind="src" path="cts/tests/tests/example/src"/>
<classpathentry kind="src" path="cts/tests/tests/gesture/src"/>
<classpathentry kind="src" path="cts/tests/tests/graphics/src"/>
+ <classpathentry kind="src" path="cts/tests/tests/graphics2/src"/>
<classpathentry kind="src" path="cts/tests/tests/hardware/src"/>
<classpathentry kind="src" path="cts/tests/tests/holo/src"/>
<classpathentry kind="src" path="cts/tests/tests/jni/src"/>
<classpathentry kind="src" path="cts/tests/tests/location/src"/>
<classpathentry kind="src" path="cts/tests/tests/media/src"/>
+ <classpathentry kind="src" path="cts/tests/tests/mediastress/src"/>
<classpathentry kind="src" path="cts/tests/tests/net/src"/>
+ <classpathentry kind="src" path="cts/tests/tests/openglperf/src"/>
<classpathentry kind="src" path="cts/tests/tests/os/src"/>
<classpathentry kind="src" path="cts/tests/tests/performance/src"/>
<classpathentry kind="src" path="cts/tests/tests/performance2/src"/>
@@ -47,12 +52,14 @@
<classpathentry kind="src" path="cts/tests/tests/permission/src"/>
<classpathentry kind="src" path="cts/tests/tests/permission2/src"/>
<classpathentry kind="src" path="cts/tests/tests/preference/src"/>
+ <classpathentry kind="src" path="cts/tests/tests/preference2/src"/>
<classpathentry kind="src" path="cts/tests/tests/provider/src"/>
<classpathentry kind="src" path="cts/tests/tests/renderscript/src"/>
<classpathentry kind="src" path="cts/tests/tests/security/src"/>
<classpathentry kind="src" path="cts/tests/tests/speech/src"/>
<classpathentry kind="src" path="cts/tests/tests/telephony/src"/>
<classpathentry kind="src" path="cts/tests/tests/text/src"/>
+ <classpathentry kind="src" path="cts/tests/tests/textureview/src"/>
<classpathentry kind="src" path="cts/tests/tests/util/src"/>
<classpathentry kind="src" path="cts/tests/tests/view/src"/>
<classpathentry kind="src" path="cts/tests/tests/webkit/src"/>
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 8fef728..22905e9 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -28,12 +28,14 @@
<meta-data android:name="android.app.cts.float" android:value="100.1" />
<meta-data android:name="android.app.cts.reference" android:resource="@xml/metadata" />
</permission>
-
+
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_TIME_ZONE" />
- <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+ <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+ <uses-permission android:name="android.permission.WRITE_SOCIAL_STREAM" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
+ <uses-permission android:name="android.permission.READ_SOCIAL_STREAM" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.DEVICE_POWER" />
@@ -114,6 +116,8 @@
<application android:label="Android TestCase"
android:icon="@drawable/size_48x48" android:name="android.app.cts.MockApplication">
+ <activity android:name="android.app.cts.ActionBarActivity" />
+
<activity android:name="android.media.cts.AudioManagerStub"
android:label="AudioManagerStub"/>
<activity android:name="android.media.cts.AudioManagerStubHelper"
@@ -169,7 +173,8 @@
</activity>
<activity android:name="android.app.cts.DialogStubActivity"
- android:label="DialogStubActivity">
+ android:label="DialogStubActivity"
+ android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -918,7 +923,7 @@
<service android:name="android.app.cts.IntentServiceStub"/>
<activity android:name="android.app.cts.LaunchpadActivity"
- android:configChanges="keyboardHidden|orientation"
+ android:configChanges="keyboardHidden|orientation|screenSize"
android:multiprocess="true">
</activity>
diff --git a/tests/appsecurity-tests/src/com/android/cts/monkey/AbstractMonkeyTest.java b/tests/appsecurity-tests/src/com/android/cts/monkey/AbstractMonkeyTest.java
new file mode 100644
index 0000000..0bc2c10
--- /dev/null
+++ b/tests/appsecurity-tests/src/com/android/cts/monkey/AbstractMonkeyTest.java
@@ -0,0 +1,47 @@
+package com.android.cts.monkey;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+
+abstract class AbstractMonkeyTest extends DeviceTestCase implements IBuildReceiver {
+
+ static final String[] PKGS = {"com.android.cts.monkey", "com.android.cts.monkey2"};
+ static final String[] APKS = {"CtsMonkeyApp.apk", "CtsMonkeyApp2.apk"};
+
+ CtsBuildHelper mBuild;
+ ITestDevice mDevice;
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mDevice = getDevice();
+ for (int i = 0; i < PKGS.length; i++) {
+ mDevice.uninstallPackage(PKGS[i]);
+ File app = mBuild.getTestApp(APKS[i]);
+ mDevice.installPackage(app, false);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ for (int i = 0; i < PKGS.length; i++) {
+ mDevice.uninstallPackage(PKGS[i]);
+ }
+ }
+
+ void clearLogCat() throws DeviceNotAvailableException {
+ mDevice.executeAdbCommand("logcat", "-c");
+ }
+}
diff --git a/tests/appsecurity-tests/src/com/android/cts/monkey/CategoryTest.java b/tests/appsecurity-tests/src/com/android/cts/monkey/CategoryTest.java
new file mode 100644
index 0000000..3932653
--- /dev/null
+++ b/tests/appsecurity-tests/src/com/android/cts/monkey/CategoryTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.monkey;
+
+public class CategoryTest extends AbstractMonkeyTest {
+
+ public void testDefaultCategories() throws Exception {
+ String out = mDevice.executeShellCommand("monkey -v -p " + PKGS[0] + " 5000");
+ assertTrue(out.contains("cmp=com.android.cts.monkey/.MonkeyActivity"));
+ assertTrue(out.contains("cmp=com.android.cts.monkey/.BaboonActivity"));
+ }
+
+ public void testSingleCategory() throws Exception {
+ String out = mDevice.executeShellCommand("monkey -v -p " + PKGS[0]
+ + " -c android.intent.category.LAUNCHER 5000");
+ assertTrue(out.contains("cmp=com.android.cts.monkey/.MonkeyActivity"));
+ assertFalse(out.contains("cmp=com.android.cts.monkey/.BaboonActivity"));
+
+ out = mDevice.executeShellCommand("monkey -v -p " + PKGS[0]
+ + " -c android.intent.category.MONKEY 5000");
+ assertFalse(out.contains("cmp=com.android.cts.monkey/.MonkeyActivity"));
+ assertTrue(out.contains("cmp=com.android.cts.monkey/.BaboonActivity"));
+ }
+
+ public void testMultipleCategories() throws Exception {
+ String out = mDevice.executeShellCommand("monkey -v -p " + PKGS[0]
+ + " -c android.intent.category.LAUNCHER"
+ + " -c android.intent.category.MONKEY 5000");
+ assertTrue(out.contains("cmp=com.android.cts.monkey/.MonkeyActivity"));
+ assertTrue(out.contains("cmp=com.android.cts.monkey/.BaboonActivity"));
+ }
+}
diff --git a/tests/appsecurity-tests/src/com/android/cts/monkey/MonkeyTest.java b/tests/appsecurity-tests/src/com/android/cts/monkey/MonkeyTest.java
new file mode 100644
index 0000000..2bf27ed
--- /dev/null
+++ b/tests/appsecurity-tests/src/com/android/cts/monkey/MonkeyTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.monkey;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+import java.util.Scanner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class MonkeyTest extends AbstractMonkeyTest {
+
+ private static final Pattern LOG_PATTERN =
+ Pattern.compile("I/MonkeyActivity\\([\\d ]+\\): (.*)");
+ private static final String MONKEY = "@(>.<)@";
+ private static final String HUMAN = "(^_^)";
+
+ public void testIsMonkey() throws Exception {
+ clearLogCat();
+ mDevice.executeShellCommand("monkey -p " + PKGS[0] + " 500");
+ assertIsUserAMonkey(true);
+ }
+
+ public void testNotMonkey() throws Exception {
+ clearLogCat();
+ mDevice.executeShellCommand("am start -W -a android.intent.action.MAIN "
+ + "-n com.android.cts.monkey/com.android.cts.monkey.MonkeyActivity");
+ assertIsUserAMonkey(false);
+ }
+
+ private void assertIsUserAMonkey(boolean isMonkey) throws DeviceNotAvailableException {
+ String logs = mDevice.executeAdbCommand("logcat", "-d", "MonkeyActivity:I", "*:S");
+ boolean monkeyLogsFound = false;
+ Scanner s = new Scanner(logs);
+ try {
+ while (s.hasNextLine()) {
+ String line = s.nextLine();
+ Matcher m = LOG_PATTERN.matcher(line);
+ if (m.matches()) {
+ monkeyLogsFound = true;
+ assertEquals(isMonkey ? MONKEY : HUMAN, m.group(1));
+ }
+ }
+ assertTrue(monkeyLogsFound);
+ } finally {
+ s.close();
+ }
+ }
+}
diff --git a/tests/appsecurity-tests/src/com/android/cts/monkey/PackageTest.java b/tests/appsecurity-tests/src/com/android/cts/monkey/PackageTest.java
new file mode 100644
index 0000000..aa6106b
--- /dev/null
+++ b/tests/appsecurity-tests/src/com/android/cts/monkey/PackageTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.monkey;
+
+public class PackageTest extends AbstractMonkeyTest {
+
+ public void testSinglePackage() throws Exception {
+ String out = mDevice.executeShellCommand("monkey -v -p " + PKGS[0] + " 5000");
+ assertTrue(out.contains("cmp=com.android.cts.monkey/.MonkeyActivity"));
+ assertFalse(out.contains("cmp=com.android.cts.monkey2/.ChimpActivity"));
+
+ out = mDevice.executeShellCommand("monkey -v -p " + PKGS[1] + " 5000");
+ assertFalse(out.contains("cmp=com.android.cts.monkey/.MonkeyActivity"));
+ assertTrue(out.contains("cmp=com.android.cts.monkey2/.ChimpActivity"));
+ }
+
+ public void testMultiplePackages() throws Exception {
+ String out = mDevice.executeShellCommand("monkey -v -p " + PKGS[0]
+ + " -p " + PKGS[1] + " 5000");
+ assertTrue(out.contains("cmp=com.android.cts.monkey/.MonkeyActivity"));
+ assertTrue(out.contains("cmp=com.android.cts.monkey2/.ChimpActivity"));
+ }
+}
diff --git a/tests/appsecurity-tests/src/com/android/cts/monkey/SeedTest.java b/tests/appsecurity-tests/src/com/android/cts/monkey/SeedTest.java
new file mode 100644
index 0000000..4f8f842
--- /dev/null
+++ b/tests/appsecurity-tests/src/com/android/cts/monkey/SeedTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.monkey;
+
+import java.util.Scanner;
+
+public class SeedTest extends AbstractMonkeyTest {
+
+ public void testSeed() throws Exception {
+ String cmd1 = "monkey -s 1337 -v -p " + PKGS[0] + " 500";
+ String out1 = mDevice.executeShellCommand(cmd1);
+ String out2 = mDevice.executeShellCommand(cmd1);
+ assertOutputs(out1, out2);
+
+ String cmd2 = "monkey -s 3007 -v -p " + PKGS[0] + " 125";
+ String out3 = mDevice.executeShellCommand(cmd2);
+ String out4 = mDevice.executeShellCommand(cmd2);
+ assertOutputs(out3, out4);
+ }
+
+ private void assertOutputs(String out1, String out2) {
+ Scanner s1 = new Scanner(out1);
+ Scanner s2 = new Scanner(out2);
+ int numEvents = 0;
+ while (true) {
+ String line1 = getNextLine(s1);
+ String line2 = getNextLine(s2);
+ if (line1 != null || line2 != null) {
+ assertEquals(line1, line2);
+ numEvents++;
+ } else {
+ break;
+ }
+ }
+ assertTrue(numEvents > 0);
+ }
+
+ private String getNextLine(Scanner sc) {
+ while (sc.hasNextLine()) {
+ String line = sc.nextLine().trim();
+ if (line.startsWith(":Sending")) {
+ return line;
+ }
+ }
+ return null;
+ }
+}
diff --git a/tests/appsecurity-tests/src/com/android/cts/monkey/VerbosityTest.java b/tests/appsecurity-tests/src/com/android/cts/monkey/VerbosityTest.java
new file mode 100644
index 0000000..2956191
--- /dev/null
+++ b/tests/appsecurity-tests/src/com/android/cts/monkey/VerbosityTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.monkey;
+
+public class VerbosityTest extends AbstractMonkeyTest {
+
+ public void testVerbosity() throws Exception {
+ String v0 = mDevice.executeShellCommand("monkey -s 1337 -p " + PKGS[0] + " 500");
+ assertTrue(v0.contains("Events injected"));
+ assertFalse(v0.contains("Sending Touch"));
+ assertFalse(v0.contains("Sending Trackball"));
+ assertFalse(v0.contains("Switch"));
+ assertFalse(v0.contains("Sleeping"));
+
+ String v1 = mDevice.executeShellCommand("monkey -v -p " + PKGS[0] + " 500");
+ assertTrue(v1.contains("Events injected"));
+ assertTrue(v1.contains("Sending Touch"));
+ assertTrue(v1.contains("Sending Trackball"));
+ assertTrue(v1.contains("Switch"));
+ assertFalse(v1.contains("Sleeping"));
+
+ String v2 = mDevice.executeShellCommand("monkey -v -v -p " + PKGS[0] + " 500");
+ assertTrue(v2.contains("Events injected"));
+ assertTrue(v2.contains("Sending Touch"));
+ assertTrue(v2.contains("Sending Trackball"));
+ assertTrue(v2.contains("Switch"));
+ assertTrue(v2.contains("Sleeping"));
+
+ assertTrue(v0.length() < v1.length());
+ assertTrue(v1.length() < v2.length());
+ }
+}
diff --git a/tests/appsecurity-tests/test-apps/CtsMonkeyApp/Android.mk b/tests/appsecurity-tests/test-apps/CtsMonkeyApp/Android.mk
new file mode 100644
index 0000000..85a82d8
--- /dev/null
+++ b/tests/appsecurity-tests/test-apps/CtsMonkeyApp/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_PACKAGE_NAME := CtsMonkeyApp
+
+include $(BUILD_PACKAGE)
diff --git a/tests/appsecurity-tests/test-apps/CtsMonkeyApp/AndroidManifest.xml b/tests/appsecurity-tests/test-apps/CtsMonkeyApp/AndroidManifest.xml
new file mode 100644
index 0000000..55f3d6f
--- /dev/null
+++ b/tests/appsecurity-tests/test-apps/CtsMonkeyApp/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.monkey">
+
+ <application>
+
+ <activity android:name=".MonkeyActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".BaboonActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.MONKEY" />
+ </intent-filter>
+ </activity>
+
+ </application>
+</manifest>
diff --git a/tests/appsecurity-tests/test-apps/CtsMonkeyApp/src/com/android/cts/monkey/BaboonActivity.java b/tests/appsecurity-tests/test-apps/CtsMonkeyApp/src/com/android/cts/monkey/BaboonActivity.java
new file mode 100644
index 0000000..f7b8f47
--- /dev/null
+++ b/tests/appsecurity-tests/test-apps/CtsMonkeyApp/src/com/android/cts/monkey/BaboonActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.monkey;
+
+import android.app.Activity;
+
+public class BaboonActivity extends Activity {
+}
diff --git a/tests/appsecurity-tests/test-apps/CtsMonkeyApp/src/com/android/cts/monkey/MonkeyActivity.java b/tests/appsecurity-tests/test-apps/CtsMonkeyApp/src/com/android/cts/monkey/MonkeyActivity.java
new file mode 100644
index 0000000..fd792a7
--- /dev/null
+++ b/tests/appsecurity-tests/test-apps/CtsMonkeyApp/src/com/android/cts/monkey/MonkeyActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.monkey;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.os.Bundle;
+import android.util.Log;
+
+/** @(>.<)@ I'm a monkey! */
+public class MonkeyActivity extends Activity {
+
+ private static final String TAG = "MonkeyActivity";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.i(TAG, ActivityManager.isUserAMonkey() ? "@(>.<)@" : "(^_^)");
+ }
+}
diff --git a/tests/appsecurity-tests/test-apps/CtsMonkeyApp2/Android.mk b/tests/appsecurity-tests/test-apps/CtsMonkeyApp2/Android.mk
new file mode 100644
index 0000000..2f3abd2
--- /dev/null
+++ b/tests/appsecurity-tests/test-apps/CtsMonkeyApp2/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_PACKAGE_NAME := CtsMonkeyApp2
+
+include $(BUILD_PACKAGE)
diff --git a/tests/appsecurity-tests/test-apps/CtsMonkeyApp2/AndroidManifest.xml b/tests/appsecurity-tests/test-apps/CtsMonkeyApp2/AndroidManifest.xml
new file mode 100644
index 0000000..34bca75
--- /dev/null
+++ b/tests/appsecurity-tests/test-apps/CtsMonkeyApp2/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.monkey2">
+
+ <application>
+
+ <activity android:name=".ChimpActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+</manifest>
diff --git a/tests/appsecurity-tests/test-apps/CtsMonkeyApp2/src/com/android/cts/monkey2/ChimpActivity.java b/tests/appsecurity-tests/test-apps/CtsMonkeyApp2/src/com/android/cts/monkey2/ChimpActivity.java
new file mode 100644
index 0000000..ef9fcc3
--- /dev/null
+++ b/tests/appsecurity-tests/test-apps/CtsMonkeyApp2/src/com/android/cts/monkey2/ChimpActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.monkey2;
+
+import android.app.Activity;
+
+public class ChimpActivity extends Activity {
+}
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 7d0ec98..b8621a7 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -8,12 +8,17 @@
bug: 4371654
},
{
+ name: "android.openglperf.cts.GlVboPerfTest#testVboWithVaryingIndexBufferNumbers",
+ bug: 5898262
+},
+{
name: "android.webkit.cts.WebViewTest#testRequestFocusNodeHref",
bug: 3241968
},
{
names: [
"libcore.java.net.URLConnectionTest#testServerClosesSocket",
+ "libcore.java.net.URLConnectionTest#testServerShutdownInput",
"libcore.java.net.URLConnectionTest#testServerShutdownOutput"
],
bug: 5534202
diff --git a/tests/src/android/provider/cts/FileCopyHelper.java b/tests/src/android/provider/cts/FileCopyHelper.java
index 4ee93ac..114c3ad 100644
--- a/tests/src/android/provider/cts/FileCopyHelper.java
+++ b/tests/src/android/provider/cts/FileCopyHelper.java
@@ -19,6 +19,7 @@
import android.content.Context;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -57,36 +58,36 @@
* @param fileName the file name
*
* @return the absolute path of the destination file
+ * @throws IOException
*/
- public String copy(int resId, String fileName) {
- InputStream source = null;
- OutputStream target = null;
+ public String copy(int resId, String fileName) throws IOException {
+ InputStream source = mContext.getResources().openRawResource(resId);
+ OutputStream target = mContext.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
+ copyFile(source, target);
+ mFilesList.add(fileName);
+ return mContext.getFileStreamPath(fileName).getAbsolutePath();
+ }
+ public void copyToExternalStorage(int resId, File path) throws IOException {
+ InputStream source = mContext.getResources().openRawResource(resId);
+ OutputStream target = new FileOutputStream(path);
+ copyFile(source, target);
+ }
+
+ private void copyFile(InputStream source, OutputStream target) throws IOException {
try {
- source = mContext.getResources().openRawResource(resId);
- target = mContext.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
-
byte[] buffer = new byte[1024];
for (int len = source.read(buffer); len > 0; len = source.read(buffer)) {
target.write(buffer, 0, len);
}
- } catch (IOException e) {
- e.printStackTrace();
} finally {
- try {
- if (source != null) {
- source.close();
- }
- if (target != null) {
- target.close();
- }
- } catch (IOException e) {
- // Ignore the IOException.
+ if (source != null) {
+ source.close();
+ }
+ if (target != null) {
+ target.close();
}
}
-
- mFilesList.add(fileName);
- return mContext.getFileStreamPath(fileName).getAbsolutePath();
}
/**
diff --git a/tests/tests/animation/Android.mk b/tests/tests/animation/Android.mk
new file mode 100644
index 0000000..ed9874e
--- /dev/null
+++ b/tests/tests/animation/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsAnimationTestCases
+
+# Don't include this package in any target.
+LOCAL_MODULE_TAGS := optional
+
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# All tests should include android.test.runner.
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+include $(BUILD_PACKAGE)
+
diff --git a/tests/tests/animation/AndroidManifest.xml b/tests/tests/animation/AndroidManifest.xml
new file mode 100644
index 0000000..f3fd898
--- /dev/null
+++ b/tests/tests/animation/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.animation">
+
+ <application>
+ <activity android:name="android.animation.cts.AnimationActivity"
+ android:label="AnimationActivity"/>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.cts.animation"
+ android:label="CTS tests for android.animation package"/>
+</manifest>
+
diff --git a/tests/tests/animation/res/layout/animation_main.xml b/tests/tests/animation/res/layout/animation_main.xml
new file mode 100644
index 0000000..81356a1
--- /dev/null
+++ b/tests/tests/animation/res/layout/animation_main.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+ <FrameLayout android:id="@+id/container" android:layout_width="fill_parent"
+ android:layout_height="fill_parent"/>
+</LinearLayout>
diff --git a/tests/tests/animation/src/android/animation/cts/AnimationActivity.java b/tests/tests/animation/src/android/animation/cts/AnimationActivity.java
new file mode 100644
index 0000000..43679c8
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/AnimationActivity.java
@@ -0,0 +1,256 @@
+/*
+ * 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.animation.cts;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
+import java.util.ArrayList;
+
+import com.android.cts.animation.R;
+
+public class AnimationActivity extends Activity {
+ private static final String BALL_HEIGHT = "ballwidth";
+ private static final String BALL_WIDTH = "ballheight";
+ private static final String STARTX = "startx";
+ private static final String STARTY = "starty";
+ private static final String DELTAX = "deltax";
+ private static final String DELTAY = "deltay";
+ private static final String DURATION = "duration";
+
+ float mBallHeight = 50f;
+ float mBallWidth = 50f;
+ float mStartX = 200f;
+ float mStartY = 200f;
+ float mDeltaX = 200f;
+ float mDeltaY = 200f;
+ long mDuration = 1000;
+ public AnimationView view = null;
+
+ @Override
+ public void onCreate(Bundle bundle){
+ super.onCreate(bundle);
+ Intent intent = this.getIntent();
+ Bundle extras = intent.getExtras();
+ if(extras != null) {
+ mBallHeight = extras.getFloat(BALL_HEIGHT);
+ mBallWidth = extras.getFloat(BALL_WIDTH);
+ mStartX = extras.getFloat(STARTX);
+ mStartY = extras.getFloat(STARTY);
+ mDeltaX = extras.getFloat(DELTAX);
+ mDeltaY = extras.getFloat(DELTAY);
+ mDuration = extras.getInt(DURATION);
+ }
+ setContentView(R.layout.animation_main);
+ view = new AnimationView(this);
+ ViewGroup viewGroup = (ViewGroup) findViewById(R.id.container);
+ viewGroup.addView(view);
+ }
+
+ public ValueAnimator createAnimator(Object object,String propertyName, long duration,
+ int repeatCount, int repeatMode,
+ TimeInterpolator timeInterpolator, float start, float end){
+ ValueAnimator valueAnimator = ObjectAnimator.ofFloat(object, propertyName, start,end);
+ valueAnimator.setDuration(duration);
+ valueAnimator.setRepeatCount(repeatCount);
+ valueAnimator.setInterpolator(timeInterpolator);
+ valueAnimator.setRepeatMode(repeatMode);
+ return valueAnimator;
+ }
+
+ public ValueAnimator createAnimatorWithRepeatMode(int repeatMode) {
+ return createAnimator(view.newBall, "y", 1000, ValueAnimator.INFINITE, repeatMode,
+ new AccelerateInterpolator(), mStartY, mStartY + mDeltaY);
+ }
+
+ public ValueAnimator createAnimatorWithRepeatCount(int repeatCount) {
+ return createAnimator(view.newBall, "y", 1000, repeatCount, ValueAnimator.REVERSE,
+ new AccelerateInterpolator(), mStartY, mStartY + mDeltaY);
+ }
+
+ public ValueAnimator createAnimatorWithDuration(long duration) {
+ return createAnimator(view.newBall, "y", duration ,ValueAnimator.INFINITE,
+ ValueAnimator.REVERSE,new AccelerateInterpolator(), mStartY, mStartY + mDeltaY);
+ }
+
+ public ValueAnimator createAnimatorWithInterpolator(TimeInterpolator interpolator){
+ return createAnimator(view.newBall, "y", 1000, ValueAnimator.INFINITE, ValueAnimator.REVERSE,
+ interpolator, mStartY, mStartY + mDeltaY);
+ }
+
+ public ValueAnimator createObjectAnimatorForInt(Object object,String propertyName,
+ long duration, int repeatCount, int repeatMode, TimeInterpolator timeInterpolator,
+ int start, int end) {
+ ObjectAnimator objAnimator = ObjectAnimator.ofInt(object, propertyName, start,end);
+ objAnimator.setDuration(duration);
+
+ objAnimator.setRepeatCount(repeatCount);
+ objAnimator.setInterpolator(timeInterpolator);
+ objAnimator.setRepeatMode(repeatMode);
+ return objAnimator;
+ }
+
+ public ValueAnimator createObjectAnimatorForInt() {
+ ObjectAnimator objAnimator = ObjectAnimator.ofInt(view.newBall, "y", (int)mStartY,
+ (int)(mStartY + mDeltaY));
+ objAnimator.setDuration(mDuration);
+
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(new AccelerateInterpolator());
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ return objAnimator;
+ }
+
+ public void startAnimation(long duration){
+ ValueAnimator bounceAnimator = ObjectAnimator.ofFloat(view.newBall, "y", mStartY,
+ mStartY + mDeltaY);
+ bounceAnimator.setDuration(duration);
+ bounceAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ bounceAnimator.setInterpolator(new AccelerateInterpolator());
+ bounceAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ view.bounceAnimator = bounceAnimator;
+ view.startColorAnimator();
+ view.animateBall();
+ }
+
+ public void startAnimation(ValueAnimator valueAnimator){
+ view.bounceAnimator = valueAnimator;
+ view.startColorAnimator();
+ view.animateBall();
+ }
+
+ public void startAnimation(ObjectAnimator bounceAnimator) {
+ view.bounceAnimator = bounceAnimator;
+ view.startColorAnimator();
+ view.animateBall();
+ }
+
+ public void startAnimation(ObjectAnimator bounceAnimator, ObjectAnimator colorAnimator) {
+ view.bounceAnimator = bounceAnimator;
+ view.startColorAnimator(colorAnimator);
+ view.animateBall();
+ }
+
+ public void startColorAnimation(ValueAnimator colorAnimator){
+ view.startColorAnimator(colorAnimator);
+ }
+
+ public class AnimationView extends View {
+ public static final int RED = 0xffFF8080;
+ public static final int BLUE = 0xff8080FF;
+ public ShapeHolder newBall = null;
+ public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
+ AnimatorSet animation = null;
+ public ValueAnimator bounceAnimator;
+ public ValueAnimator colorAnimator;
+
+ public AnimationView(Context context) {
+ super(context);
+ newBall = addBall(mBallHeight, mBallWidth);
+ }
+
+ public void startColorAnimator() {
+ colorAnimator = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE);
+ colorAnimator.setDuration(1000);
+ colorAnimator.setEvaluator(new ArgbEvaluator());
+ colorAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ colorAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ colorAnimator.start();
+ }
+
+ public void startColorAnimator(ValueAnimator animator) {
+ this.colorAnimator = animator;
+ colorAnimator.start();
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return true;
+ }
+
+ public void animateBall() {
+ float startY = mStartY;
+ float endY = startY + mDeltaY;
+ AnimatorSet bouncer = new AnimatorSet();
+ bouncer.play(bounceAnimator);
+ // Fading animation - remove the ball when the animation is done
+ ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+ fadeAnim.setDuration(250);
+ fadeAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ balls.remove(((ObjectAnimator)animation).getTarget());
+ }
+ });
+
+ // Sequence the two animations to play one after the other
+ AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.play(bouncer).before(fadeAnim);
+ animatorSet.start();
+ }
+
+ private ShapeHolder addBall(float x, float y) {
+ OvalShape circle = new OvalShape();
+ circle.resize(x, y);
+ ShapeDrawable drawable = new ShapeDrawable(circle);
+ ShapeHolder shapeHolder = new ShapeHolder(drawable);
+ shapeHolder.setX(x - 25f);
+ shapeHolder.setY(y - 25f);
+ Paint paint = drawable.getPaint();
+ shapeHolder.setPaint(paint);
+ int red = (int)(Math.random() * 255);
+ int green = (int)(Math.random() * 255);
+ int blue = (int)(Math.random() * 255);
+ int color = 0xff000000 | red << 16 | green << 8 | blue;
+ int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;
+ RadialGradient gradient = new RadialGradient(37.5f, 12.5f,
+ 50f, color, darkColor, Shader.TileMode.CLAMP);
+ paint.setShader(gradient);
+ balls.add(shapeHolder);
+ return shapeHolder;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ for (int i = 0; i < balls.size(); ++i) {
+ ShapeHolder shapeHolder = balls.get(i);
+ canvas.save();
+ canvas.translate(shapeHolder.getX(), shapeHolder.getY());
+ shapeHolder.getShape().draw(canvas);
+ canvas.restore();
+ }
+ }
+ }
+}
diff --git a/tests/tests/animation/src/android/animation/cts/ArgbEvaluatorTest.java b/tests/tests/animation/src/android/animation/cts/ArgbEvaluatorTest.java
new file mode 100644
index 0000000..33c3716
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/ArgbEvaluatorTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.animation.cts;
+
+import android.animation.ArgbEvaluator;
+import android.graphics.Color;
+import android.test.InstrumentationTestCase;
+
+public class ArgbEvaluatorTest extends InstrumentationTestCase {
+ public void testEvaluate() throws Throwable {
+ final int RED = 0xffFF8080;
+ final int BLUE = 0xff8080FF;
+ int aRED = Color.alpha(RED);
+ int rRED = Color.red(RED);
+ int gRED = Color.green(RED);
+ int bRED = Color.blue(RED);
+ int aBLUE = Color.alpha(BLUE);
+ int rBLUE = Color.red(BLUE);
+ int gBLUE = Color.green(BLUE);
+ int bBLUE = Color.blue(BLUE);
+
+ final ArgbEvaluator evaluator = new ArgbEvaluator();
+ class AnimationRunnable implements Runnable{
+ int result;
+ public void run() {
+ result = (Integer) evaluator.evaluate(0.5f, RED, BLUE);
+ }
+ }
+ AnimationRunnable aRunnable = new AnimationRunnable();
+ this.runTestOnUiThread(aRunnable);
+ Thread.sleep(100);
+ int result = aRunnable.result;
+
+ int aResult = Color.alpha(result);
+ int rResult = Color.red(result);
+ int gResult = Color.green(result);
+ int bResult = Color.blue(result);
+ assertTrue(aResult >= aRED);
+ assertTrue(aResult <= aBLUE);
+ assertTrue(rResult <= rRED);
+ assertTrue(rResult >= rBLUE);
+ assertTrue(gResult >= gRED);
+ assertTrue(gResult <= gBLUE);
+ assertTrue(bResult >= bRED);
+ assertTrue(bResult <= bBLUE);
+ }
+}
+
diff --git a/tests/tests/animation/src/android/animation/cts/FloatEvaluatorTest.java b/tests/tests/animation/src/android/animation/cts/FloatEvaluatorTest.java
new file mode 100644
index 0000000..8cc1ffe
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/FloatEvaluatorTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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.animation.cts;
+
+import android.animation.FloatEvaluator;
+import android.test.InstrumentationTestCase;
+
+public class FloatEvaluatorTest extends InstrumentationTestCase {
+ public void testEvaluate() {
+ float start = 0.0f;
+ float end = 1.0f;
+ float fraction = 0.5f;
+ FloatEvaluator floatEvaluator = new FloatEvaluator();
+ float result = floatEvaluator.evaluate(fraction, start, end);
+ assertTrue(result >= (fraction*start));
+ assertTrue(result <= (fraction*end));
+ }
+}
+
diff --git a/tests/tests/animation/src/android/animation/cts/IntEvaluatorTest.java b/tests/tests/animation/src/android/animation/cts/IntEvaluatorTest.java
new file mode 100644
index 0000000..11df20c
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/IntEvaluatorTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.animation.cts;
+
+import android.animation.IntEvaluator;
+import android.test.InstrumentationTestCase;
+
+public class IntEvaluatorTest extends InstrumentationTestCase {
+ public void testEvaluate() throws Throwable {
+ final int start = 0;
+ final int end = 100;
+ final float fraction = 0.5f;
+ final IntEvaluator intEvaluator = new IntEvaluator();
+ class AnimationRunnable implements Runnable{
+ int result;
+ public void run() {
+ result = intEvaluator.evaluate(fraction, start, end);
+ }
+ }
+ AnimationRunnable aRunnable = new AnimationRunnable();
+ this.runTestOnUiThread(aRunnable);
+ Thread.sleep(1);
+ int result = aRunnable.result;
+ assertTrue(result >= (fraction*start));
+ assertTrue(result <= (fraction*end));
+ }
+}
+
diff --git a/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
new file mode 100644
index 0000000..be5c1d4
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
@@ -0,0 +1,269 @@
+/*
+ * 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.animation.cts;
+
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Property;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Interpolator;
+
+public class ObjectAnimatorTest extends
+ ActivityInstrumentationTestCase2<AnimationActivity> {
+ private AnimationActivity mActivity;
+ private ObjectAnimator mObjectAnimator;
+ private long mDuration = 1000;
+
+ public ObjectAnimatorTest() {
+ super(AnimationActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ setActivityInitialTouchMode(false);
+ mActivity = getActivity();
+ mObjectAnimator = (ObjectAnimator) mActivity.createAnimatorWithDuration(mDuration);
+ }
+
+ public void testDuration() throws Throwable {
+ final long duration = 2000;
+ ObjectAnimator objectAnimatorLocal = (ObjectAnimator)mActivity.createAnimatorWithDuration(
+ duration);
+ startAnimation(objectAnimatorLocal);
+ assertEquals(duration, objectAnimatorLocal.getDuration());
+ }
+ public void testOfFloat() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ ObjectAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ assertTrue(objAnimator != null);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(new AccelerateInterpolator());
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ startAnimation(objAnimator);
+ assertTrue(objAnimator != null);
+ Thread.sleep(100);
+ float x = mActivity.view.newBall.getX();
+ float y = mActivity.view.newBall.getY();
+ assertTrue( y >= startY);
+ assertTrue( y <= endY);
+ }
+
+ public void testOfFloatBase() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ ObjectAnimator animator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ ObjectAnimator objAnimator = new ObjectAnimator();
+ objAnimator.setTarget(object);
+ objAnimator.setPropertyName(property);
+ assertEquals(animator.getTarget(), objAnimator.getTarget());
+ assertEquals(animator.getPropertyName(), objAnimator.getPropertyName());
+ }
+
+ public void testOfInt() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+
+ ObjectAnimator colorAnimator = ObjectAnimator.ofInt(object, property,
+ startColor, endColor);
+ colorAnimator.setDuration(1000);
+ colorAnimator.setEvaluator(new ArgbEvaluator());
+ colorAnimator.setRepeatCount(1);
+ colorAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ colorAnimator.start();
+ startAnimation(mObjectAnimator, colorAnimator);
+ Thread.sleep(100);
+ Integer i = (Integer) colorAnimator.getAnimatedValue();
+ //We are going from less negative value to a more negative value
+ assertTrue(i.intValue() <= startColor);
+ assertTrue(endColor <= i.intValue());
+ }
+
+ public void testOfObject() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+ Object[] values = {new Integer(startColor), new Integer(endColor)};
+ ArgbEvaluator evaluator = new ArgbEvaluator();
+ ObjectAnimator colorAnimator = ObjectAnimator.ofObject(object, property,
+ evaluator, values);
+ colorAnimator.setDuration(1000);
+ colorAnimator.setRepeatCount(1);
+ colorAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ colorAnimator.start();
+ startAnimation(mObjectAnimator, colorAnimator);
+ Thread.sleep(100);
+ Integer i = (Integer) colorAnimator.getAnimatedValue();
+ //We are going from less negative value to a more negative value
+ assertTrue(i.intValue() <= startColor);
+ assertTrue(endColor <= i.intValue());
+ }
+
+ public void testOfPropertyValuesHolder() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String propertyName = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+ int values[] = {startColor, endColor};
+ ArgbEvaluator evaluator = new ArgbEvaluator();
+ PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofInt(propertyName, values);
+ ObjectAnimator colorAnimator = ObjectAnimator.ofPropertyValuesHolder(object,
+ propertyValuesHolder);
+ colorAnimator.setDuration(1000);
+ colorAnimator.setRepeatCount(1);
+ colorAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ colorAnimator.start();
+ startAnimation(mObjectAnimator, colorAnimator);
+ Thread.sleep(100);
+ Integer i = (Integer) colorAnimator.getAnimatedValue();
+ //We are going from less negative value to a more negative value
+ assertTrue(i.intValue() <= startColor);
+ assertTrue(endColor <= i.intValue());
+ }
+
+ public void testGetPropertyName() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String propertyName = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+ Object[] values = {new Integer(startColor), new Integer(endColor)};
+ ArgbEvaluator evaluator = new ArgbEvaluator();
+ ObjectAnimator colorAnimator = ObjectAnimator.ofObject(object, propertyName,
+ evaluator, values);
+ String actualPropertyName = colorAnimator.getPropertyName();
+ assertEquals(propertyName, actualPropertyName);
+ }
+
+ public void testSetCurrentPlayTime() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String propertyName = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+ long playTime = 10000l;
+ Object[] values = {new Integer(startColor), new Integer(endColor)};
+ ArgbEvaluator evaluator = new ArgbEvaluator();
+ ObjectAnimator colorAnimator = ObjectAnimator.ofObject(object, propertyName,
+ evaluator, values);
+ colorAnimator.setCurrentPlayTime(playTime);
+ long actualPlayTime = colorAnimator.getCurrentPlayTime();
+ assertEquals(playTime, actualPlayTime);
+ }
+
+ public void testSetFloatValues() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ float[] values = {startY, endY};
+ ObjectAnimator objAnimator = new ObjectAnimator();
+ objAnimator.setTarget(object);
+ objAnimator.setPropertyName(property);
+ objAnimator.setFloatValues(values);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(new AccelerateInterpolator());
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ startAnimation(objAnimator);
+ Thread.sleep(100);
+ float y = mActivity.view.newBall.getY();
+ assertTrue( y >= startY);
+ assertTrue( y <= endY);
+ }
+
+ public void testGetTarget() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String propertyName = "backgroundColor";
+ int startColor = mActivity.view.RED;
+ int endColor = mActivity.view.BLUE;
+ Object[] values = {new Integer(startColor), new Integer(endColor)};
+ ArgbEvaluator evaluator = new ArgbEvaluator();
+ ObjectAnimator colorAnimator = ObjectAnimator.ofObject(object, propertyName,
+ evaluator, values);
+ Object target = colorAnimator.getTarget();
+ assertEquals(object, target);
+ }
+
+ public void testClone() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ Interpolator interpolator = new AccelerateInterpolator();
+ ObjectAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(interpolator);
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ ObjectAnimator cloneAnimator = objAnimator.clone();
+
+ assertEquals(mDuration, cloneAnimator.getDuration());
+ assertEquals(ValueAnimator.INFINITE, cloneAnimator.getRepeatCount());
+ assertEquals(ValueAnimator.REVERSE, cloneAnimator.getRepeatMode());
+ assertEquals(object, cloneAnimator.getTarget());
+ assertEquals(property, cloneAnimator.getPropertyName());
+ assertEquals(interpolator, cloneAnimator.getInterpolator());
+ }
+
+ public void testIsStarted() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ Interpolator interpolator = new AccelerateInterpolator();
+ ObjectAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(interpolator);
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ startAnimation(objAnimator);
+ Thread.sleep(100);
+ assertTrue(objAnimator.isStarted());
+ Thread.sleep(100);
+ }
+
+ private void startAnimation(final ObjectAnimator mObjectAnimator) throws Throwable {
+ Thread mAnimationRunnable = new Thread() {
+ public void run() {
+ mActivity.startAnimation(mObjectAnimator);
+ }
+ };
+ this.runTestOnUiThread(mAnimationRunnable);
+ }
+ private void startAnimation(final ObjectAnimator mObjectAnimator, final
+ ObjectAnimator colorAnimator) throws Throwable {
+ Thread mAnimationRunnable = new Thread() {
+ public void run() {
+ mActivity.startAnimation(mObjectAnimator, colorAnimator);
+ }
+ };
+ this.runTestOnUiThread(mAnimationRunnable);
+ }
+}
+
+
diff --git a/tests/tests/animation/src/android/animation/cts/ShapeHolder.java b/tests/tests/animation/src/android/animation/cts/ShapeHolder.java
new file mode 100644
index 0000000..f8d5fa6
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/ShapeHolder.java
@@ -0,0 +1,111 @@
+/*
+ * 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.animation.cts;
+
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.Shape;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+
+/**
+ * A data structure that holds a Shape and various properties that can be used to define
+ * how the shape is drawn.
+ */
+public class ShapeHolder {
+ private float mX = 0, mY = 0;
+ private ShapeDrawable mShape;
+ private int mColor;
+ private RadialGradient mGradient;
+ private float mAlpha = 1f;
+ private Paint mPaint;
+
+ public void setPaint(Paint value) {
+ mPaint = value;
+ }
+
+ public Paint getPaint() {
+ return mPaint;
+ }
+
+ public void setX(float value) {
+ mX = value;
+ }
+
+ public float getX() {
+ return mX;
+ }
+
+ public void setY(float value) {
+ mY = value;
+ }
+
+ public float getY() {
+ return mY;
+ }
+
+ public void setShape(ShapeDrawable value) {
+ mShape = value;
+ }
+
+ public ShapeDrawable getShape() {
+ return mShape;
+ }
+
+ public int getColor() {
+ return mColor;
+ }
+
+ public void setColor(int value) {
+ mShape.getPaint().setColor(value);
+ mColor = value;
+ }
+
+ public void setGradient(RadialGradient value) {
+ mGradient = value;
+ }
+ public RadialGradient getGradient() {
+ return mGradient;
+ }
+
+ public void setAlpha(float alpha) {
+ this.mAlpha = alpha;
+ mShape.setAlpha((int)((alpha * 255f) + .5f));
+ }
+
+ public float getWidth() {
+ return mShape.getShape().getWidth();
+ }
+
+ public void setWidth(float width) {
+ Shape s = mShape.getShape();
+ s.resize(width, s.getHeight());
+ }
+
+ public float getHeight() {
+ return mShape.getShape().getHeight();
+ }
+
+ public void setHeight(float height) {
+ Shape s = mShape.getShape();
+ s.resize(s.getWidth(), height);
+ }
+
+ public ShapeHolder(ShapeDrawable s) {
+ mShape = s;
+ }
+}
+
diff --git a/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
new file mode 100644
index 0000000..a7626bc
--- /dev/null
+++ b/tests/tests/animation/src/android/animation/cts/ValueAnimatorTest.java
@@ -0,0 +1,263 @@
+/*
+ * 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.animation.cts;
+
+import android.animation.ArgbEvaluator;
+import android.animation.FloatEvaluator;
+import android.animation.IntEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.animation.AccelerateInterpolator;
+
+public class ValueAnimatorTest extends
+ ActivityInstrumentationTestCase2<AnimationActivity> {
+ private AnimationActivity mActivity;
+ private ValueAnimator mValueAnimator;
+ private long mDuration = 1000;
+
+ public ValueAnimatorTest() {
+ super(AnimationActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ setActivityInitialTouchMode(false);
+ mActivity = getActivity();
+ mValueAnimator = mActivity.createAnimatorWithDuration(mDuration);
+ }
+
+ public void testDuration() throws Throwable {
+ final long duration = 2000;
+ ValueAnimator valueAnimatorLocal = mActivity.createAnimatorWithDuration(duration);
+ startAnimation(valueAnimatorLocal);
+ assertEquals(duration, valueAnimatorLocal.getDuration());
+ }
+
+ public void testIsRunning() throws Throwable {
+ assertFalse(mValueAnimator.isRunning());
+ startAnimation(mValueAnimator);
+ ValueAnimator valueAnimatorReturned = mActivity.view.bounceAnimator;
+ assertTrue(valueAnimatorReturned.isRunning());
+ }
+
+ public void testIsStarted() throws Throwable {
+ assertFalse(mValueAnimator.isRunning());
+ assertFalse(mValueAnimator.isStarted());
+ long startDelay = 10000;
+ mValueAnimator.setStartDelay(startDelay);
+ startAnimation(mValueAnimator);
+ assertFalse(mValueAnimator.isRunning());
+ assertTrue(mValueAnimator.isStarted());
+ }
+
+ public void testRepeatMode() throws Throwable {
+ ValueAnimator mValueAnimator = mActivity.createAnimatorWithRepeatMode(ValueAnimator.RESTART);
+ startAnimation(mValueAnimator);
+ assertEquals(ValueAnimator.RESTART, mValueAnimator.getRepeatMode());
+ }
+
+ public void testRepeatCount() throws Throwable {
+ int repeatCount = 2;
+ ValueAnimator mValueAnimator = mActivity.createAnimatorWithRepeatCount(repeatCount);
+ startAnimation(mValueAnimator);
+ assertEquals(repeatCount, mValueAnimator.getRepeatCount());
+ }
+
+ public void testStartDelay() {
+ long startDelay = 1000;
+ mValueAnimator.setStartDelay(startDelay);
+ assertEquals(startDelay, mValueAnimator.getStartDelay());
+ }
+
+ public void testCurrentPlayTime() throws Throwable {
+ startAnimation(mValueAnimator);
+ Thread.sleep(100);
+ long currentPlayTime = mValueAnimator.getCurrentPlayTime();
+ assertTrue(currentPlayTime > 0);
+ }
+
+ public void testGetFrameDelay() throws Throwable {
+ long frameDelay = 10;
+ mValueAnimator.setFrameDelay(frameDelay);
+ startAnimation(mValueAnimator);
+ Thread.sleep(100);
+ long actualFrameDelay = mValueAnimator.getFrameDelay();
+ assertEquals(frameDelay, actualFrameDelay);
+ }
+
+ public void testSetInterpolator() throws Throwable {
+ AccelerateInterpolator interpolator = new AccelerateInterpolator();
+ ValueAnimator mValueAnimator = mActivity.createAnimatorWithInterpolator(interpolator);
+ startAnimation(mValueAnimator);
+ assertTrue(interpolator.equals(mValueAnimator.getInterpolator()));
+ }
+
+ public void testCancel() throws Throwable {
+ startAnimation(mValueAnimator);
+ Thread.sleep(100);
+ mValueAnimator.cancel();
+ assertFalse(mValueAnimator.isRunning());
+ }
+
+ public void testEnd() throws Throwable {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ ObjectAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(new AccelerateInterpolator());
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ startAnimation(objAnimator);
+ Thread.sleep(100);
+ endAnimation(objAnimator);
+ float y = mActivity.view.newBall.getY();
+ assertEquals(y, endY);
+ }
+
+ public void testGetAnimatedFraction() throws Throwable {
+ ValueAnimator objAnimator = getAnimator();
+ startAnimation(objAnimator);
+ assertNotNull(objAnimator);
+ float[] fractions = getValue(objAnimator, 10, "getAnimatedFraction()", 100l, null);
+ for(int j = 0; j < 9; j++){
+ assertTrue(fractions[j] >= 0.0);
+ assertTrue(fractions[j] <= 1.0);
+ assertTrue(fractions[j + 1] != fractions[j]);
+ }
+ }
+
+ public void testGetAnimatedValue() throws Throwable {
+ ValueAnimator objAnimator = getAnimator();
+ startAnimation(objAnimator);
+ assertNotNull(objAnimator);
+ float[] animatedValues = getValue(objAnimator, 10, "getAnimatedValue()", 100l, null);
+
+ for(int j = 0; j < 9; j++){
+ assertTrue(animatedValues[j + 1] != animatedValues[j]);
+ }
+ }
+ public void testGetAnimatedValue_PropertyName() throws Throwable {
+ String property = "y";
+
+ ValueAnimator objAnimator = getAnimator();
+ startAnimation(objAnimator);
+ assertNotNull(objAnimator);
+ float[] animatedValues = getValue(objAnimator, 10, "getAnimatedValue(property)", 100l,
+ property);
+ for(int j = 0; j < 9; j++){
+ assertTrue(animatedValues[j + 1] != animatedValues[j]);
+ }
+ }
+
+ public void testOfFloat() throws Throwable {
+ float start = 0.0f;
+ float end = 1.0f;
+ float[] values = {start, end};
+ final ValueAnimator valueAnimatorLocal = ValueAnimator.ofFloat(values);
+ valueAnimatorLocal.setDuration(mDuration);
+ valueAnimatorLocal.setRepeatCount(ValueAnimator.INFINITE);
+ valueAnimatorLocal.setInterpolator(new AccelerateInterpolator());
+ valueAnimatorLocal.setRepeatMode(ValueAnimator.RESTART);
+
+ this.runTestOnUiThread(new Runnable(){
+ public void run() {
+ valueAnimatorLocal.start();
+ }
+ });
+ Thread.sleep(100);
+ boolean isRunning = valueAnimatorLocal.isRunning();
+ assertTrue(isRunning);
+
+ Float animatedValue = (Float) valueAnimatorLocal.getAnimatedValue();
+ assertTrue(animatedValue >= start);
+ assertTrue(animatedValue <= end);
+ }
+
+ public void testOfInt() throws Throwable {
+ int start = 0;
+ int end = 10;
+ int[] values = {start, end};
+ final ValueAnimator valueAnimatorLocal = ValueAnimator.ofInt(values);
+ valueAnimatorLocal.setDuration(mDuration);
+ valueAnimatorLocal.setRepeatCount(ValueAnimator.INFINITE);
+ valueAnimatorLocal.setInterpolator(new AccelerateInterpolator());
+ valueAnimatorLocal.setRepeatMode(ValueAnimator.RESTART);
+
+ this.runTestOnUiThread(new Runnable(){
+ public void run() {
+ valueAnimatorLocal.start();
+ }
+ });
+ Thread.sleep(100);
+ boolean isRunning = valueAnimatorLocal.isRunning();
+ assertTrue(isRunning);
+
+ Integer animatedValue = (Integer) valueAnimatorLocal.getAnimatedValue();
+ assertTrue(animatedValue >= start);
+ assertTrue(animatedValue <= end);
+ }
+
+ private ValueAnimator getAnimator() {
+ Object object = mActivity.view.newBall;
+ String property = "y";
+ float startY = mActivity.mStartY;
+ float endY = mActivity.mStartY + mActivity.mDeltaY;
+ ValueAnimator objAnimator = ObjectAnimator.ofFloat(object, property, startY, endY);
+ objAnimator.setDuration(mDuration);
+ objAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ objAnimator.setInterpolator(new AccelerateInterpolator());
+ objAnimator.setRepeatMode(ValueAnimator.REVERSE);
+ return objAnimator;
+ }
+
+ private float[] getValue(ValueAnimator animator, int n, String methodName,
+ long sleepTime, String property) throws InterruptedException {
+ float[] values = new float[n];
+ for(int i = 0; i < (n-1); i++){
+ Thread.sleep(sleepTime);
+ float value = 0.0f;
+ if(methodName.equals("getAnimatedFraction()")) {
+ value = animator.getAnimatedFraction();
+ }else if(methodName.equals("getAnimatedValue()")) {
+ value = ((Float)animator.getAnimatedValue()).floatValue();
+ }else if(methodName.equals("getAnimatedValue(property)")) {
+ value = ((Float)animator.getAnimatedValue(property)).floatValue();
+ }
+ values[i] = value;
+ }
+ return values;
+ }
+ private void startAnimation(final ValueAnimator mValueAnimator) throws Throwable {
+ this.runTestOnUiThread(new Runnable(){
+ public void run() {
+ mActivity.startAnimation(mValueAnimator);
+ }
+ });
+ }
+ private void endAnimation(final ValueAnimator mValueAnimator) throws Throwable {
+ Thread animationRunnable = new Thread() {
+ public void run() {
+ mValueAnimator.end();
+ }
+ };
+ this.runTestOnUiThread(animationRunnable);
+ }
+}
+
diff --git a/tests/tests/app/src/android/app/cts/ActionBarActivity.java b/tests/tests/app/src/android/app/cts/ActionBarActivity.java
new file mode 100644
index 0000000..11cee03
--- /dev/null
+++ b/tests/tests/app/src/android/app/cts/ActionBarActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app.cts;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+
+public class ActionBarActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ActionBar bar = getActionBar();
+ bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+ }
+}
diff --git a/tests/tests/app/src/android/app/cts/ActionBarTest.java b/tests/tests/app/src/android/app/cts/ActionBarTest.java
new file mode 100644
index 0000000..796cd74
--- /dev/null
+++ b/tests/tests/app/src/android/app/cts/ActionBarTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.app.cts;
+
+import android.app.ActionBar;
+import android.app.ActionBar.Tab;
+import android.app.ActionBar.TabListener;
+import android.app.FragmentTransaction;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+
+public class ActionBarTest extends ActivityInstrumentationTestCase2<ActionBarActivity> {
+
+ private ActionBarActivity mActivity;
+ private ActionBar mBar;
+
+ public ActionBarTest() {
+ super(ActionBarActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mBar = mActivity.getActionBar();
+ }
+
+ @UiThreadTest
+ public void testAddTab() {
+ assertEquals(0, mBar.getTabCount());
+
+ Tab t1 = createTab("Tab 1");
+ mBar.addTab(t1);
+ assertEquals(1, mBar.getTabCount());
+ assertEquals(t1, mBar.getSelectedTab());
+ assertEquals(t1, mBar.getTabAt(0));
+
+ Tab t2 = createTab("Tab 2");
+ mBar.addTab(t2);
+ assertEquals(2, mBar.getTabCount());
+ assertEquals(t1, mBar.getSelectedTab());
+ assertEquals(t2, mBar.getTabAt(1));
+
+ Tab t3 = createTab("Tab 3");
+ mBar.addTab(t3, true);
+ assertEquals(3, mBar.getTabCount());
+ assertEquals(t3, mBar.getSelectedTab());
+ assertEquals(t3, mBar.getTabAt(2));
+
+ Tab t4 = createTab("Tab 2.5");
+ mBar.addTab(t4, 2);
+ assertEquals(4, mBar.getTabCount());
+ assertEquals(t4, mBar.getTabAt(2));
+ assertEquals(t3, mBar.getTabAt(3));
+
+ Tab t5 = createTab("Tab 0.5");
+ mBar.addTab(t5, 0, true);
+ assertEquals(5, mBar.getTabCount());
+ assertEquals(t5, mBar.getSelectedTab());
+ assertEquals(t5, mBar.getTabAt(0));
+ assertEquals(t1, mBar.getTabAt(1));
+ assertEquals(t2, mBar.getTabAt(2));
+ assertEquals(t4, mBar.getTabAt(3));
+ assertEquals(t3, mBar.getTabAt(4));
+ }
+
+ private Tab createTab(String name) {
+ return mBar.newTab().setText("Tab 1").setTabListener(new TestTabListener());
+ }
+
+ static class TestTabListener implements TabListener {
+ @Override
+ public void onTabSelected(Tab tab, FragmentTransaction ft) {
+ }
+
+ @Override
+ public void onTabUnselected(Tab tab, FragmentTransaction ft) {
+ }
+
+ @Override
+ public void onTabReselected(Tab tab, FragmentTransaction ft) {
+ }
+ }
+}
diff --git a/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
index 41a5224..a68cfb8 100644
--- a/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -343,14 +343,17 @@
}
public void testWifiFeature() throws Exception {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+ // no WiFi, skip the test
+ return;
+ }
boolean enabled = mWifiManager.isWifiEnabled();
try {
- // WifiManager is hard-coded to return true, but in other implementations this could
- // return false for devices that don't have WiFi.
+ // WifiManager is hard-coded to return true,
+ // the case without WiFi is already handled,
+ // so this case MUST have WiFi.
if (mWifiManager.setWifiEnabled(true)) {
assertAvailable(PackageManager.FEATURE_WIFI);
- } else {
- assertNotAvailable(PackageManager.FEATURE_WIFI);
}
} finally {
if (!enabled) {
diff --git a/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java b/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java
index 1cc4cfb..2da0bfb 100644
--- a/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java
+++ b/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java
@@ -57,6 +57,9 @@
// Need to clean up created account
removeAccount(sAccountManager, ACCOUNT, null /* callback */);
+ // Need to cancel any sync that was started.
+ cancelSync(null, AUTHORITY, LATCH_TIMEOUT_MS);
+
super.tearDown();
}
@@ -87,8 +90,8 @@
}
private CountDownLatch setNewLatch(CountDownLatch latch) {
- getMockSyncAdapter().setLatch(latch);
getMockSyncAdapter().clearData();
+ getMockSyncAdapter().setLatch(latch);
return latch;
}
@@ -101,7 +104,9 @@
// Wait with timeout for the callback to do its work
try {
- latch.await(latchTimeoutMs, TimeUnit.MILLISECONDS);
+ if (!latch.await(latchTimeoutMs, TimeUnit.MILLISECONDS)) {
+ fail("should not time out waiting on latch");
+ }
} catch (InterruptedException e) {
fail("should not throw an InterruptedException");
}
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/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/graphics2/Android.mk b/tests/tests/graphics2/Android.mk
new file mode 100644
index 0000000..d977ee8
--- /dev/null
+++ b/tests/tests/graphics2/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsGraphics2TestCases
+
+LOCAL_INSTRUMENTATION_FOR :=
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tests/tests/graphics2/AndroidManifest.xml b/tests/tests/graphics2/AndroidManifest.xml
new file mode 100644
index 0000000..e26b962
--- /dev/null
+++ b/tests/tests/graphics2/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.graphics2"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-feature android:name="android.hardware.camera" />
+
+ <instrumentation
+ android:targetPackage="com.android.cts.graphics2"
+ android:name="android.test.InstrumentationTestRunner" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="android.graphics2.cts.TextureViewCameraActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/tests/tests/graphics2/src/android/graphics2/cts/TextureViewCameraActivity.java b/tests/tests/graphics2/src/android/graphics2/cts/TextureViewCameraActivity.java
new file mode 100644
index 0000000..d947565
--- /dev/null
+++ b/tests/tests/graphics2/src/android/graphics2/cts/TextureViewCameraActivity.java
@@ -0,0 +1,111 @@
+/*
+ * 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.graphics2.cts;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.SurfaceTexture;
+import android.hardware.Camera;
+import android.os.Bundle;
+import android.view.TextureView;
+import android.view.View;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.Assert;
+
+
+public class TextureViewCameraActivity extends Activity implements
+ TextureView.SurfaceTextureListener {
+ private static final int CAPTURE_SCREEN_INTERVAL = 10;
+ private static final float SCREEN_ROTATION_RATE = 1.0f;
+ private static final int MAX_FRAME_UPDATE = 40;
+ private Camera mCamera;
+ private TextureView mTextureView;
+ private int mUpdateCounter = 0;
+ private int mWidth;
+ private int mHeight;
+ private float mRotation = 0f;
+ private final CountDownLatch mLatch = new CountDownLatch(1);
+
+ public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+ Assert.assertTrue(mTextureView.getLayerType() == View.LAYER_TYPE_HARDWARE);
+ Assert.assertTrue(mTextureView.isAvailable());
+ Assert.assertNotNull(mTextureView.getSurfaceTexture());
+ Assert.assertTrue(mTextureView.getSurfaceTextureListener() == this);
+ Assert.assertTrue(mTextureView.isOpaque());
+ mWidth = width;
+ mHeight = height;
+ mCamera = Camera.open();
+
+ try {
+ mCamera.setPreviewTexture(surface);
+ mCamera.startPreview();
+ } catch (IOException ioe) {
+ // Something bad happened
+ Assert.fail();
+ }
+ }
+
+ public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ }
+
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+ mCamera.stopPreview();
+ mCamera.release();
+ return true;
+ }
+
+ public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+ mUpdateCounter++;
+ if (mUpdateCounter % CAPTURE_SCREEN_INTERVAL == 0) {
+ Canvas canvas = mTextureView.lockCanvas();
+ canvas.drawColor(0xffff0000);
+ mTextureView.unlockCanvasAndPost(canvas);
+ Bitmap bitmap = mTextureView.getBitmap();
+ Assert.assertEquals(mHeight, bitmap.getHeight());
+ Assert.assertEquals(mWidth, bitmap.getWidth());
+ bitmap.recycle();
+ if (mUpdateCounter >= MAX_FRAME_UPDATE) {
+ mLatch.countDown();
+ }
+ }
+ Matrix transformMatrix = mTextureView.getTransform(null);
+ mRotation += SCREEN_ROTATION_RATE;
+ transformMatrix.setRotate(mRotation, mWidth/2, mHeight/2);
+ mTextureView.setTransform(transformMatrix);
+ }
+
+ public boolean waitForCompletion(long timeoutInSecs) throws InterruptedException {
+ return mLatch.await(timeoutInSecs, TimeUnit.SECONDS);
+ }
+
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mTextureView = new TextureView(this);
+ mTextureView.setSurfaceTextureListener(this);
+ mTextureView.setOpaque(true);
+ setContentView(mTextureView);
+ }
+}
diff --git a/tests/tests/graphics2/src/android/graphics2/cts/TextureViewTest.java b/tests/tests/graphics2/src/android/graphics2/cts/TextureViewTest.java
new file mode 100644
index 0000000..932a5d5
--- /dev/null
+++ b/tests/tests/graphics2/src/android/graphics2/cts/TextureViewTest.java
@@ -0,0 +1,41 @@
+/*
+ * 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.graphics2.cts;
+
+import android.graphics2.cts.TextureViewCameraActivity;
+import android.test.ActivityInstrumentationTestCase2;
+
+
+public class TextureViewTest extends ActivityInstrumentationTestCase2<TextureViewCameraActivity> {
+ private static final long WAIT_TIMEOUT_IN_SECS = 10;
+ private TextureViewCameraActivity mActivity;
+ public TextureViewTest() {
+ super(TextureViewCameraActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+
+ public void testTextureViewActivity() throws InterruptedException {
+ assertTrue(mActivity.waitForCompletion(WAIT_TIMEOUT_IN_SECS));
+ }
+
+}
+
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
index 3b29f6a..d70938c 100755
--- a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
@@ -1863,28 +1863,30 @@
// variance is averaged out.
// Check if the frame interval is too large or too small.
- double intervalMargin = 30; // ms
+ // x100 = percent, intervalMargin should be bigger than fpsMargin considering that
+ // fps will be in the order of 10.
+ double intervalMargin = 0.9;
long lastArrivalTime = mFrames.get(mFrames.size() - 1);
double interval = arrivalTime - lastArrivalTime;
if (LOGV) Log.v(TAG, "Frame interval=" + interval);
assertTrue("Frame interval (" + interval + "ms) is too large." +
" mMaxFrameInterval=" + mMaxFrameInterval + "ms",
- interval < mMaxFrameInterval + intervalMargin);
+ interval < mMaxFrameInterval * (1.0 + intervalMargin));
assertTrue("Frame interval (" + interval + "ms) is too small." +
" mMinFrameInterval=" + mMinFrameInterval + "ms",
- interval > mMinFrameInterval - intervalMargin);
+ interval > mMinFrameInterval * (1.0 - intervalMargin));
// Check if the fps is within range.
- double fpsMargin = 0.05;
+ double fpsMargin = 0.5; // x100 = percent
double avgInterval = (double)(arrivalTime - mFrames.get(0))
/ mFrames.size();
double fps = 1000.0 / avgInterval;
assertTrue("Actual fps (" + fps + ") should be larger than " +
"min fps (" + mMinFps + ")",
- fps >= mMinFps * (1 - fpsMargin));
+ fps >= mMinFps * (1.0 - fpsMargin));
assertTrue("Actual fps (" + fps + ") should be smaller than " +
"max fps (" + mMaxFps + ")",
- fps <= mMaxFps * (1 + fpsMargin));
+ fps <= mMaxFps * (1.0 + fpsMargin));
}
// Add the arrival time of this frame to the list.
mFrames.add(arrivalTime);
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_inputmethod_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_darkactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view_feb.png
new file mode 100644
index 0000000..2c0619b
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_light_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view_feb.png b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
new file mode 100644
index 0000000..1421fbc
--- /dev/null
+++ b/tests/tests/holo/res/drawable-hdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_dialog_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_dialog_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_inputmethod_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_inputmethod_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_inputmethod_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_darkactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_darkactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_darkactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_light_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_light_panel_calendar_view_feb.png
new file mode 100644
index 0000000..f27f7d2
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_light_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_fullscreen_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_notitlebar_calendar_view_feb.png b/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_notitlebar_calendar_view_feb.png
new file mode 100644
index 0000000..fc65b4a
--- /dev/null
+++ b/tests/tests/holo/res/drawable-ldpi/holo_wallpaper_notitlebar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_inputmethod_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_darkactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view_feb.png
new file mode 100644
index 0000000..a457bc3
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_light_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view_feb.png b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
new file mode 100644
index 0000000..aed3bc0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-mdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_inputmethod_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_inputmethod_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_inputmethod_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_darkactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_darkactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_darkactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_light_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_light_panel_calendar_view_feb.png
new file mode 100644
index 0000000..afefcfb
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_light_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_panel_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_notitlebar_calendar_view_feb.png b/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
new file mode 100644
index 0000000..f6682f0
--- /dev/null
+++ b/tests/tests/holo/res/drawable-tvdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_inputmethod_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_inputmethod_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_inputmethod_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_darkactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_darkactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_darkactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialog_noactionbar_minwidth_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_dialogwhenlarge_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_light_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_light_panel_calendar_view_feb.png
new file mode 100644
index 0000000..3e7e915
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_light_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_fullscreen_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_noactionbar_fullscreen_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_panel_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_panel_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_panel_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_notitlebar_calendar_view_feb.png b/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
new file mode 100644
index 0000000..37f6f4f
--- /dev/null
+++ b/tests/tests/holo/res/drawable-xhdpi/holo_wallpaper_notitlebar_calendar_view_feb.png
Binary files differ
diff --git a/tests/tests/holo/res/values/strings.xml b/tests/tests/holo/res/values/strings.xml
index 61550cb..5eb7d82 100644
--- a/tests/tests/holo/res/values/strings.xml
+++ b/tests/tests/holo/res/values/strings.xml
@@ -40,7 +40,8 @@
<string name="button">Button</string>
<string name="button_pressed">Button Pressed</string>
- <string name="calendarview">CalendarView</string>
+ <string name="calendarview_jan">CalendarView (January)</string>
+ <string name="calendarview_feb">CalendarView (February)</string>
<string name="checkbox">CheckBox</string>
<string name="checkbox_checked">CheckBox Checked</string>
<string name="chronometer">Chronometer</string>
diff --git a/tests/tests/holo/src/android/holo/cts/AllThemesIterator.java b/tests/tests/holo/src/android/holo/cts/AllThemesIterator.java
index d403d8d..4ddc187 100644
--- a/tests/tests/holo/src/android/holo/cts/AllThemesIterator.java
+++ b/tests/tests/holo/src/android/holo/cts/AllThemesIterator.java
@@ -26,14 +26,17 @@
class AllThemesIterator implements Iterator<Intent> {
private final ThemeAdapter mThemeAdapter = new ThemeAdapter(null);
- private final LayoutAdapter mLayoutAdapter = new LayoutAdapter(null);
+ private final LayoutAdapter mLayoutAdapter;
private final int mTask;
+ private final int mAdapterMode;
private int mThemeIndex;
private int mLayoutIndex;
- AllThemesIterator(int task) {
+ AllThemesIterator(int task, int adapterMode) {
mTask = task;
+ mAdapterMode = adapterMode;
+ mLayoutAdapter = new LayoutAdapter(null, adapterMode);
}
@Override
@@ -46,6 +49,7 @@
Intent intent = new Intent();
intent.putExtra(LayoutTestActivity.EXTRA_THEME_INDEX, mThemeIndex);
intent.putExtra(LayoutTestActivity.EXTRA_LAYOUT_INDEX, mLayoutIndex);
+ intent.putExtra(LayoutTestActivity.EXTRA_LAYOUT_ADAPTER_MODE, mAdapterMode);
intent.putExtra(LayoutTestActivity.EXTRA_TASK, mTask);
mLayoutIndex++;
diff --git a/tests/tests/holo/src/android/holo/cts/HoloTest.java b/tests/tests/holo/src/android/holo/cts/HoloTest.java
index e47cf01..f3e7e63 100644
--- a/tests/tests/holo/src/android/holo/cts/HoloTest.java
+++ b/tests/tests/holo/src/android/holo/cts/HoloTest.java
@@ -131,6 +131,7 @@
Intent intent = new Intent();
intent.putExtra(ThemeTestActivity.EXTRA_TASK, ThemeTestActivity.TASK_COMPARE_BITMAPS);
intent.putExtra(ThemeTestActivity.EXTRA_THEME_INDEX, themeIndex);
+ intent.putExtra(ThemeTestActivity.EXTRA_LAYOUT_ADAPTER_MODE, LayoutAdapter.MODE_TESTING);
setActivityIntent(intent);
// Enable touch mode or else widgets will be highlighted causing bitmap
diff --git a/tests/tests/holo/src/android/holo/cts/HoloTestUtilitiesActivity.java b/tests/tests/holo/src/android/holo/cts/HoloTestUtilitiesActivity.java
index 3fa4184e4..3092490 100644
--- a/tests/tests/holo/src/android/holo/cts/HoloTestUtilitiesActivity.java
+++ b/tests/tests/holo/src/android/holo/cts/HoloTestUtilitiesActivity.java
@@ -137,6 +137,7 @@
private void generateAllBitmaps() {
Intent intent = new Intent(this, ThemeTestActivity.class);
intent.putExtra(ThemeTestActivity.EXTRA_TASK, ThemeTestActivity.TASK_GENERATE_BITMAPS);
+ intent.putExtra(ThemeTestActivity.EXTRA_LAYOUT_ADAPTER_MODE, LayoutAdapter.MODE_TESTING);
startActivity(intent);
}
diff --git a/tests/tests/holo/src/android/holo/cts/LayoutAdapter.java b/tests/tests/holo/src/android/holo/cts/LayoutAdapter.java
index 539f4f8..d7732a9 100644
--- a/tests/tests/holo/src/android/holo/cts/LayoutAdapter.java
+++ b/tests/tests/holo/src/android/holo/cts/LayoutAdapter.java
@@ -22,7 +22,6 @@
import android.holo.cts.modifiers.SearchViewModifier;
import android.holo.cts.modifiers.TabHostModifier;
import android.holo.cts.modifiers.TimePickerModifier;
-import android.holo.cts.modifiers.ViewPressedModifier;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -30,6 +29,7 @@
import android.widget.TextView;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.List;
/**
@@ -37,6 +37,12 @@
*/
class LayoutAdapter extends BaseAdapter {
+ /** Mode where we are just viewing all the layouts. */
+ static final int MODE_VIEWING = 0;
+
+ /** Mode where we are testing and may not include some layouts based on the device state. */
+ static final int MODE_TESTING = 1;
+
/** No timeout for widgets in layouts that aren't changed after inflation. */
private static final int NO_TIMEOUT_MS = 0;
@@ -92,7 +98,7 @@
private final LayoutInflater mInflater;
- LayoutAdapter(LayoutInflater inflater) {
+ LayoutAdapter(LayoutInflater inflater, int adapterMode) {
mInflater = inflater;
// Widgets
@@ -103,8 +109,7 @@
// addLayout(R.string.button_pressed, "button_pressed",
// R.layout.button, new ViewPressedModifier(), LONG_TIMEOUT_MS);
- addLayout(R.string.calendarview, "calendar_view",
- R.layout.calendarview, new CalendarViewModifier(), SHORT_TIMEOUT_MS);
+ addCalendarLayouts(adapterMode);
addLayout(R.string.checkbox, "checkbox",
R.layout.checkbox, null, NO_TIMEOUT_MS);
@@ -214,8 +219,11 @@
addLayout(R.string.togglebutton_checked, "toggle_button_checked",
R.layout.togglebutton_checked, null, NO_TIMEOUT_MS);
- addLayout(R.string.zoomcontrols, "zoomcontrols",
- R.layout.zoomcontrols, null, NO_TIMEOUT_MS);
+
+ // TODO: Zoom control hasn't been styled for Holo so don't test them.
+
+// addLayout(R.string.zoomcontrols, "zoomcontrols",
+// R.layout.zoomcontrols, null, NO_TIMEOUT_MS);
// Dialogs
@@ -289,7 +297,31 @@
private void addLayout(int displayName, String fileName, int layout, LayoutModifier modifier,
long timeoutMs) {
- mLayoutInfos.add(new LayoutInfo(displayName, fileName, layout, modifier, timeoutMs));
+ addLayout(new LayoutInfo(displayName, fileName, layout, modifier, timeoutMs));
+ }
+
+ private void addLayout(LayoutInfo info) {
+ mLayoutInfos.add(info);
+ }
+
+ private void addCalendarLayouts(int adapterMode) {
+ if (adapterMode == MODE_VIEWING || !CalendarViewModifier.isMonth(Calendar.JANUARY)) {
+ addLayout(getCalendarLayoutInfo());
+ }
+
+ if (adapterMode == MODE_VIEWING || !CalendarViewModifier.isMonth(Calendar.FEBRUARY)) {
+ addLayout(getFebruaryCalendarLayoutInfo());
+ }
+ }
+
+ private LayoutInfo getCalendarLayoutInfo() {
+ return new LayoutInfo(R.string.calendarview_jan, "calendar_view",
+ R.layout.calendarview, new CalendarViewModifier(true), SHORT_TIMEOUT_MS);
+ }
+
+ private LayoutInfo getFebruaryCalendarLayoutInfo() {
+ return new LayoutInfo(R.string.calendarview_feb, "calendar_view_feb",
+ R.layout.calendarview, new CalendarViewModifier(false), SHORT_TIMEOUT_MS);
}
@Override
diff --git a/tests/tests/holo/src/android/holo/cts/LayoutPickerActivity.java b/tests/tests/holo/src/android/holo/cts/LayoutPickerActivity.java
index 00c3af0..f808d59 100644
--- a/tests/tests/holo/src/android/holo/cts/LayoutPickerActivity.java
+++ b/tests/tests/holo/src/android/holo/cts/LayoutPickerActivity.java
@@ -38,7 +38,7 @@
super.onCreate(savedInstanceState);
mThemeIndex = getIntent().getIntExtra(EXTRA_THEME_INDEX, -1);
mTestTask = getIntent().getIntExtra(EXTRA_TASK, -1);
- setListAdapter(new LayoutAdapter(getLayoutInflater()));
+ setListAdapter(new LayoutAdapter(getLayoutInflater(), LayoutAdapter.MODE_VIEWING));
}
@Override
@@ -47,6 +47,7 @@
intent.putExtra(ThemeTestActivity.EXTRA_THEME_INDEX, mThemeIndex);
intent.putExtra(ThemeTestActivity.EXTRA_LAYOUT_INDEX, position);
intent.putExtra(ThemeTestActivity.EXTRA_TASK, mTestTask);
+ intent.putExtra(ThemeTestActivity.EXTRA_LAYOUT_ADAPTER_MODE, LayoutAdapter.MODE_VIEWING);
startActivity(intent);
}
}
diff --git a/tests/tests/holo/src/android/holo/cts/LayoutTestActivity.java b/tests/tests/holo/src/android/holo/cts/LayoutTestActivity.java
index 0377f9d..052ddea 100644
--- a/tests/tests/holo/src/android/holo/cts/LayoutTestActivity.java
+++ b/tests/tests/holo/src/android/holo/cts/LayoutTestActivity.java
@@ -47,6 +47,7 @@
static final String EXTRA_THEME_INDEX = "themeIndex";
static final String EXTRA_LAYOUT_INDEX = "layoutIndex";
static final String EXTRA_TASK = "task";
+ static final String EXTRA_LAYOUT_ADAPTER_MODE = "layoutAdapterMode";
// Output extras
static final String EXTRA_BITMAP_NAME = "bitmapName";
@@ -64,10 +65,11 @@
int themeIndex = getIntent().getIntExtra(EXTRA_THEME_INDEX, -1);
int layoutIndex = getIntent().getIntExtra(EXTRA_LAYOUT_INDEX, -1);
+ int layoutMode = getIntent().getIntExtra(EXTRA_LAYOUT_ADAPTER_MODE, -1);
int task = getIntent().getIntExtra(EXTRA_TASK, -1);
ThemeAdapter themeAdapter = new ThemeAdapter(getLayoutInflater());
- LayoutAdapter layoutAdapter = new LayoutAdapter(getLayoutInflater());
+ LayoutAdapter layoutAdapter = new LayoutAdapter(getLayoutInflater(), layoutMode);
ThemeInfo themeInfo = themeAdapter.getItem(themeIndex);
LayoutInfo layoutInfo = layoutAdapter.getItem(layoutIndex);
diff --git a/tests/tests/holo/src/android/holo/cts/SingleLayoutIterator.java b/tests/tests/holo/src/android/holo/cts/SingleLayoutIterator.java
index f50a872..afc0fbe 100644
--- a/tests/tests/holo/src/android/holo/cts/SingleLayoutIterator.java
+++ b/tests/tests/holo/src/android/holo/cts/SingleLayoutIterator.java
@@ -29,10 +29,12 @@
private final int mTask;
private final int mLayoutIndex;
+ private final int mLayoutAdapterMode;
private int mThemeIndex;
- SingleLayoutIterator(int layoutIndex, int task) {
+ SingleLayoutIterator(int layoutIndex, int task, int layoutAdapterMode) {
mTask = task;
+ mLayoutAdapterMode = layoutAdapterMode;
mLayoutIndex = layoutIndex;
}
@@ -47,6 +49,7 @@
intent.putExtra(LayoutTestActivity.EXTRA_THEME_INDEX, mThemeIndex);
intent.putExtra(LayoutTestActivity.EXTRA_LAYOUT_INDEX, mLayoutIndex);
intent.putExtra(LayoutTestActivity.EXTRA_TASK, mTask);
+ intent.putExtra(LayoutTestActivity.EXTRA_LAYOUT_ADAPTER_MODE, mLayoutAdapterMode);
mThemeIndex++;
diff --git a/tests/tests/holo/src/android/holo/cts/SingleThemeIterator.java b/tests/tests/holo/src/android/holo/cts/SingleThemeIterator.java
index cdfbb8e..3c489ab 100644
--- a/tests/tests/holo/src/android/holo/cts/SingleThemeIterator.java
+++ b/tests/tests/holo/src/android/holo/cts/SingleThemeIterator.java
@@ -25,14 +25,17 @@
*/
class SingleThemeIterator implements Iterator<Intent> {
- private final LayoutAdapter mLayoutAdapter = new LayoutAdapter(null);
+ private final LayoutAdapter mLayoutAdapter;
private final int mTask;
private final int mThemeIndex;
+ private final int mLayoutAdapterMode;
private int mLayoutIndex;
- SingleThemeIterator(int themeIndex, int task) {
+ SingleThemeIterator(int themeIndex, int task, int layoutAdapterMode) {
mTask = task;
+ mLayoutAdapterMode = layoutAdapterMode;
+ mLayoutAdapter = new LayoutAdapter(null, layoutAdapterMode);
mThemeIndex = themeIndex;
}
@@ -47,6 +50,7 @@
intent.putExtra(LayoutTestActivity.EXTRA_THEME_INDEX, mThemeIndex);
intent.putExtra(LayoutTestActivity.EXTRA_LAYOUT_INDEX, mLayoutIndex);
intent.putExtra(LayoutTestActivity.EXTRA_TASK, mTask);
+ intent.putExtra(LayoutTestActivity.EXTRA_LAYOUT_ADAPTER_MODE, mLayoutAdapterMode);
mLayoutIndex++;
diff --git a/tests/tests/holo/src/android/holo/cts/SingleThemeLayoutIterator.java b/tests/tests/holo/src/android/holo/cts/SingleThemeLayoutIterator.java
index e49c9f8..5fe5086 100644
--- a/tests/tests/holo/src/android/holo/cts/SingleThemeLayoutIterator.java
+++ b/tests/tests/holo/src/android/holo/cts/SingleThemeLayoutIterator.java
@@ -25,13 +25,15 @@
private final int mThemeIndex;
private final int mLayoutIndex;
private final int mTask;
+ private final int mLayoutAdapterMode;
private boolean hasNext = true;
- SingleThemeLayoutIterator(int themeIndex, int layoutIndex, int task) {
+ SingleThemeLayoutIterator(int themeIndex, int layoutIndex, int task, int layoutAdapterMode) {
mThemeIndex = themeIndex;
mLayoutIndex = layoutIndex;
mTask = task;
+ mLayoutAdapterMode = layoutAdapterMode;
}
@Override
@@ -45,6 +47,7 @@
intent.putExtra(LayoutTestActivity.EXTRA_THEME_INDEX, mThemeIndex);
intent.putExtra(LayoutTestActivity.EXTRA_LAYOUT_INDEX, mLayoutIndex);
intent.putExtra(LayoutTestActivity.EXTRA_TASK, mTask);
+ intent.putExtra(LayoutTestActivity.EXTRA_LAYOUT_ADAPTER_MODE, mLayoutAdapterMode);
hasNext = false;
diff --git a/tests/tests/holo/src/android/holo/cts/ThemeTestActivity.java b/tests/tests/holo/src/android/holo/cts/ThemeTestActivity.java
index 096c8ed..08659df 100644
--- a/tests/tests/holo/src/android/holo/cts/ThemeTestActivity.java
+++ b/tests/tests/holo/src/android/holo/cts/ThemeTestActivity.java
@@ -40,6 +40,7 @@
static final String EXTRA_TASK = "task";
static final String EXTRA_THEME_INDEX = "themeIndex";
static final String EXTRA_LAYOUT_INDEX = "layoutIndex";
+ static final String EXTRA_LAYOUT_ADAPTER_MODE = "layoutAdapterMode";
static final int TASK_VIEW_LAYOUTS = 1;
static final int TASK_GENERATE_BITMAPS = 2;
@@ -82,17 +83,18 @@
int themeIndex = getIntent().getIntExtra(EXTRA_THEME_INDEX, -1);
int layoutIndex = getIntent().getIntExtra(EXTRA_LAYOUT_INDEX, -1);
+ int adapterMode = getIntent().getIntExtra(EXTRA_LAYOUT_ADAPTER_MODE, -1);
Log.i(TAG, "Theme index: " + themeIndex + " Layout index: " + layoutIndex);
if (themeIndex < 0 && layoutIndex < 0) {
- mIterator = new AllThemesIterator(task);
+ mIterator = new AllThemesIterator(task, adapterMode);
} else if (themeIndex >= 0 && layoutIndex >= 0) {
- mIterator = new SingleThemeLayoutIterator(themeIndex, layoutIndex, task);
+ mIterator = new SingleThemeLayoutIterator(themeIndex, layoutIndex, task, adapterMode);
} else if (layoutIndex >= 0) {
- mIterator = new SingleLayoutIterator(layoutIndex, task);
+ mIterator = new SingleLayoutIterator(layoutIndex, task, adapterMode);
} else if (themeIndex >= 0) {
- mIterator = new SingleThemeIterator(themeIndex, task);
+ mIterator = new SingleThemeIterator(themeIndex, task, adapterMode);
} else {
throw new IllegalStateException();
}
diff --git a/tests/tests/holo/src/android/holo/cts/modifiers/CalendarViewModifier.java b/tests/tests/holo/src/android/holo/cts/modifiers/CalendarViewModifier.java
index 36194c0..e27b6c1 100644
--- a/tests/tests/holo/src/android/holo/cts/modifiers/CalendarViewModifier.java
+++ b/tests/tests/holo/src/android/holo/cts/modifiers/CalendarViewModifier.java
@@ -20,6 +20,8 @@
import android.view.View;
import android.widget.CalendarView;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
import java.util.TimeZone;
/**
@@ -30,16 +32,31 @@
* Long representation of a date that is 30 years in milliseconds from
* Unix epoch (January 1, 1970 00:00:00).
*/
- private static final long DATE = 946707779241L;
+ private static final long JANUARY_DATE = 946707779241L;
+
+ private static final long FEBRUARY_DATE = 951033600000L;
+
+ private static final TimeZone TZ = TimeZone.getTimeZone("GMT+00:00");
+
+ private final boolean mJanuary;
+
+ public CalendarViewModifier(boolean january) {
+ mJanuary = january;
+ }
@Override
public void prepare() {
- TimeZone.setDefault(TimeZone.getTimeZone("GMT+00:00"));
+ TimeZone.setDefault(TZ);
}
@Override
public View modifyView(View view) {
- ((CalendarView) view).setDate(DATE);
+ ((CalendarView) view).setDate(mJanuary ? JANUARY_DATE : FEBRUARY_DATE);
return view;
}
+
+ public static boolean isMonth(int month) {
+ Calendar cal = new GregorianCalendar(TZ);
+ return cal.get(Calendar.MONTH) == month;
+ }
}
diff --git a/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java b/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
index 0587f88..e34856c 100644
--- a/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
+++ b/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
@@ -21,6 +21,7 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
+import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
@@ -237,6 +238,16 @@
)
})
public void testGet() {
+ /*
+ * Device may not have rear camera for checkGet(-1).
+ * Checking PackageManager.FEATURE_CAMERA is included or not to decide the flow.
+ * Continue if the feature is included.
+ * Otherwise, exit test.
+ */
+ PackageManager pm = mContext.getPackageManager();
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
+ return;
+ }
checkGet(-1);
}
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 9947592..9c03a0b 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -27,6 +27,7 @@
import android.os.PowerManager;
import java.io.File;
+import java.util.concurrent.CountDownLatch;
/**
* Tests for the MediaPlayer API and local video/audio playback.
@@ -36,6 +37,7 @@
* Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
*/
public class MediaPlayerTest extends MediaPlayerTestBase {
+
public void testPlayNullSource() throws Exception {
try {
mMediaPlayer.setDataSource((String) null);
@@ -109,41 +111,51 @@
* from the time setDisplay() was called
*/
public void testVideoSurfaceResetting() throws Exception {
- final int tolerance = 150;
+ final int tolerance = 66 * 3 / 2; /* Test video is 15fps... 66 ms per frame */
final int seekPos = 1500;
- playVideoTest(R.raw.testvideo, 352, 288);
+ final CountDownLatch seekDone = new CountDownLatch(1);
- mMediaPlayer.start();
+ mMediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
+ @Override
+ public void onSeekComplete(MediaPlayer mp) {
+ seekDone.countDown();
+ }
+ });
+
+ loadResource(R.raw.testvideo);
+ playLoadedVideo(352, 288, -1);
+
Thread.sleep(SLEEP_TIME);
int posBefore = mMediaPlayer.getCurrentPosition();
mMediaPlayer.setDisplay(getActivity().getSurfaceHolder2());
int posAfter = mMediaPlayer.getCurrentPosition();
- assertEquals(posAfter, posBefore);
+ assertEquals(posAfter, posBefore, tolerance);
assertTrue(mMediaPlayer.isPlaying());
Thread.sleep(SLEEP_TIME);
mMediaPlayer.seekTo(seekPos);
+ seekDone.await();
Thread.sleep(SLEEP_TIME / 2);
posBefore = mMediaPlayer.getCurrentPosition();
mMediaPlayer.setDisplay(null);
posAfter = mMediaPlayer.getCurrentPosition();
- assertEquals(posAfter, posBefore);
+ assertEquals(posAfter, posBefore, tolerance);
assertEquals(seekPos + SLEEP_TIME / 2, posBefore, tolerance);
assertTrue(mMediaPlayer.isPlaying());
Thread.sleep(SLEEP_TIME);
posBefore = mMediaPlayer.getCurrentPosition();
- mMediaPlayer.setDisplay(getActivity().generateSurfaceHolder());
+ mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
posAfter = mMediaPlayer.getCurrentPosition();
- assertEquals(posAfter, posBefore);
+ assertEquals(posAfter, posBefore, tolerance);
assertTrue(mMediaPlayer.isPlaying());
Thread.sleep(SLEEP_TIME);
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
index 6b6f3d7..a594122 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
@@ -32,7 +32,7 @@
protected static final int SLEEP_TIME = 1000;
protected static final int LONG_SLEEP_TIME = 6000;
- protected static final int STREAM_RETRIES = 5;
+ protected static final int STREAM_RETRIES = 20;
public static class Monitor {
private boolean signalled;
@@ -141,9 +141,13 @@
*
* @param width width of the video to verify, or null to skip verification
* @param height height of the video to verify, or null to skip verification
- * @param playTime length of time to play video, or 0 to play entire video
+ * @param playTime length of time to play video, or 0 to play entire video.
+ * with a non-negative value, this method stops the playback after the length of
+ * time or the duration the video is elapsed. With a value of -1,
+ * this method simply starts the video and returns immediately without
+ * stoping the video playback.
*/
- private void playLoadedVideo(final Integer width, final Integer height, int playTime)
+ protected void playLoadedVideo(final Integer width, final Integer height, int playTime)
throws Exception {
final float leftVolume = 0.5f;
final float rightVolume = 0.5f;
@@ -181,13 +185,16 @@
mMediaPlayer.setVolume(leftVolume, rightVolume);
// waiting to complete
- if (playTime == 0) {
+ if (playTime == -1) {
+ return;
+ } else if (playTime == 0) {
while (mMediaPlayer.isPlaying()) {
Thread.sleep(SLEEP_TIME);
}
} else {
Thread.sleep(playTime);
}
+ mMediaPlayer.stop();
}
private static class PrepareFailedException extends Exception {}
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
index c753ff1..f6ceacf 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
@@ -24,6 +24,7 @@
import android.os.Environment;
import android.test.AndroidTestCase;
+import java.io.File;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -52,7 +53,7 @@
static class ScannerNotificationReceiver extends BroadcastReceiver {
- private static final int TIMEOUT_MS = 30 * 1000;
+ private static final int TIMEOUT_MS = 4 * 60 * 1000;
private final String mAction;
private final CountDownLatch mLatch = new CountDownLatch(1);
@@ -69,8 +70,26 @@
}
public void waitForBroadcast() throws InterruptedException {
- assertTrue("Failed to receive broadcast for " + mAction,
- mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ if (!mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ int numFiles = countFiles(Environment.getExternalStorageDirectory());
+ fail("Failed to receive broadcast in " + TIMEOUT_MS + "ms for " + mAction
+ + " while trying to scan " + numFiles + " files!");
+ }
+ }
+
+ private int countFiles(File dir) {
+ int count = 0;
+ File[] files = dir.listFiles();
+ if (files != null) {
+ for (File file : files) {
+ if (file.isDirectory()) {
+ count += countFiles(file);
+ } else {
+ count++;
+ }
+ }
+ }
+ return count;
}
}
}
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerStreamingTest.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
similarity index 98%
rename from tests/tests/media/src/android/media/cts/MediaPlayerStreamingTest.java
rename to tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
index 652c5bd..b8ccf22 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerStreamingTest.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
@@ -22,7 +22,7 @@
/**
* Tests of MediaPlayer streaming capabilities.
*/
-public class MediaPlayerStreamingTest extends MediaPlayerTestBase {
+public class StreamingMediaPlayerTest extends MediaPlayerTestBase {
private CtsTestServer mServer;
// Streaming RTSP video from YouTube
diff --git a/tests/tests/mediastress/Android.mk b/tests/tests/mediastress/Android.mk
new file mode 100644
index 0000000..4fa7fdb
--- /dev/null
+++ b/tests/tests/mediastress/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsMediaStressTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tests/tests/mediastress/AndroidManifest.xml b/tests/tests/mediastress/AndroidManifest.xml
new file mode 100644
index 0000000..5a4569c
--- /dev/null
+++ b/tests/tests/mediastress/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.mediastress">
+
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity android:label="@string/app_name"
+ android:name="android.mediastress.cts.MediaFrameworkTest"
+ android:screenOrientation="landscape">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.cts.mediastress"
+ android:label="Media stress tests InstrumentationRunner" />
+
+</manifest>
diff --git a/tests/tests/mediastress/res/layout/surface_view.xml b/tests/tests/mediastress/res/layout/surface_view.xml
new file mode 100644
index 0000000..97f1dd4
--- /dev/null
+++ b/tests/tests/mediastress/res/layout/surface_view.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <SurfaceView
+ android:id="@+id/surface_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_centerInParent="true" />
+
+ <ImageView android:id="@+id/overlay_layer"
+ android:layout_width="0dip"
+ android:layout_height="392dip"/>
+
+ <VideoView
+ android:id="@+id/video_view"
+ android:layout_width="320px"
+ android:layout_height="240px" />
+
+ </FrameLayout>
+
+</LinearLayout>
diff --git a/tests/tests/mediastress/res/values/strings.xml b/tests/tests/mediastress/res/values/strings.xml
new file mode 100644
index 0000000..32c58e0
--- /dev/null
+++ b/tests/tests/mediastress/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string name="app_name">MediaStressTest</string>
+ <string name="open_url">Open</string>
+</resources>
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java b/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java
new file mode 100644
index 0000000..c349ac0
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java
@@ -0,0 +1,817 @@
+/*
+ * 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.mediastress.cts;
+
+import android.content.res.AssetFileDescriptor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.MediaMetadataRetriever;
+import android.media.MediaPlayer;
+import android.media.MediaRecorder;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Junit / Instrumentation test case for the media player api
+ */
+public class CodecTest {
+ private static String TAG = "CodecTest";
+ private static MediaPlayer mMediaPlayer;
+ private MediaPlayer.OnPreparedListener mOnPreparedListener;
+
+ private static int WAIT_FOR_COMMAND_TO_COMPLETE = 60000; //1 min max.
+ private static boolean mInitialized = false;
+ private static boolean mPrepareReset = false;
+ private static Looper mLooper = null;
+ private static final Object mLock = new Object();
+ private static final Object mPrepareDone = new Object();
+ private static final Object mVideoSizeChanged = new Object();
+ private static final Object mOnCompletion = new Object();
+ private static boolean mOnPrepareSuccess = false;
+ private static final long PAUSE_WAIT_TIME = 3000;
+ private static final long WAIT_TIME = 2000;
+ private static final int SEEK_TIME = 10000;
+
+ public static boolean mOnCompleteSuccess = false;
+ public static boolean mPlaybackError = false;
+ public static int mMediaInfoUnknownCount = 0;
+ public static int mMediaInfoVideoTrackLaggingCount = 0;
+ public static int mMediaInfoBadInterleavingCount = 0;
+ public static int mMediaInfoNotSeekableCount = 0;
+ public static int mMediaInfoMetdataUpdateCount = 0;
+
+ public static String printCpuInfo() {
+ String cm = "dumpsys cpuinfo";
+ String cpuinfo = null;
+ int ch;
+ try {
+ Process p = Runtime.getRuntime().exec(cm);
+ InputStream in = p.getInputStream();
+ StringBuffer sb = new StringBuffer(512);
+ while ( ( ch = in.read() ) != -1 ) {
+ sb.append((char) ch);
+ }
+ cpuinfo = sb.toString();
+ } catch (IOException e) {
+ Log.v(TAG, e.toString());
+ }
+ return cpuinfo;
+ }
+
+
+ public static int getDuration(String filePath) {
+ Log.v(TAG, "getDuration - " + filePath);
+ MediaPlayer mp = new MediaPlayer();
+ try {
+ mp.setDataSource(filePath);
+ mp.prepare();
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ int duration = mp.getDuration();
+ Log.v(TAG, "Duration " + duration);
+ mp.release();
+ Log.v(TAG, "release");
+ return duration;
+ }
+
+ public static boolean getCurrentPosition(String filePath) {
+ Log.v(TAG, "GetCurrentPosition - " + filePath);
+ int currentPosition = 0;
+ long t1=0;
+ long t2 =0;
+ MediaPlayer mp = new MediaPlayer();
+ try {
+ mp.setDataSource(filePath);
+ Log.v(TAG, "start playback");
+ mp.prepare();
+ mp.start();
+ t1=SystemClock.uptimeMillis();
+ Thread.sleep(10000);
+ mp.pause();
+ Thread.sleep(PAUSE_WAIT_TIME);
+ t2=SystemClock.uptimeMillis();
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ currentPosition = mp.getCurrentPosition();
+ mp.stop();
+ mp.release();
+ Log.v(TAG, "mp currentPositon = " + currentPosition + " play duration = " + (t2-t1));
+
+ if ((currentPosition < ((t2-t1) *1.2)) && (currentPosition > 0))
+ return true;
+ else
+ return false;
+ }
+
+ public static boolean seekTo(String filePath) {
+ Log.v(TAG, "seekTo " + filePath);
+ int currentPosition = 0;
+ MediaPlayer mp = new MediaPlayer();
+ try {
+ mp.setDataSource(filePath);
+ mp.prepare();
+ mp.start();
+ mp.seekTo(SEEK_TIME);
+ Thread.sleep(WAIT_TIME);
+ currentPosition = mp.getCurrentPosition();
+ } catch (Exception e) {
+ Log.v(TAG, e.getMessage());
+ }
+ mp.stop();
+ mp.release();
+ Log.v(TAG, "CurrentPosition = " + currentPosition);
+ //The currentposition should be at least greater than the 80% of seek time
+ if ((currentPosition > SEEK_TIME *0.8))
+ return true;
+ else
+ return false;
+ }
+
+ public static boolean setLooping(String filePath) {
+ int currentPosition = 0;
+ int duration = 0;
+ long t1 =0;
+ long t2 =0;
+ Log.v (TAG, "SetLooping - " + filePath);
+ MediaPlayer mp = new MediaPlayer();
+ try {
+ mp.setDataSource(filePath);
+ mp.prepare();
+ duration = mp.getDuration();
+ Log.v(TAG, "setLooping duration " + duration);
+ mp.setLooping(true);
+ mp.start();
+ Thread.sleep(5000);
+ mp.seekTo(duration - 5000);
+ t1=SystemClock.uptimeMillis();
+ Thread.sleep(20000);
+ t2=SystemClock.uptimeMillis();
+ Log.v(TAG, "pause");
+ //Bug# 1106852 - IllegalStateException will be thrown if pause is called
+ //in here
+ //mp.pause();
+ currentPosition = mp.getCurrentPosition();
+ Log.v(TAG, "looping position " + currentPosition + "duration = " + (t2-t1));
+ } catch (Exception e) {
+ Log.v(TAG, "Exception : " + e.toString());
+ }
+ mp.stop();
+ mp.release();
+ //The current position should be within 20% of the sleep time
+ //and should be greater than zero.
+ if ((currentPosition < ((t2-t1-5000)*1.2)) && currentPosition > 0)
+ return true;
+ else
+ return false;
+ }
+
+ public static boolean pause(String filePath) throws Exception {
+ Log.v(TAG, "pause - " + filePath);
+ boolean misPlaying = true;
+ boolean pauseResult = false;
+ long t1=0;
+ long t2=0;
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(filePath);
+ mp.prepare();
+ int duration = mp.getDuration();
+ mp.start();
+ t1=SystemClock.uptimeMillis();
+ Thread.sleep(5000);
+ mp.pause();
+ Thread.sleep(PAUSE_WAIT_TIME);
+ t2=SystemClock.uptimeMillis();
+ misPlaying = mp.isPlaying();
+ int curPosition = mp.getCurrentPosition();
+ Log.v(TAG, filePath + " pause currentPositon " + curPosition);
+ Log.v(TAG, "isPlaying "+ misPlaying + " wait time " + (t2 - t1) );
+ String cpuinfo = printCpuInfo();
+ Log.v(TAG, cpuinfo);
+ if ((curPosition>0) && (curPosition < ((t2-t1) * 1.3)) && (misPlaying == false))
+ pauseResult = true;
+ mp.stop();
+ mp.release();
+ return pauseResult;
+ }
+
+ public static void prepareStopRelease(String filePath) throws Exception {
+ Log.v(TAG, "prepareStopRelease" + filePath);
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(filePath);
+ mp.prepare();
+ mp.stop();
+ mp.release();
+ }
+
+ public static void preparePauseRelease(String filePath) throws Exception {
+ Log.v(TAG, "preparePauseRelease" + filePath);
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(filePath);
+ mp.prepare();
+ mp.pause();
+ mp.release();
+ }
+
+ static MediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener =
+ new MediaPlayer.OnVideoSizeChangedListener() {
+ public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
+ synchronized (mVideoSizeChanged) {
+ Log.v(TAG, "sizechanged notification received ...");
+ mVideoSizeChanged.notify();
+ }
+ }
+ };
+
+ //Register the videoSizeChanged listener
+ public static int videoHeight(String filePath) throws Exception {
+ Log.v(TAG, "videoHeight - " + filePath);
+ int videoHeight = 0;
+ synchronized (mLock) {
+ initializeMessageLooper();
+ try {
+ mLock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch(Exception e) {
+ Log.v(TAG, "looper was interrupted.");
+ return 0;
+ }
+ }
+ try {
+ mMediaPlayer.setDataSource(filePath);
+ mMediaPlayer.setDisplay(MediaFrameworkTest.getSurfaceView().getHolder());
+ mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
+ synchronized (mVideoSizeChanged) {
+ try {
+ mMediaPlayer.prepare();
+ mMediaPlayer.start();
+ mVideoSizeChanged.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch (Exception e) {
+ Log.v(TAG, "wait was interrupted");
+ }
+ }
+ videoHeight = mMediaPlayer.getVideoHeight();
+ terminateMessageLooper();
+ } catch (Exception e) {
+ Log.e(TAG, e.getMessage());
+ }
+
+ return videoHeight;
+ }
+
+ //Register the videoSizeChanged listener
+ public static int videoWidth(String filePath) throws Exception {
+ Log.v(TAG, "videoWidth - " + filePath);
+ int videoWidth = 0;
+
+ synchronized (mLock) {
+ initializeMessageLooper();
+ try {
+ mLock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch(Exception e) {
+ Log.v(TAG, "looper was interrupted.");
+ return 0;
+ }
+ }
+ try {
+ mMediaPlayer.setDataSource(filePath);
+ mMediaPlayer.setDisplay(MediaFrameworkTest.getSurfaceView().getHolder());
+ mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
+ synchronized (mVideoSizeChanged) {
+ try {
+ mMediaPlayer.prepare();
+ mMediaPlayer.start();
+ mVideoSizeChanged.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch (Exception e) {
+ Log.v(TAG, "wait was interrupted");
+ }
+ }
+ videoWidth = mMediaPlayer.getVideoWidth();
+ terminateMessageLooper();
+ } catch (Exception e) {
+ Log.e(TAG, e.getMessage());
+ }
+ return videoWidth;
+ }
+
+ //This also test the streaming video which may take a long
+ //time to start the playback.
+ public static boolean videoSeekTo(String filePath) throws Exception {
+ Log.v(TAG, "videoSeekTo - " + filePath);
+ int currentPosition = 0;
+ int duration = 0;
+ boolean videoResult = false;
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(filePath);
+ mp.setDisplay(MediaFrameworkTest.getSurfaceView().getHolder());
+ mp.prepare();
+ mp.start();
+
+ Thread.sleep(5000);
+ duration = mp.getDuration();
+ Log.v(TAG, "video duration " + duration);
+ mp.pause();
+ Thread.sleep(PAUSE_WAIT_TIME);
+ mp.seekTo(duration - 20000 );
+ mp.start();
+ Thread.sleep(1000);
+ mp.pause();
+ Thread.sleep(PAUSE_WAIT_TIME);
+ mp.seekTo(duration/2);
+ mp.start();
+ Thread.sleep(10000);
+ currentPosition = mp.getCurrentPosition();
+ Log.v(TAG, "video currentPosition " + currentPosition);
+ mp.release();
+ if (currentPosition > (duration /2 )*0.9)
+ return true;
+ else
+ return false;
+
+ }
+
+ public static boolean seekToEnd(String filePath) {
+ Log.v(TAG, "seekToEnd - " + filePath);
+ int duration = 0;
+ int currentPosition = 0;
+ boolean isPlaying = false;
+ MediaPlayer mp = new MediaPlayer();
+ try {
+ mp.setDataSource(filePath);
+ Log.v(TAG, "start playback");
+ mp.prepare();
+ duration = mp.getDuration();
+ mp.seekTo(duration - 3000);
+ mp.start();
+ Thread.sleep(6000);
+ } catch (Exception e) {}
+ isPlaying = mp.isPlaying();
+ currentPosition = mp.getCurrentPosition();
+ Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
+ mp.stop();
+ mp.release();
+ Log.v(TAG, "duration = " + duration);
+ if (currentPosition < 0.9 * duration || isPlaying)
+ return false;
+ else
+ return true;
+ }
+
+ public static boolean shortMediaStop(String filePath) {
+ Log.v(TAG, "shortMediaStop - " + filePath);
+ //This test is only for the short media file
+ int duration = 0;
+ int currentPosition = 0;
+ boolean isPlaying = false;
+ MediaPlayer mp = new MediaPlayer();
+ try {
+ mp.setDataSource(filePath);
+ Log.v(TAG, "start playback");
+ mp.prepare();
+ duration = mp.getDuration();
+ mp.start();
+ Thread.sleep(10000);
+ } catch (Exception e) {}
+ isPlaying = mp.isPlaying();
+ currentPosition = mp.getCurrentPosition();
+ Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
+ mp.stop();
+ mp.release();
+ Log.v(TAG, "duration = " + duration);
+ if (currentPosition > duration || isPlaying)
+ return false;
+ else
+ return true;
+ }
+
+ public static boolean playToEnd(String filePath) {
+ Log.v(TAG, "shortMediaStop - " + filePath);
+ //This test is only for the short media file
+ int duration = 200000;
+ int updateDuration = 0;
+ int currentPosition = 0;
+ boolean isPlaying = false;
+ MediaPlayer mp = new MediaPlayer();
+ try {
+ Thread.sleep(5000);
+ mp.setDataSource(filePath);
+ Log.v(TAG, "start playback");
+ mp.prepare();
+ //duration = mp.getDuration();
+ mp.start();
+ Thread.sleep(50000);
+ } catch (Exception e){}
+ isPlaying = mp.isPlaying();
+ currentPosition = mp.getCurrentPosition();
+ //updateDuration = mp.getDuration();
+ Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
+ mp.stop();
+ mp.release();
+ //Log.v(TAG, "duration = " + duration);
+ //Log.v(TAG, "Update duration = " + updateDuration);
+ if (currentPosition > duration || isPlaying)
+ return false;
+ else
+ return true;
+ }
+
+ public static boolean seektoBeforeStart(String filePath){
+ Log.v(TAG, "seektoBeforeStart - " + filePath);
+ //This test is only for the short media file
+ int duration = 0;
+ int currentPosition = 0;
+
+ MediaPlayer mp = new MediaPlayer();
+ try {
+ mp.setDataSource(filePath);
+ mp.prepare();
+ duration = mp.getDuration();
+ mp.seekTo(duration - 10000);
+ mp.start();
+ currentPosition=mp.getCurrentPosition();
+ mp.stop();
+ mp.release();
+ } catch (Exception e) {}
+ if (currentPosition < duration/2)
+ return false;
+ else
+ return true;
+ }
+
+ public static boolean mediaRecorderRecord(String filePath){
+ Log.v(TAG, "SoundRecording - " + filePath);
+ //This test is only for the short media file
+ int duration = 0;
+ try {
+ MediaRecorder mRecorder = new MediaRecorder();
+ mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ mRecorder.setOutputFile(filePath);
+ mRecorder.prepare();
+ mRecorder.start();
+ Thread.sleep(500);
+ mRecorder.stop();
+ Log.v(TAG, "sound recorded");
+ mRecorder.release();
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+
+ //Verify the recorded file
+ MediaPlayer mp = new MediaPlayer();
+ try {
+ mp.setDataSource(filePath);
+ mp.prepare();
+ duration = mp.getDuration();
+ Log.v(TAG,"Duration " + duration);
+ mp.release();
+ } catch (Exception e) {}
+ //Check the record media file length is greate than zero
+ if (duration > 0)
+ return true;
+ else
+ return false;
+
+ }
+
+ //Test for mediaMeta Data Thumbnail
+ public static boolean getThumbnail(String filePath, String goldenPath) {
+ Log.v(TAG, "getThumbnail - " + filePath);
+
+ int goldenHeight = 0;
+ int goldenWidth = 0;
+ int outputWidth = 0;
+ int outputHeight = 0;
+
+ //This test is only for the short media file
+ try {
+ BitmapFactory mBitmapFactory = new BitmapFactory();
+
+ MediaMetadataRetriever mMediaMetadataRetriever = new MediaMetadataRetriever();
+ try {
+ mMediaMetadataRetriever.setDataSource(filePath);
+ } catch(Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ Bitmap outThumbnail = mMediaMetadataRetriever.getFrameAtTime(-1);
+
+ //Verify the thumbnail
+ Bitmap goldenBitmap = mBitmapFactory.decodeFile(goldenPath);
+ outputWidth = outThumbnail.getWidth();
+ outputHeight = outThumbnail.getHeight();
+ goldenHeight = goldenBitmap.getHeight();
+ goldenWidth = goldenBitmap.getWidth();
+
+ //check the image dimension
+ if ((outputWidth != goldenWidth) || (outputHeight != goldenHeight))
+ return false;
+
+ // Check half line of pixel
+ int x = goldenHeight / 2;
+ for (int j = 1; j < goldenWidth / 2; j++) {
+ if (goldenBitmap.getPixel(x, j) != outThumbnail.getPixel(x, j)) {
+ Log.v(TAG, "pixel = " + goldenBitmap.getPixel(x, j));
+ return false;
+ }
+ }
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ return false;
+ }
+ return true;
+ }
+
+ //Load midi file from resources
+ public static boolean resourcesPlayback(AssetFileDescriptor afd, int expectedDuration) {
+ int duration = 0;
+ try {
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getLength());
+ mp.prepare();
+ mp.start();
+ duration = mp.getDuration();
+ Thread.sleep(5000);
+ mp.release();
+ } catch (Exception e) {
+ Log.v(TAG,e.getMessage());
+ }
+ if (duration > expectedDuration)
+ return true;
+ else
+ return false;
+ }
+
+ public static boolean prepareAsyncReset(String filePath) {
+ //preparesAsync
+ try {
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(filePath);
+ mp.prepareAsync();
+ mp.reset();
+ mp.release();
+ } catch (Exception e) {
+ Log.v(TAG,e.getMessage());
+ return false;
+ }
+ return true;
+ }
+
+
+ public static boolean isLooping(String filePath) {
+ MediaPlayer mp = null;
+
+ try {
+ mp = new MediaPlayer();
+ if (mp.isLooping()) {
+ Log.v(TAG, "MediaPlayer.isLooping() returned true after ctor");
+ return false;
+ }
+ mp.setDataSource(filePath);
+ mp.prepare();
+
+ mp.setLooping(true);
+ if (!mp.isLooping()) {
+ Log.v(TAG, "MediaPlayer.isLooping() returned false after setLooping(true)");
+ return false;
+ }
+
+ mp.setLooping(false);
+ if (mp.isLooping()) {
+ Log.v(TAG, "MediaPlayer.isLooping() returned true after setLooping(false)");
+ return false;
+ }
+ } catch (Exception e) {
+ Log.v(TAG, "Exception : " + e.toString());
+ return false;
+ } finally {
+ if (mp != null)
+ mp.release();
+ }
+
+ return true;
+ }
+
+ public static boolean isLoopingAfterReset(String filePath) {
+ MediaPlayer mp = null;
+ try {
+ mp = new MediaPlayer();
+ mp.setDataSource(filePath);
+ mp.prepare();
+
+ mp.setLooping(true);
+ mp.reset();
+ if (mp.isLooping()) {
+ Log.v(TAG, "MediaPlayer.isLooping() returned true after reset()");
+ return false;
+ }
+ } catch (Exception e){
+ Log.v(TAG, "Exception : " + e.toString());
+ return false;
+ } finally {
+ if (mp != null)
+ mp.release();
+ }
+
+ return true;
+ }
+
+ /*
+ * Initializes the message looper so that the mediaPlayer object can
+ * receive the callback messages.
+ */
+ private static void initializeMessageLooper() {
+ Log.v(TAG, "start looper");
+ new Thread() {
+ @Override
+ public void run() {
+ // Set up a looper to be used by camera.
+ Looper.prepare();
+ Log.v(TAG, "start loopRun");
+ // Save the looper so that we can terminate this thread
+ // after we are done with it.
+ mLooper = Looper.myLooper();
+ mMediaPlayer = new MediaPlayer();
+ synchronized (mLock) {
+ mInitialized = true;
+ mLock.notify();
+ }
+ Looper.loop(); // Blocks forever until Looper.quit() is called.
+ Log.v(TAG, "initializeMessageLooper: quit.");
+ }
+ }.start();
+ }
+
+ /*
+ * Terminates the message looper thread.
+ */
+ private static void terminateMessageLooper() {
+ mLooper.quit();
+ mMediaPlayer.release();
+ }
+
+ static MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
+ public void onPrepared(MediaPlayer mp) {
+ synchronized (mPrepareDone) {
+ if(mPrepareReset) {
+ Log.v(TAG, "call Reset");
+ mMediaPlayer.reset();
+ }
+ Log.v(TAG, "notify the prepare callback");
+ mPrepareDone.notify();
+ mOnPrepareSuccess = true;
+ }
+ }
+ };
+
+ public static boolean prepareAsyncCallback(String filePath, boolean reset) throws Exception {
+ //Added the PrepareReset flag which allow us to switch to different
+ //test case.
+ if (reset) {
+ mPrepareReset = true;
+ }
+
+ synchronized (mLock) {
+ initializeMessageLooper();
+ try {
+ mLock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch(Exception e) {
+ Log.v(TAG, "looper was interrupted.");
+ return false;
+ }
+ }
+ try{
+ mMediaPlayer.setOnPreparedListener(mPreparedListener);
+ mMediaPlayer.setDataSource(filePath);
+ mMediaPlayer.setDisplay(MediaFrameworkTest.getSurfaceView().getHolder());
+ mMediaPlayer.prepareAsync();
+ synchronized (mPrepareDone) {
+ try {
+ mPrepareDone.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch (Exception e) {
+ Log.v(TAG, "wait was interrupted.");
+ }
+ }
+ terminateMessageLooper();
+ }catch (Exception e) {
+ Log.v(TAG,e.getMessage());
+ }
+ return mOnPrepareSuccess;
+ }
+
+ static MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
+ public void onCompletion(MediaPlayer mp) {
+ synchronized (mOnCompletion) {
+ Log.v(TAG, "notify the completion callback");
+ mOnCompletion.notify();
+ mOnCompleteSuccess = true;
+ }
+ }
+ };
+
+ static MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {
+ public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
+ Log.v(TAG, "playback error");
+ mPlaybackError = true;
+ mp.reset();
+ synchronized (mOnCompletion) {
+ Log.v(TAG, "notify the completion callback");
+ mOnCompletion.notify();
+ mOnCompleteSuccess = false;
+ }
+ return true;
+ }
+ };
+
+ static MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
+ public boolean onInfo(MediaPlayer mp, int what, int extra) {
+ switch (what) {
+ case MediaPlayer.MEDIA_INFO_UNKNOWN:
+ mMediaInfoUnknownCount++;
+ break;
+ case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
+ mMediaInfoVideoTrackLaggingCount++;
+ break;
+ case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:
+ mMediaInfoBadInterleavingCount++;
+ break;
+ case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:
+ mMediaInfoNotSeekableCount++;
+ break;
+ case MediaPlayer.MEDIA_INFO_METADATA_UPDATE:
+ mMediaInfoMetdataUpdateCount++;
+ break;
+ }
+ return true;
+ }
+ };
+
+ public static boolean playMediaSample(String fileName) throws Exception {
+ int duration = 0;
+ int curPosition = 0;
+ int nextPosition = 0;
+ int waittime = 0;
+ mOnCompleteSuccess = false;
+ mMediaInfoUnknownCount = 0;
+ mMediaInfoVideoTrackLaggingCount = 0;
+ mMediaInfoBadInterleavingCount = 0;
+ mMediaInfoNotSeekableCount = 0;
+ mMediaInfoMetdataUpdateCount = 0;
+ mPlaybackError = false;
+
+ initializeMessageLooper();
+ synchronized (mLock) {
+ try {
+ mLock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch(Exception e) {
+ Log.v(TAG, "looper was interrupted.");
+ return false;
+ }
+ }
+ try {
+ mMediaPlayer.setOnCompletionListener(mCompletionListener);
+ mMediaPlayer.setOnErrorListener(mOnErrorListener);
+ mMediaPlayer.setOnInfoListener(mInfoListener);
+ Log.v(TAG, "playMediaSample: sample file name " + fileName);
+ mMediaPlayer.setDataSource(fileName);
+ mMediaPlayer.setDisplay(MediaFrameworkTest.getSurfaceView().getHolder());
+ mMediaPlayer.prepare();
+ duration = mMediaPlayer.getDuration();
+ Log.v(TAG, "duration of media " + duration);
+ // start to play
+ mMediaPlayer.start();
+ waittime = duration - mMediaPlayer.getCurrentPosition();
+ synchronized(mOnCompletion) {
+ try {
+ mOnCompletion.wait(waittime + 2000);
+ } catch (Exception e) {
+ Log.v(TAG, "playMediaSamples are interrupted");
+ return false;
+ }
+ }
+ terminateMessageLooper();
+ } catch (Exception e) {
+ Log.v(TAG, "playMediaSample Exception:" + e.getMessage());
+ }
+ return mOnCompleteSuccess;
+ }
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/H263QcifLongPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/H263QcifLongPlayerTest.java
new file mode 100644
index 0000000..6e47fe1
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/H263QcifLongPlayerTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.mediastress.cts;
+
+public class H263QcifLongPlayerTest extends MediaPlayerStressTest {
+ private final static String VIDEO_PATH_MIDDLE = "bbb_full/176x144/3gp_h263_libfaac/";
+ private final String[] mMedias = { // indentation shortened due to long file name
+ "bbb_full.ffmpeg.176x144.3gp.h263_56kbps_12fps.libfaac_mono_24kbps_11025Hz.3gp"
+ };
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackLong(0);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/H263QcifShortPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/H263QcifShortPlayerTest.java
new file mode 100644
index 0000000..2035869
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/H263QcifShortPlayerTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.mediastress.cts;
+
+public class H263QcifShortPlayerTest extends MediaPlayerStressTest {
+ private final static String VIDEO_PATH_MIDDLE = "bbb_short/176x144/3gp_h263_libfaac/";
+ private final String[] mMedias = {
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_12fps.libfaac_mono_24kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_12fps.libfaac_mono_24kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_12fps.libfaac_stereo_128kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_12fps.libfaac_stereo_128kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_12fps.libfaac_stereo_24kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_12fps.libfaac_stereo_24kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_25fps.libfaac_mono_24kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_25fps.libfaac_mono_24kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_25fps.libfaac_stereo_128kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_25fps.libfaac_stereo_128kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_25fps.libfaac_stereo_24kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_300kbps_25fps.libfaac_stereo_24kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_12fps.libfaac_mono_24kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_12fps.libfaac_mono_24kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_12fps.libfaac_stereo_128kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_12fps.libfaac_stereo_128kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_12fps.libfaac_stereo_24kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_12fps.libfaac_stereo_24kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_25fps.libfaac_mono_24kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_25fps.libfaac_mono_24kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_25fps.libfaac_stereo_128kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_25fps.libfaac_stereo_128kbps_22050Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_25fps.libfaac_stereo_24kbps_11025Hz.3gp",
+ "bbb_short.ffmpeg.176x144.3gp.h263_56kbps_25fps.libfaac_stereo_24kbps_22050Hz.3gp"
+ };
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackShort(0);
+ }
+
+ public void testPlay01() throws Exception {
+ doTestVideoPlaybackShort(1);
+ }
+
+ public void testPlay02() throws Exception {
+ doTestVideoPlaybackShort(2);
+ }
+
+ public void testPlay03() throws Exception {
+ doTestVideoPlaybackShort(3);
+ }
+
+ public void testPlay04() throws Exception {
+ doTestVideoPlaybackShort(4);
+ }
+
+ public void testPlay05() throws Exception {
+ doTestVideoPlaybackShort(5);
+ }
+
+ public void testPlay06() throws Exception {
+ doTestVideoPlaybackShort(6);
+ }
+
+ public void testPlay07() throws Exception {
+ doTestVideoPlaybackShort(7);
+ }
+
+ public void testPlay08() throws Exception {
+ doTestVideoPlaybackShort(8);
+ }
+
+ public void testPlay09() throws Exception {
+ doTestVideoPlaybackShort(9);
+ }
+
+ public void testPlay10() throws Exception {
+ doTestVideoPlaybackShort(10);
+ }
+
+ public void testPlay11() throws Exception {
+ doTestVideoPlaybackShort(11);
+ }
+
+ public void testPlay12() throws Exception {
+ doTestVideoPlaybackShort(12);
+ }
+
+ public void testPlay13() throws Exception {
+ doTestVideoPlaybackShort(13);
+ }
+
+ public void testPlay14() throws Exception {
+ doTestVideoPlaybackShort(14);
+ }
+
+ public void testPlay15() throws Exception {
+ doTestVideoPlaybackShort(15);
+ }
+
+ public void testPlay16() throws Exception {
+ doTestVideoPlaybackShort(16);
+ }
+
+ public void testPlay17() throws Exception {
+ doTestVideoPlaybackShort(17);
+ }
+
+ public void testPlay18() throws Exception {
+ doTestVideoPlaybackShort(18);
+ }
+
+ public void testPlay19() throws Exception {
+ doTestVideoPlaybackShort(19);
+ }
+
+ public void testPlay20() throws Exception {
+ doTestVideoPlaybackShort(20);
+ }
+
+ public void testPlay21() throws Exception {
+ doTestVideoPlaybackShort(21);
+ }
+
+ public void testPlay22() throws Exception {
+ doTestVideoPlaybackShort(22);
+ }
+
+ public void testPlay23() throws Exception {
+ doTestVideoPlaybackShort(23);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/H264R1080pAacLongPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/H264R1080pAacLongPlayerTest.java
new file mode 100644
index 0000000..b7f7564
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/H264R1080pAacLongPlayerTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.mediastress.cts;
+
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder.AudioEncoder;
+import android.media.MediaRecorder.VideoEncoder;
+
+public class H264R1080pAacLongPlayerTest extends MediaPlayerStressTest {
+ private static final String VIDEO_PATH_MIDDLE = "bbb_full/1920x1080/mp4_libx264_libfaac/";
+ private final String[] mMedias = {
+ "bbb_full.ffmpeg.1920x1080.mp4.libx264_10000kbps_30fps.libfaac_stereo_192kbps_48000Hz.mp4"
+ };
+
+ public H264R1080pAacLongPlayerTest() {
+ super(CamcorderProfile.QUALITY_1080P, VideoEncoder.H264, AudioEncoder.AAC);
+ }
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackLong(0);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/H264R1080pAacShortPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/H264R1080pAacShortPlayerTest.java
new file mode 100644
index 0000000..3b7da57
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/H264R1080pAacShortPlayerTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.mediastress.cts;
+
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder.AudioEncoder;
+import android.media.MediaRecorder.VideoEncoder;
+
+public class H264R1080pAacShortPlayerTest extends MediaPlayerStressTest {
+ private static final String VIDEO_PATH_MIDDLE = "bbb_short/1920x1080/mp4_libx264_libfaac/";
+ private final String[] mMedias = {
+ "bbb_short.ffmpeg.1920x1080.mp4.libx264_10000kbps_30fps.libfaac_stereo_192kbps_48000Hz.mp4",
+ "bbb_short.ffmpeg.1920x1080.mp4.libx264_1750kbps_30fps.libfaac_stereo_192kbps_48000Hz.mp4",
+ "bbb_short.ffmpeg.1920x1080.mp4.libx264_5000kbps_30fps.libfaac_stereo_192kbps_48000Hz.mp4"
+ };
+
+ public H264R1080pAacShortPlayerTest() {
+ super(CamcorderProfile.QUALITY_1080P, VideoEncoder.H264, AudioEncoder.AAC);
+ }
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackShort(0);
+ }
+
+ public void testPlay01() throws Exception {
+ doTestVideoPlaybackShort(1);
+ }
+
+ public void testPlay02() throws Exception {
+ doTestVideoPlaybackShort(2);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/H264R480pAacLongPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/H264R480pAacLongPlayerTest.java
new file mode 100644
index 0000000..f01aa75
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/H264R480pAacLongPlayerTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.mediastress.cts;
+
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder.AudioEncoder;
+import android.media.MediaRecorder.VideoEncoder;
+
+public class H264R480pAacLongPlayerTest extends MediaPlayerStressTest {
+ private static final String VIDEO_PATH_MIDDLE = "bbb_full/720x480/mp4_libx264_libfaac/";
+ private final String[] mMedias = {
+ "bbb_full.ffmpeg.720x480.mp4.libx264_500kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4"
+ };
+
+ public H264R480pAacLongPlayerTest() {
+ super(CamcorderProfile.QUALITY_480P, VideoEncoder.H264, AudioEncoder.AAC);
+ }
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackLong(0);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/H264R480pAacShortPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/H264R480pAacShortPlayerTest.java
new file mode 100644
index 0000000..81b80e5
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/H264R480pAacShortPlayerTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.mediastress.cts;
+
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder.AudioEncoder;
+import android.media.MediaRecorder.VideoEncoder;
+
+public class H264R480pAacShortPlayerTest extends MediaPlayerStressTest {
+ private static final String VIDEO_PATH_MIDDLE = "bbb_short/720x480/mp4_libx264_libfaac/";
+ private final String[] mMedias = {
+ "bbb_short.ffmpeg.720x480.mp4.libx264_1000kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_1000kbps_25fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_1000kbps_30fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_1000kbps_30fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_1350kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_1350kbps_25fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_1350kbps_30fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_1350kbps_30fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_500kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_500kbps_25fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_500kbps_30fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.720x480.mp4.libx264_500kbps_30fps.libfaac_stereo_192kbps_44100Hz.mp4"
+ };
+
+ public H264R480pAacShortPlayerTest() {
+ super(CamcorderProfile.QUALITY_480P, VideoEncoder.H264, AudioEncoder.AAC);
+ }
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackShort(0);
+ }
+
+ public void testPlay01() throws Exception {
+ doTestVideoPlaybackShort(1);
+ }
+
+ public void testPlay02() throws Exception {
+ doTestVideoPlaybackShort(2);
+ }
+
+ public void testPlay03() throws Exception {
+ doTestVideoPlaybackShort(3);
+ }
+
+ public void testPlay04() throws Exception {
+ doTestVideoPlaybackShort(4);
+ }
+
+ public void testPlay05() throws Exception {
+ doTestVideoPlaybackShort(5);
+ }
+
+ public void testPlay06() throws Exception {
+ doTestVideoPlaybackShort(6);
+ }
+
+ public void testPlay07() throws Exception {
+ doTestVideoPlaybackShort(7);
+ }
+
+ public void testPlay08() throws Exception {
+ doTestVideoPlaybackShort(8);
+ }
+
+ public void testPlay09() throws Exception {
+ doTestVideoPlaybackShort(9);
+ }
+
+ public void testPlay10() throws Exception {
+ doTestVideoPlaybackShort(10);
+ }
+
+ public void testPlay11() throws Exception {
+ doTestVideoPlaybackShort(11);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/H264R480x360AacShortPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/H264R480x360AacShortPlayerTest.java
new file mode 100644
index 0000000..12e8f6d
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/H264R480x360AacShortPlayerTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.mediastress.cts;
+
+public class H264R480x360AacShortPlayerTest extends MediaPlayerStressTest {
+ private static final String VIDEO_PATH_MIDDLE = "bbb_short/480x360/mp4_libx264_libfaac/";
+ private final String[] mMedias = {
+ "bbb_short.ffmpeg.480x360.mp4.libx264_1000kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_1000kbps_25fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_1000kbps_30fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_1000kbps_30fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_1350kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_1350kbps_25fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_1350kbps_30fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_1350kbps_30fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_500kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_500kbps_25fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_500kbps_30fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.480x360.mp4.libx264_500kbps_30fps.libfaac_stereo_192kbps_44100Hz.mp4"
+ };
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackShort(0);
+ }
+
+ public void testPlay01() throws Exception {
+ doTestVideoPlaybackShort(1);
+ }
+
+ public void testPlay02() throws Exception {
+ doTestVideoPlaybackShort(2);
+ }
+
+ public void testPlay03() throws Exception {
+ doTestVideoPlaybackShort(3);
+ }
+
+ public void testPlay04() throws Exception {
+ doTestVideoPlaybackShort(4);
+ }
+
+ public void testPlay05() throws Exception {
+ doTestVideoPlaybackShort(5);
+ }
+
+ public void testPlay06() throws Exception {
+ doTestVideoPlaybackShort(6);
+ }
+
+ public void testPlay07() throws Exception {
+ doTestVideoPlaybackShort(7);
+ }
+
+ public void testPlay08() throws Exception {
+ doTestVideoPlaybackShort(8);
+ }
+
+ public void testPlay09() throws Exception {
+ doTestVideoPlaybackShort(9);
+ }
+
+ public void testPlay10() throws Exception {
+ doTestVideoPlaybackShort(10);
+ }
+
+ public void testPlay11() throws Exception {
+ doTestVideoPlaybackShort(11);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/H264R720pAacLongPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/H264R720pAacLongPlayerTest.java
new file mode 100644
index 0000000..3efec62
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/H264R720pAacLongPlayerTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.mediastress.cts;
+
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder.AudioEncoder;
+import android.media.MediaRecorder.VideoEncoder;
+
+public class H264R720pAacLongPlayerTest extends MediaPlayerStressTest {
+ private static final String VIDEO_PATH_MIDDLE = "bbb_full/1280x720/mp4_libx264_libfaac/";
+ private final String[] mMedias = {
+ "bbb_full.ffmpeg.1280x720.mp4.libx264_1350kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_full.ffmpeg.1280x720.mp4.libx264_1750kbps_30fps.libfaac_stereo_192kbps_48000Hz.mp4"
+ };
+
+ public H264R720pAacLongPlayerTest() {
+ super(CamcorderProfile.QUALITY_720P, VideoEncoder.H264, AudioEncoder.AAC);
+ }
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackLong(0);
+ }
+
+ public void testPlay01() throws Exception {
+ doTestVideoPlaybackLong(1);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/H264R720pAacShortPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/H264R720pAacShortPlayerTest.java
new file mode 100644
index 0000000..e919a35
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/H264R720pAacShortPlayerTest.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.mediastress.cts;
+
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder.AudioEncoder;
+import android.media.MediaRecorder.VideoEncoder;
+
+public class H264R720pAacShortPlayerTest extends MediaPlayerStressTest {
+ private static final String VIDEO_PATH_MIDDLE = "bbb_short/1280x720/mp4_libx264_libfaac/";
+ private final String[] mMedias = {
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_10000kbps_30fps.libfaac_stereo_192kbps_48000Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_1000kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_1000kbps_25fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_1000kbps_30fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_1000kbps_30fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_1350kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_1350kbps_25fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_1350kbps_30fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_1350kbps_30fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_1750kbps_30fps.libfaac_stereo_192kbps_48000Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_5000kbps_30fps.libfaac_stereo_192kbps_48000Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_500kbps_25fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_500kbps_25fps.libfaac_stereo_192kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_500kbps_30fps.libfaac_stereo_128kbps_44100Hz.mp4",
+ "bbb_short.ffmpeg.1280x720.mp4.libx264_500kbps_30fps.libfaac_stereo_192kbps_44100Hz.mp4"
+ };
+
+ public H264R720pAacShortPlayerTest() {
+ super(CamcorderProfile.QUALITY_720P, VideoEncoder.H264, AudioEncoder.AAC);
+ }
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackShort(0);
+ }
+
+ public void testPlay01() throws Exception {
+ doTestVideoPlaybackShort(1);
+ }
+
+ public void testPlay02() throws Exception {
+ doTestVideoPlaybackShort(2);
+ }
+
+ public void testPlay03() throws Exception {
+ doTestVideoPlaybackShort(3);
+ }
+
+ public void testPlay04() throws Exception {
+ doTestVideoPlaybackShort(4);
+ }
+
+ public void testPlay05() throws Exception {
+ doTestVideoPlaybackShort(5);
+ }
+
+ public void testPlay06() throws Exception {
+ doTestVideoPlaybackShort(6);
+ }
+
+ public void testPlay07() throws Exception {
+ doTestVideoPlaybackShort(7);
+ }
+
+ public void testPlay08() throws Exception {
+ doTestVideoPlaybackShort(8);
+ }
+
+ public void testPlay09() throws Exception {
+ doTestVideoPlaybackShort(9);
+ }
+
+ public void testPlay10() throws Exception {
+ doTestVideoPlaybackShort(10);
+ }
+
+ public void testPlay11() throws Exception {
+ doTestVideoPlaybackShort(11);
+ }
+
+ public void testPlay12() throws Exception {
+ doTestVideoPlaybackShort(12);
+ }
+
+ public void testPlay13() throws Exception {
+ doTestVideoPlaybackShort(13);
+ }
+
+ public void testPlay14() throws Exception {
+ doTestVideoPlaybackShort(14);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java b/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
new file mode 100644
index 0000000..b8c67e4
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/MediaFrameworkTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.mediastress.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.PowerManager;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import com.android.cts.mediastress.R;
+
+public class MediaFrameworkTest extends Activity implements SurfaceHolder.Callback {
+ private static String TAG = "MediaFrameworkTest";
+ private static SurfaceView mSurfaceView;
+
+ private Bitmap mDestBitmap;
+ private ImageView mOverlayView;
+
+ private PowerManager.WakeLock mWakeLock = null;
+
+ public static SurfaceView getSurfaceView() {
+ return mSurfaceView;
+ }
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.surface_view);
+ mSurfaceView = (SurfaceView)findViewById(R.id.surface_view);
+ mOverlayView = (ImageView)findViewById(R.id.overlay_layer);
+ ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
+ mSurfaceView.getHolder().addCallback(this);
+
+ mOverlayView.setLayoutParams(lp);
+ mDestBitmap = Bitmap.createBitmap((int)640, (int)480, Bitmap.Config.ARGB_8888);
+ mOverlayView.setImageBitmap(mDestBitmap);
+
+ //Acquire the full wake lock to keep the device up
+ PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "MediaFrameworkTest");
+ mWakeLock.acquire();
+ }
+
+ public void onStop(Bundle icicle) {
+ mWakeLock.release();
+ super.onStop();
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ //Can do nothing in here. The test case will fail if the surface destroyed.
+ Log.v(TAG, "Test application surface destroyed");
+ }
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ //Do nothing in here. Just print out the log
+ Log.v(TAG, "Test application surface changed");
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ holder.addCallback(this);
+ Log.v(TAG, "Test application surface created");
+ }
+
+ public void startPlayback(String filename){
+ String mimetype = "audio/mpeg";
+ Uri path = Uri.parse(filename);
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setDataAndType(path, mimetype);
+ startActivity(intent);
+ }
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/MediaPlayerStressTest.java b/tests/tests/mediastress/src/android/mediastress/cts/MediaPlayerStressTest.java
new file mode 100644
index 0000000..3678811
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/MediaPlayerStressTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.mediastress.cts;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder.AudioEncoder;
+import android.media.MediaRecorder.VideoEncoder;
+import android.os.Environment;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+
+import android.test.InstrumentationTestCase;
+
+/**
+ * Helper for implementing video playback stress test
+ */
+abstract class MediaPlayerStressTest extends InstrumentationTestCase {
+ protected static final String VIDEO_TOP_DIR = WorkDir.getMediaDirString();
+ protected static final int REPEAT_NUMBER_FOR_SHORT_CLIPS = 2;
+ protected static final int REPEAT_NUMBER_FOR_LONG_CLIPS = 1;
+ private static final String TAG = "MediaPlayerStressTest";
+ // whether a video format is supported or not.
+ private final boolean mSupported;
+
+ /**
+ * construct a test case with check of whether the format is supported or not.
+ * @param quality
+ * @param videoCodec
+ * @param audioCodec
+ */
+ protected MediaPlayerStressTest(int quality, int videoCodec, int audioCodec) {
+ mSupported = VideoPlayerCapability.formatSupported(quality, videoCodec, audioCodec);
+ }
+
+ protected MediaPlayerStressTest() {
+ mSupported = true; // supported if nothing specified
+ }
+
+ /**
+ * provides full path name of video clip for the given media number
+ * @param mediaNumber
+ * @return video file name
+ */
+ abstract protected String getFullVideoClipName(int mediaNumber);
+
+ private int mTotalPlaybackError;
+ private int mTotalComplete;
+ private int mTotalInfoUnknown;
+ private int mTotalVideoTrackLagging;
+ private int mTotalBadInterleaving;
+ private int mTotalNotSeekable;
+ private int mTotalMetaDataUpdate;
+
+ private void writeTestOutput(String filename, Writer output) throws Exception{
+ output.write("File Name: " + filename);
+ output.write(" Complete: " + CodecTest.mOnCompleteSuccess);
+ output.write(" Error: " + CodecTest.mPlaybackError);
+ output.write(" Unknown Info: " + CodecTest.mMediaInfoUnknownCount);
+ output.write(" Track Lagging: " + CodecTest.mMediaInfoVideoTrackLaggingCount);
+ output.write(" Bad Interleaving: " + CodecTest.mMediaInfoBadInterleavingCount);
+ output.write(" Not Seekable: " + CodecTest.mMediaInfoNotSeekableCount);
+ output.write(" Info Meta data update: " + CodecTest.mMediaInfoMetdataUpdateCount);
+ output.write("\n");
+ }
+
+ private void writeTestSummary(Writer output) throws Exception{
+ output.write("Total Result:\n");
+ output.write("Total Complete: " + mTotalComplete + "\n");
+ output.write("Total Error: " + mTotalPlaybackError + "\n");
+ output.write("Total Unknown Info: " + mTotalInfoUnknown + "\n");
+ output.write("Total Track Lagging: " + mTotalVideoTrackLagging + "\n" );
+ output.write("Total Bad Interleaving: " + mTotalBadInterleaving + "\n");
+ output.write("Total Not Seekable: " + mTotalNotSeekable + "\n");
+ output.write("Total Info Meta data update: " + mTotalMetaDataUpdate + "\n");
+ output.write("\n");
+ }
+
+ private void updateTestResult(){
+ if (CodecTest.mOnCompleteSuccess){
+ mTotalComplete++;
+ }
+ else if (CodecTest.mPlaybackError){
+ mTotalPlaybackError++;
+ }
+ mTotalInfoUnknown += CodecTest.mMediaInfoUnknownCount;
+ mTotalVideoTrackLagging += CodecTest.mMediaInfoVideoTrackLaggingCount;
+ mTotalBadInterleaving += CodecTest.mMediaInfoBadInterleavingCount;
+ mTotalNotSeekable += CodecTest.mMediaInfoNotSeekableCount;
+ mTotalMetaDataUpdate += CodecTest.mMediaInfoMetdataUpdateCount;
+ }
+
+ /**
+ * runs video playback test for the given mediaNumber
+ * @param mediaNumber number of media to be used for playback.
+ * This number is passed to getFullVideoClipName.
+ * @param repeatCounter repeat playback for the given number
+ * @throws Exception
+ */
+ protected void doTestVideoPlayback(int mediaNumber, int repeatCounter) throws Exception {
+ if (!mSupported) {
+ return;
+ }
+
+ File playbackOutput = new File(WorkDir.getTopDir(), "PlaybackTestResult.txt");
+ Writer output = new BufferedWriter(new FileWriter(playbackOutput, true));
+
+ boolean testResult = true;
+ boolean onCompleteSuccess = false;
+
+ Instrumentation inst = getInstrumentation();
+ Intent intent = new Intent();
+
+ intent.setClass(inst.getTargetContext(), MediaFrameworkTest.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ Activity act = inst.startActivitySync(intent);
+
+ String mediaName = getFullVideoClipName(mediaNumber);
+ for (int i = 0; i < repeatCounter; i++) {
+ Log.v(TAG, "start playing " + mediaName);
+ onCompleteSuccess =
+ CodecTest.playMediaSample(mediaName);
+ if (!onCompleteSuccess) {
+ //Don't fail the test right away, print out the failure file.
+ Log.v(TAG, "Failure File : " + mediaName);
+ testResult = false;
+ }
+ }
+ Thread.sleep(1000);
+
+ act.finish();
+ //Write test result to an output file
+ writeTestOutput(mediaName, output);
+ //Get the summary
+ updateTestResult();
+
+ writeTestSummary(output);
+ output.close();
+ assertTrue("playback " + mediaName, testResult);
+ }
+
+ protected void doTestVideoPlaybackShort(int mediaNumber) throws Exception {
+ doTestVideoPlayback(mediaNumber, REPEAT_NUMBER_FOR_SHORT_CLIPS);
+ }
+
+ protected void doTestVideoPlaybackLong(int mediaNumber) throws Exception {
+ doTestVideoPlayback(mediaNumber, REPEAT_NUMBER_FOR_LONG_CLIPS);
+ }
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/MediaRecorderStressTest.java b/tests/tests/mediastress/src/android/mediastress/cts/MediaRecorderStressTest.java
new file mode 100644
index 0000000..fd4e3b3
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/MediaRecorderStressTest.java
@@ -0,0 +1,382 @@
+/*
+ * 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.mediastress.cts;
+
+import android.hardware.Camera;
+import android.media.CamcorderProfile;
+import android.media.MediaPlayer;
+import android.media.MediaRecorder;
+import android.os.Handler;
+import android.os.Looper;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+
+ private static String TAG = "MediaRecorderStressTest";
+ private static final int NUMBER_OF_CAMERA_STRESS_LOOPS = 50;
+ private static final int NUMBER_OF_RECORDER_STRESS_LOOPS = 50;
+ private static final int NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS = 25;
+ private static final int NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER = 50;
+ private static final long WAIT_TIME_CAMERA_TEST = 3000; // in ms
+ private static final long WAIT_TIME_RECORDER_TEST = 5000; // in ms
+ private static final String OUTPUT_FILE = WorkDir.getTopDirString() + "temp";
+ private static final String OUTPUT_FILE_EXT = ".3gp";
+ private static final String MEDIA_STRESS_OUTPUT ="mediaStressOutput.txt";
+ private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
+ private final RecorderErrorCallback mRecorderErrorCallback = new RecorderErrorCallback();
+ private final static int WAIT_TIMEOUT = 10000;
+
+ private MediaRecorder mRecorder;
+ private Camera mCamera;
+ private Thread mLooperThread;
+ private Handler mHandler;
+
+ private static int mCameraId;
+ private static int mProfileQuality = CamcorderProfile.QUALITY_HIGH;
+ private static CamcorderProfile profile =
+ CamcorderProfile.get(mCameraId, mProfileQuality);
+
+ private int mVideoEncoder;
+ private int mAudioEncoder;
+ private int mFrameRate;
+ private int mVideoWidth;
+ private int mVideoHeight;
+ private int mBitRate;
+ private boolean mRemoveVideo = true;
+ private int mRecordDuration = 5000;
+
+ public MediaRecorderStressTest() {
+ super(MediaFrameworkTest.class);
+ }
+
+ protected void setUp() throws Exception {
+ int cameraId = 0;
+ CamcorderProfile profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_HIGH);
+ mVideoEncoder = profile.videoCodec;
+ mAudioEncoder = profile.audioCodec;
+ mFrameRate = profile.videoFrameRate;
+ mVideoWidth = profile.videoFrameWidth;
+ mVideoHeight = profile.videoFrameHeight;
+ mBitRate = profile.videoBitRate;
+
+ final Semaphore sem = new Semaphore(0);
+ mLooperThread = new Thread() {
+ @Override
+ public void run() {
+ Log.v(TAG, "starting looper");
+ Looper.prepare();
+ mHandler = new Handler();
+ sem.release();
+ Looper.loop();
+ Log.v(TAG, "quit looper");
+ }
+ };
+ mLooperThread.start();
+ if (!sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
+ fail("Failed to start the looper.");
+ }
+
+ getActivity();
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mHandler != null) {
+ mHandler.getLooper().quit();
+ mHandler = null;
+ }
+ if (mLooperThread != null) {
+ mLooperThread.join(WAIT_TIMEOUT);
+ if (mLooperThread.isAlive()) {
+ fail("Failed to stop the looper.");
+ }
+ mLooperThread = null;
+ }
+
+ super.tearDown();
+ }
+
+ private void runOnLooper(final Runnable command) throws InterruptedException {
+ final Semaphore sem = new Semaphore(0);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ command.run();
+ } finally {
+ sem.release();
+ }
+ }
+ });
+ if (! sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
+ fail("Failed to run the command on the looper.");
+ }
+ }
+
+ private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
+ public void onError(int error, android.hardware.Camera camera) {
+ assertTrue("Camera test mediaserver died", error !=
+ android.hardware.Camera.CAMERA_ERROR_SERVER_DIED);
+ }
+ }
+
+ private final class RecorderErrorCallback implements MediaRecorder.OnErrorListener {
+ public void onError(MediaRecorder mr, int what, int extra) {
+ // fail the test case no matter what error come up
+ fail("mediaRecorder error");
+ }
+ }
+
+ //Test case for stressing the camera preview.
+ @LargeTest
+ public void testStressCamera() throws Exception {
+ SurfaceHolder mSurfaceHolder;
+ mSurfaceHolder = MediaFrameworkTest.getSurfaceView().getHolder();
+ File stressOutFile = new File(WorkDir.getTopDir(), MEDIA_STRESS_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
+ output.write("Camera start preview stress:\n");
+ output.write("Total number of loops:" +
+ NUMBER_OF_CAMERA_STRESS_LOOPS + "\n");
+
+ Log.v(TAG, "Start preview");
+ output.write("No of loop: ");
+
+ for (int i = 0; i< NUMBER_OF_CAMERA_STRESS_LOOPS; i++) {
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mCamera = Camera.open();
+ }
+ });
+ mCamera.setErrorCallback(mCameraErrorCallback);
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ mCamera.startPreview();
+ Thread.sleep(WAIT_TIME_CAMERA_TEST);
+ mCamera.stopPreview();
+ mCamera.release();
+ output.write(" ," + i);
+ }
+
+ output.write("\n\n");
+ output.close();
+ }
+
+ //Test case for stressing the camera preview.
+ @LargeTest
+ public void testStressRecorder() throws Exception {
+ String filename;
+ SurfaceHolder mSurfaceHolder;
+ mSurfaceHolder = MediaFrameworkTest.getSurfaceView().getHolder();
+ File stressOutFile = new File(WorkDir.getTopDir(), MEDIA_STRESS_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
+ output.write("H263 video record- reset after prepare Stress test\n");
+ output.write("Total number of loops:" +
+ NUMBER_OF_RECORDER_STRESS_LOOPS + "\n");
+
+ output.write("No of loop: ");
+ Log.v(TAG, "Start preview");
+ for (int i = 0; i < NUMBER_OF_RECORDER_STRESS_LOOPS; i++) {
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mRecorder = new MediaRecorder();
+ }
+ });
+ Log.v(TAG, "counter = " + i);
+ filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
+ Log.v(TAG, filename);
+ mRecorder.setOnErrorListener(mRecorderErrorCallback);
+ mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFile(filename);
+ mRecorder.setVideoFrameRate(mFrameRate);
+ mRecorder.setVideoSize(176,144);
+ Log.v(TAG, "setEncoder");
+ mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
+ mSurfaceHolder = MediaFrameworkTest.getSurfaceView().getHolder();
+ Log.v(TAG, "setPreview");
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+ Log.v(TAG, "prepare");
+ mRecorder.prepare();
+ Log.v(TAG, "before release");
+ Thread.sleep(WAIT_TIME_RECORDER_TEST);
+ mRecorder.reset();
+ mRecorder.release();
+ output.write(", " + i);
+ }
+
+ output.write("\n\n");
+ output.close();
+ }
+
+ //Stress test case for switching camera and video recorder preview.
+ @LargeTest
+ public void testStressCameraSwitchRecorder() throws Exception {
+ String filename;
+ SurfaceHolder mSurfaceHolder;
+ mSurfaceHolder = MediaFrameworkTest.getSurfaceView().getHolder();
+ File stressOutFile = new File(WorkDir.getTopDir(), MEDIA_STRESS_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
+ output.write("Camera and video recorder preview switching\n");
+ output.write("Total number of loops:"
+ + NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER + "\n");
+
+ Log.v(TAG, "Start preview");
+ output.write("No of loop: ");
+ for (int i = 0; i < NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER; i++) {
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mCamera = Camera.open();
+ }
+ });
+ mCamera.setErrorCallback(mCameraErrorCallback);
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ mCamera.startPreview();
+ Thread.sleep(WAIT_TIME_CAMERA_TEST);
+ mCamera.stopPreview();
+ mCamera.release();
+ mCamera = null;
+ Log.v(TAG, "release camera");
+ filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
+ Log.v(TAG, filename);
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mRecorder = new MediaRecorder();
+ }
+ });
+ mRecorder.setOnErrorListener(mRecorderErrorCallback);
+ mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFile(filename);
+ mRecorder.setVideoFrameRate(mFrameRate);
+ mRecorder.setVideoSize(176,144);
+ Log.v(TAG, "Media recorder setEncoder");
+ mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
+ Log.v(TAG, "mediaRecorder setPreview");
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+ Log.v(TAG, "prepare");
+ mRecorder.prepare();
+ Log.v(TAG, "before release");
+ Thread.sleep(WAIT_TIME_CAMERA_TEST);
+ mRecorder.reset();
+ mRecorder.release();
+ Log.v(TAG, "release video recorder");
+ output.write(", " + i);
+ }
+
+ output.write("\n\n");
+ output.close();
+ }
+
+ public void validateRecordedVideo(String recordedFile) throws Exception {
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(recordedFile);
+ mp.prepare();
+ int duration = mp.getDuration();
+ if (duration <= 0){
+ assertTrue("stressRecordAndPlayback", false);
+ }
+ mp.release();
+ }
+
+ public void removeRecodedVideo(String filename){
+ File video = new File(filename);
+ Log.v(TAG, "remove recorded video " + filename);
+ video.delete();
+ }
+
+ //Stress test case for record a video and play right away.
+ @LargeTest
+ public void testStressRecordVideoAndPlayback() throws Exception {
+ String filename;
+ SurfaceHolder mSurfaceHolder;
+ mSurfaceHolder = MediaFrameworkTest.getSurfaceView().getHolder();
+ File stressOutFile = new File(WorkDir.getTopDir(), MEDIA_STRESS_OUTPUT);
+ Writer output = new BufferedWriter(
+ new FileWriter(stressOutFile, true));
+ output.write("Video record and play back stress test:\n");
+ output.write("Total number of loops:"
+ + NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS + "\n");
+
+ output.write("No of loop: ");
+ for (int i = 0; i < NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS; i++){
+ filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
+ Log.v(TAG, filename);
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mRecorder = new MediaRecorder();
+ }
+ });
+ Log.v(TAG, "iterations : " + i);
+ Log.v(TAG, "videoEncoder : " + mVideoEncoder);
+ Log.v(TAG, "audioEncoder : " + mAudioEncoder);
+ Log.v(TAG, "frameRate : " + mFrameRate);
+ Log.v(TAG, "videoWidth : " + mVideoWidth);
+ Log.v(TAG, "videoHeight : " + mVideoHeight);
+ Log.v(TAG, "bitRate : " + mBitRate);
+ Log.v(TAG, "recordDuration : " + mRecordDuration);
+
+ mRecorder.setOnErrorListener(mRecorderErrorCallback);
+ mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFile(filename);
+ mRecorder.setVideoFrameRate(mFrameRate);
+ mRecorder.setVideoSize(mVideoWidth, mVideoHeight);
+ mRecorder.setVideoEncoder(mVideoEncoder);
+ mRecorder.setAudioEncoder(mAudioEncoder);
+ Log.v(TAG, "mediaRecorder setPreview");
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+ mRecorder.prepare();
+ mRecorder.start();
+ Thread.sleep(mRecordDuration);
+ Log.v(TAG, "Before stop");
+ mRecorder.stop();
+ mRecorder.release();
+ //start the playback
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(filename);
+ mp.setDisplay(MediaFrameworkTest.getSurfaceView().getHolder());
+ mp.prepare();
+ mp.start();
+ Thread.sleep(mRecordDuration);
+ mp.release();
+ validateRecordedVideo(filename);
+ if (mRemoveVideo) {
+ removeRecodedVideo(filename);
+ }
+ output.write(", " + i);
+ }
+
+ output.write("\n\n");
+ output.close();
+ }
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/VideoPlayerCapability.java b/tests/tests/mediastress/src/android/mediastress/cts/VideoPlayerCapability.java
new file mode 100644
index 0000000..f8dd2aa
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/VideoPlayerCapability.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.mediastress.cts;
+
+import android.media.CamcorderProfile;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+public class VideoPlayerCapability {
+ private static final String TAG = "VideoPlayCapability";
+
+ static boolean formatSupported(int quality, int videoCodec, int audioCodec) {
+ if (!CamcorderProfile.hasProfile(quality)) {
+ Log.i(TAG, "quality " + quality + " not supported");
+ return false;
+ }
+ CamcorderProfile profile = CamcorderProfile.get(quality);
+ Assert.assertNotNull(profile);
+ if ((profile.videoCodec == videoCodec) && (profile.audioCodec == audioCodec)) {
+ Log.i(TAG, "quality " + quality + " video codec " + videoCodec + " audio codec " +
+ audioCodec + " supproted");
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/Vp8R480x360LongPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/Vp8R480x360LongPlayerTest.java
new file mode 100644
index 0000000..372f034
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/Vp8R480x360LongPlayerTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.mediastress.cts;
+
+public class Vp8R480x360LongPlayerTest extends MediaPlayerStressTest {
+ private static final String VIDEO_PATH_MIDDLE = "bbb_full/480x360/webm_libvpx_libvorbis/";
+ private final String[] mMedias = {
+ "bbb_full.ffmpeg.480x360.webm.libvpx_500kbps_25fps.libvorbis_stereo_128kbps_44100Hz.webm"
+ };
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackLong(0);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/Vp8R480x360ShortPlayerTest.java b/tests/tests/mediastress/src/android/mediastress/cts/Vp8R480x360ShortPlayerTest.java
new file mode 100644
index 0000000..30b4d2e
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/Vp8R480x360ShortPlayerTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.mediastress.cts;
+
+public class Vp8R480x360ShortPlayerTest extends MediaPlayerStressTest {
+ private static final String VIDEO_PATH_MIDDLE = "bbb_short/480x360/webm_libvpx_libvorbis/";
+ private final String[] mMedias = {
+ "bbb_short.ffmpeg.480x360.webm.libvpx_1000kbps_25fps.libvorbis_stereo_128kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_1000kbps_25fps.libvorbis_stereo_192kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_1000kbps_30fps.libvorbis_stereo_128kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_1000kbps_30fps.libvorbis_stereo_192kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_1350kbps_25fps.libvorbis_stereo_128kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_1350kbps_25fps.libvorbis_stereo_192kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_1350kbps_30fps.libvorbis_stereo_128kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_1350kbps_30fps.libvorbis_stereo_192kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_500kbps_25fps.libvorbis_stereo_128kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_500kbps_25fps.libvorbis_stereo_192kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_500kbps_30fps.libvorbis_stereo_128kbps_44100Hz.webm",
+ "bbb_short.ffmpeg.480x360.webm.libvpx_500kbps_30fps.libvorbis_stereo_192kbps_44100Hz.webm"
+ };
+
+ public void testPlay00() throws Exception {
+ doTestVideoPlaybackShort(0);
+ }
+
+ public void testPlay01() throws Exception {
+ doTestVideoPlaybackShort(1);
+ }
+
+ public void testPlay02() throws Exception {
+ doTestVideoPlaybackShort(2);
+ }
+
+ public void testPlay03() throws Exception {
+ doTestVideoPlaybackShort(3);
+ }
+
+ public void testPlay04() throws Exception {
+ doTestVideoPlaybackShort(4);
+ }
+
+ public void testPlay05() throws Exception {
+ doTestVideoPlaybackShort(5);
+ }
+
+ public void testPlay06() throws Exception {
+ doTestVideoPlaybackShort(6);
+ }
+
+ public void testPlay07() throws Exception {
+ doTestVideoPlaybackShort(7);
+ }
+
+ public void testPlay08() throws Exception {
+ doTestVideoPlaybackShort(8);
+ }
+
+ public void testPlay09() throws Exception {
+ doTestVideoPlaybackShort(9);
+ }
+
+ public void testPlay10() throws Exception {
+ doTestVideoPlaybackShort(10);
+ }
+
+ public void testPlay11() throws Exception {
+ doTestVideoPlaybackShort(11);
+ }
+
+ @Override
+ protected String getFullVideoClipName(int mediaNumber) {
+ return VIDEO_TOP_DIR + VIDEO_PATH_MIDDLE + mMedias[mediaNumber];
+ }
+
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/WorkDir.java b/tests/tests/mediastress/src/android/mediastress/cts/WorkDir.java
new file mode 100644
index 0000000..4a40fad
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/cts/WorkDir.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.mediastress.cts;
+
+import android.os.Environment;
+
+import java.io.File;
+
+import junit.framework.Assert;
+
+public class WorkDir {
+ static final File getTopDir() {
+ Assert.assertEquals(Environment.getExternalStorageState(), Environment.MEDIA_MOUNTED);
+ return Environment.getExternalStorageDirectory();
+ }
+
+ static final String getTopDirString() {
+ return (getTopDir().getAbsolutePath() + File.separator);
+ }
+
+ static final String getMediaDirString() {
+ return (getTopDirString() + "test/");
+ }
+}
diff --git a/tests/tests/net/Android.mk b/tests/tests/net/Android.mk
index 1fd9ba0..bf51890 100644
--- a/tests/tests/net/Android.mk
+++ b/tests/tests/net/Android.mk
@@ -23,12 +23,12 @@
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+# include CtsTestServer as a temporary hack to free net.cts from cts.stub.
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ ../../src/android/webkit/cts/CtsTestServer.java
LOCAL_PACKAGE_NAME := CtsNetTestCases
-LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
-
# uncomment when dalvik.annotation.Test* are removed or part of SDK
#LOCAL_SDK_VERSION := current
diff --git a/tests/tests/net/AndroidManifest.xml b/tests/tests/net/AndroidManifest.xml
index a1f632e..4fa0565 100644
--- a/tests/tests/net/AndroidManifest.xml
+++ b/tests/tests/net/AndroidManifest.xml
@@ -18,12 +18,20 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.net">
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
<application>
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
- android:targetPackage="com.android.cts.stub"
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.cts.net"
android:label="CTS tests of android.net"/>
</manifest>
diff --git a/tests/tests/net/src/android/net/cts/VpnServiceTest.java b/tests/tests/net/src/android/net/cts/VpnServiceTest.java
new file mode 100644
index 0000000..9e35375
--- /dev/null
+++ b/tests/tests/net/src/android/net/cts/VpnServiceTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net.cts;
+
+import android.content.Intent;
+import android.net.VpnService;
+import android.os.ParcelFileDescriptor;
+import android.test.AndroidTestCase;
+
+import java.io.File;
+import java.net.DatagramSocket;
+import java.net.Socket;
+
+/**
+ * VpnService API is built with security in mind. However, its security also
+ * blocks us from writing tests for positive cases. For now we only test for
+ * negative cases, and we will try to cover the rest in the future.
+ */
+public class VpnServiceTest extends AndroidTestCase {
+
+ private static final String TAG = VpnServiceTest.class.getSimpleName();
+
+ private VpnService mVpnService = new VpnService();
+
+ public void testPrepare() throws Exception {
+ // Should never return null since we are not prepared.
+ Intent intent = VpnService.prepare(mContext);
+ assertNotNull(intent);
+
+ // Should be always resolved by only one activity.
+ int count = mContext.getPackageManager().queryIntentActivities(intent, 0).size();
+ assertEquals(count, 1);
+ }
+
+ public void testEstablish() throws Exception {
+ ParcelFileDescriptor descriptor = null;
+ try {
+ // Should always return null since we are not prepared.
+ descriptor = mVpnService.new Builder().addAddress("8.8.8.8", 30).establish();
+ assertNull(descriptor);
+ } finally {
+ try {
+ descriptor.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+
+ public void testProtect_DatagramSocket() throws Exception {
+ DatagramSocket socket = new DatagramSocket();
+ try {
+ // Should always return false since we are not prepared.
+ assertFalse(mVpnService.protect(socket));
+ } finally {
+ try {
+ socket.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+
+ public void testProtect_Socket() throws Exception {
+ Socket socket = new Socket();
+ try {
+ // Should always return false since we are not prepared.
+ assertFalse(mVpnService.protect(socket));
+ } finally {
+ try {
+ socket.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+
+ public void testProtect_int() throws Exception {
+ DatagramSocket socket = new DatagramSocket();
+ ParcelFileDescriptor descriptor = ParcelFileDescriptor.fromDatagramSocket(socket);
+ try {
+ // Should always return false since we are not prepared.
+ assertFalse(mVpnService.protect(descriptor.getFd()));
+ } finally {
+ try {
+ descriptor.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ try {
+ socket.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+
+ public void testTunDevice() throws Exception {
+ File file = new File("/dev/tun");
+ assertTrue(file.exists());
+ assertFalse(file.isFile());
+ assertFalse(file.isDirectory());
+ assertFalse(file.canExecute());
+ assertFalse(file.canRead());
+ assertFalse(file.canWrite());
+ }
+}
diff --git a/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java
index 0ab71c7..b7202d2 100644
--- a/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java
@@ -65,6 +65,10 @@
@Override
protected void setUp() throws Exception {
super.setUp();
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
mMySync = new MySync();
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
@@ -90,6 +94,11 @@
@Override
protected void tearDown() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ super.tearDown();
+ return;
+ }
mWifiLock.release();
mContext.unregisterReceiver(mReceiver);
if (!mWifiManager.isWifiEnabled())
@@ -115,6 +124,10 @@
args = {}
)
public void testScanResultProperties() {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
List<ScanResult> scanResults = mWifiManager.getScanResults();
// this test case should in Wifi environment
for (int i = 0; i < scanResults.size(); i++) {
diff --git a/tests/tests/net/src/android/net/wifi/cts/SupplicantStateTest.java b/tests/tests/net/src/android/net/wifi/cts/SupplicantStateTest.java
index 4e03f5e..88ecfe8 100644
--- a/tests/tests/net/src/android/net/wifi/cts/SupplicantStateTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/SupplicantStateTest.java
@@ -34,6 +34,10 @@
)
})
public void testIsValidState() {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
assertTrue(SupplicantState.isValidState(SupplicantState.DISCONNECTED));
assertTrue(SupplicantState.isValidState(SupplicantState.INACTIVE));
assertTrue(SupplicantState.isValidState(SupplicantState.SCANNING));
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiConfigurationTest.java
index 3018907..f11aa4a 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiConfigurationTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiConfigurationTest.java
@@ -50,6 +50,10 @@
)
})
public void testWifiConfiguration() {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
List<WifiConfiguration> wifiConfigurations = mWifiManager.getConfiguredNetworks();
for (int i = 0; i < wifiConfigurations.size(); i++) {
WifiConfiguration wifiConfiguration = wifiConfigurations.get(i);
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java b/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java
new file mode 100644
index 0000000..d7a83c3
--- /dev/null
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiFeature.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+public class WifiFeature {
+ static boolean isWifiSupported(Context context) {
+ PackageManager packageManager = context.getPackageManager();
+ return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
+ }
+}
+
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
index 44189cd..2713dfd 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
@@ -66,6 +66,10 @@
@Override
protected void setUp() throws Exception {
super.setUp();
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
mMySync = new MySync();
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
@@ -84,6 +88,11 @@
@Override
protected void tearDown() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ super.tearDown();
+ return;
+ }
mWifiLock.release();
mContext.unregisterReceiver(mReceiver);
if (!mWifiManager.isWifiEnabled())
@@ -161,6 +170,10 @@
)
})
public void testWifiInfoProperties() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
// this test case should in Wifi environment
WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index e2a583b..014f0ee 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -90,6 +90,10 @@
@Override
protected void setUp() throws Exception {
super.setUp();
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
mMySync = new MySync();
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
@@ -115,6 +119,11 @@
@Override
protected void tearDown() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ super.tearDown();
+ return;
+ }
mWifiLock.release();
mContext.unregisterReceiver(mReceiver);
if (!mWifiManager.isWifiEnabled())
@@ -230,6 +239,10 @@
)
})
public void testWifiManagerActions() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
assertTrue(mWifiManager.reconnect());
assertTrue(mWifiManager.reassociate());
assertTrue(mWifiManager.disconnect());
@@ -278,6 +291,10 @@
)
})
public void testWifiManagerProperties() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
setWifiEnabled(true);
assertTrue(mWifiManager.isWifiEnabled());
assertNotNull(mWifiManager.getDhcpInfo());
@@ -345,6 +362,10 @@
)
})
public void testWifiManagerNetWork() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
// store the list of enabled networks, so they can be re-enabled after test completes
Set<String> enabledSsids = getEnabledNetworks(mWifiManager.getConfiguredNetworks());
try {
@@ -441,6 +462,10 @@
)
})
public void testSignal() {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
final int numLevels = 9;
int expectLevel = 0;
assertEquals(expectLevel, WifiManager.calculateSignalLevel(MIN_RSSI, numLevels));
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java
index 53150c9..c1fc4ba 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManager_WifiLockTest.java
@@ -63,6 +63,10 @@
)
})
public void testWifiLock() {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
WifiLock wl = wm.createWifiLock(WIFI_TAG);
diff --git a/tests/tests/openglperf/Android.mk b/tests/tests/openglperf/Android.mk
new file mode 100644
index 0000000..57e6ec3
--- /dev/null
+++ b/tests/tests/openglperf/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsOpenGlPerfTestCases
+
+LOCAL_INSTRUMENTATION_FOR := com.replica.replicaisland
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tests/tests/openglperf/AndroidManifest.xml b/tests/tests/openglperf/AndroidManifest.xml
new file mode 100644
index 0000000..e47c0bc
--- /dev/null
+++ b/tests/tests/openglperf/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.openglperf"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+ <uses-permission android:name="android.permission.GET_TASKS" />
+ <uses-permission android:name="android.permission.REORDER_TASKS" />
+ <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
+
+ <!-- Two activities are used -->
+ <instrumentation
+ android:targetPackage="com.replica.replicaisland"
+ android:name="android.test.InstrumentationTestRunner" />
+ <instrumentation
+ android:targetPackage="com.android.cts.openglperf"
+ android:name="android.test.InstrumentationTestRunner" />
+
+ <application
+ android:label="@string/app_name" >
+ <uses-library android:name="android.test.runner" />
+ <activity
+ android:name="android.openglperf.cts.GlPlanetsActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity android:name="android.openglperf.cts.TextureTestActivity" />
+ </application>
+
+</manifest>
diff --git a/tests/tests/openglperf/assets/world_512_512.jpg b/tests/tests/openglperf/assets/world_512_512.jpg
new file mode 100644
index 0000000..b92bfae
--- /dev/null
+++ b/tests/tests/openglperf/assets/world_512_512.jpg
Binary files differ
diff --git a/tests/tests/openglperf/res/values/strings.xml b/tests/tests/openglperf/res/values/strings.xml
new file mode 100644
index 0000000..2cdba7f
--- /dev/null
+++ b/tests/tests/openglperf/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+ <string name="app_name">OpenGlPerfTest</string>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/GlAppSwitchTest.java b/tests/tests/openglperf/src/android/openglperf/cts/GlAppSwitchTest.java
new file mode 100644
index 0000000..aa4ca49
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/GlAppSwitchTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.openglperf.cts;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.test.ActivityInstrumentationTestCase2;
+
+import java.util.List;
+
+/**
+ * Tests OpenGl rendering after task switching to other GL-using application
+ * This test needs to control two applications and task switch between them to
+ * force losing and reclaiming GL context
+ */
+public class GlAppSwitchTest extends
+ ActivityInstrumentationTestCase2<GlPlanetsActivity> {
+
+ private static final String REPLICA_ISLAND_PACKAGE = "com.replica.replicaisland";
+ private static final String REPLICA_ISLAND_ACTIVITY = "AndouKun";
+ private static final long TASK_SWITCH_SLOW_WAIT_TIME_MS = 15 * 1000;
+ private static final int NUMBER_OF_TASK_SWITCHES_SLOW = 10;
+ private static final long TASK_SWITCH_FAST_WAIT_TIME_MS = 2000;
+ private static final int NUMBER_OF_TASK_SWITCHES_FAST = 50;
+ private static final String ERROR_REPLICA_ISLAND_DEAD = "replica island not running";
+ private static final int MAX_RUNNING_TASKS = 1000;
+
+ private ActivityManager mActivityManager;
+
+ private int mTaskIdSelf;
+ private int mTaskIdReplica;
+
+ public GlAppSwitchTest() {
+ super(GlPlanetsActivity.class);
+ }
+
+ public void testGlActivitySwitchingFast() throws InterruptedException {
+ runTaskSwitchTest(TASK_SWITCH_FAST_WAIT_TIME_MS, NUMBER_OF_TASK_SWITCHES_FAST);
+ // wait for more time at the last run to allow watch dog timer in replica island to kick
+ Thread.sleep(TASK_SWITCH_SLOW_WAIT_TIME_MS);
+ assertTrue(ERROR_REPLICA_ISLAND_DEAD, isReplicaIslandRunning());
+ }
+
+ public void testGlActivitySwitchingSlow() throws InterruptedException {
+ runTaskSwitchTest(TASK_SWITCH_SLOW_WAIT_TIME_MS, NUMBER_OF_TASK_SWITCHES_SLOW);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ Instrumentation instrument = getInstrumentation();
+ Context context = instrument.getContext();
+
+ mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+
+ Intent intentPlanets = new Intent();
+ intentPlanets.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_FRAMES, 0); //runs forever
+ intentPlanets.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_PLANETS, 4); // max load
+ setActivityIntent(intentPlanets);
+ Activity activity = getActivity();
+ instrument.waitForIdleSync();
+ mTaskIdSelf = activity.getTaskId();
+ // wait further to render some frames
+ Thread.sleep(1000);
+
+ Intent intentIsland = new Intent(Intent.ACTION_MAIN);
+ intentIsland.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intentIsland.addCategory(Intent.CATEGORY_LAUNCHER);
+ intentIsland.setComponent(new ComponentName(REPLICA_ISLAND_PACKAGE,
+ REPLICA_ISLAND_PACKAGE + "." + REPLICA_ISLAND_ACTIVITY));
+ context.startActivity(intentIsland);
+ // wait to render some frames
+ Thread.sleep(5000);
+
+ setReplicaIslandTask();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ showOrHideReplicaIsland(false);
+ super.tearDown();
+ }
+
+ /**
+ * run foreground / background task switching between replica island and GlPlanetsActivity.
+ * @param waitTimeMs time to wait after each task switching
+ * @param numberOfSwitches number of task switches to run
+ * @throws InterruptedException
+ */
+ private void runTaskSwitchTest(long waitTimeMs, int numberOfSwitches)
+ throws InterruptedException {
+ boolean replicaForeground = false;
+ assertTrue(ERROR_REPLICA_ISLAND_DEAD, isReplicaIslandRunning());
+ for (int i = 0; i < numberOfSwitches; i++ ) {
+ showOrHideReplicaIsland(replicaForeground);
+ replicaForeground = !replicaForeground;
+ Thread.sleep(waitTimeMs);
+ assertTrue(ERROR_REPLICA_ISLAND_DEAD, isReplicaIslandRunning());
+ }
+ }
+
+ private void setReplicaIslandTask() {
+ boolean foundReplica = false;
+ List<ActivityManager.RunningTaskInfo> tasks =
+ mActivityManager.getRunningTasks(MAX_RUNNING_TASKS);
+ for (ActivityManager.RunningTaskInfo info : tasks) {
+ String packageName = info.baseActivity.getPackageName();
+ if (packageName.contentEquals(REPLICA_ISLAND_PACKAGE)) {
+ foundReplica = true;
+ mTaskIdReplica = info.id;
+ break;
+ }
+ }
+ assertTrue("cannot find replica island running", foundReplica);
+ }
+
+ private boolean isReplicaIslandRunning() {
+ boolean foundReplica = false;
+ List<ActivityManager.RunningTaskInfo> tasks =
+ mActivityManager.getRunningTasks(MAX_RUNNING_TASKS);
+ for (ActivityManager.RunningTaskInfo info : tasks) {
+ String packageName = info.baseActivity.getPackageName();
+ if (packageName.contentEquals(REPLICA_ISLAND_PACKAGE)) {
+ foundReplica = true;
+ break;
+ }
+ }
+ return foundReplica;
+ }
+
+ /**
+ * send replica island to foreground (when show = true) or background
+ * requires both replica island and GlPlanetsActivity to be alive.
+ * @param show
+ */
+ private void showOrHideReplicaIsland(boolean show) {
+ mActivityManager.moveTaskToFront(show ? mTaskIdReplica : mTaskIdSelf, 0);
+ }
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/GlPlanetsActivity.java b/tests/tests/openglperf/src/android/openglperf/cts/GlPlanetsActivity.java
new file mode 100644
index 0000000..5a8c0a8
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/GlPlanetsActivity.java
@@ -0,0 +1,97 @@
+/*
+ * 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.openglperf.cts;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Activity which runs GL test and measure FPS with given parameters passed from
+ * Intent. For the meaning of parameters, check {@PlanetsRenderingParam}
+ */
+public class GlPlanetsActivity extends Activity implements
+ RenderCompletionListener {
+ public static final String INTENT_EXTRA_NUM_PLANETS = "numPlanets";
+ public static final String INTENT_EXTRA_USE_VBO_VERTICES = "useVboVertices";
+ public static final String INTENT_EXTRA_USE_VBO_INDICES = "useVboIndiices";
+ public static final String INTENT_EXTRA_NUM_FRAMES = "numFrames";
+ public static final String INTENT_EXTRA_INDICES_PER_VERTEX = "numIndicesPerVertex";
+
+ public static final String INTENT_RESULT_FPS = "fps";
+ public static final String INTENT_RESULT_NUM_TRIANGLES = "numTrigngles";
+
+ private final Semaphore mSem = new Semaphore(0);
+ private float mFps;
+ private int mNumTriangles;
+
+ private PlanetsSurfaceView mView;
+
+ public boolean waitForGlPlanetsCompletionWithTimeout(long timeoutInSecs)
+ throws InterruptedException {
+ return mSem.tryAcquire(timeoutInSecs, TimeUnit.SECONDS);
+ }
+
+ public float getFps() {
+ return mFps;
+ }
+
+ public int getNumTriangles() {
+ return mNumTriangles;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ Intent intent = getIntent();
+ PlanetsRenderingParam param = new PlanetsRenderingParam();
+ param.mNumPlanets = intent.getIntExtra(INTENT_EXTRA_NUM_PLANETS, param.mNumPlanets);
+ param.mUseVboForVertices = intent.getBooleanExtra(INTENT_EXTRA_USE_VBO_VERTICES,
+ param.mUseVboForVertices);
+ param.mUseVboForIndices = intent.getBooleanExtra(INTENT_EXTRA_USE_VBO_INDICES,
+ param.mUseVboForIndices);
+ param.mNumFrames = intent.getIntExtra(INTENT_EXTRA_NUM_FRAMES, param.mNumFrames);
+ param.mNumIndicesPerVertex = intent.getIntExtra(INTENT_EXTRA_INDICES_PER_VERTEX,
+ param.mNumIndicesPerVertex);
+ mView = new PlanetsSurfaceView(this, param, this);
+ setContentView(mView);
+ }
+
+ @Override
+ public void onRenderCompletion(float fps, int numTriangles) {
+ mFps = fps;
+ mNumTriangles = numTriangles;
+ mSem.release();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/GlTextureCoordTest.java b/tests/tests/openglperf/src/android/openglperf/cts/GlTextureCoordTest.java
new file mode 100644
index 0000000..6a0a14e
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/GlTextureCoordTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.openglperf.cts;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+/**
+ * check TextureTestRenderer for details
+ */
+public class GlTextureCoordTest extends
+ ActivityInstrumentationTestCase2<TextureTestActivity> {
+
+ public GlTextureCoordTest() {
+ super(TextureTestActivity.class);
+ }
+
+ public void testTextureCoord() throws InterruptedException {
+ getActivity();
+ Thread.sleep(3000); // give some time to render some frames
+ }
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/GlVboPerfTest.java b/tests/tests/openglperf/src/android/openglperf/cts/GlVboPerfTest.java
new file mode 100644
index 0000000..afd435c
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/GlVboPerfTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.openglperf.cts;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+public class GlVboPerfTest extends
+ ActivityInstrumentationTestCase2<GlPlanetsActivity> {
+ private static final String TAG = "GlVboPerfTest";
+ private static final int NUM_FRAMES_TO_RENDER = 100;
+ private static final long RENDERING_TIMEOUT = 5 * 60;
+ // 10% of fps_no_vbo is allowed to compensate variations in measurement
+ private static final float FPS_COMPARISON_MARGIN = 0.1f;
+ // the worst case should be above 70% of the best case
+ private static final float FPS_MIN_MAX_COMPARISON_PERCENTILE = 0.7f;
+
+ private float mFps;
+ private int mNumTriangles;
+
+ public GlVboPerfTest() {
+ super(GlPlanetsActivity.class);
+ }
+
+ public void testVboWithVaryingIndexBufferNumbers() throws Exception {
+ final int[] numIndexBuffers = {1, 10, 100, 200, 400}; // per vertex buffer
+ float[] fpsVbo = new float[numIndexBuffers.length];
+ float[] fpsNonVbo = new float[numIndexBuffers.length];
+
+ for (int i = 0; i < numIndexBuffers.length; i++) {
+ runRendering(0, true, true, numIndexBuffers[i]);
+ fpsVbo[i] = mFps;
+ runRendering(0, true, false, numIndexBuffers[i]);
+ fpsNonVbo[i] = mFps;
+ }
+ StringBuilder msgIndex = new StringBuilder();
+ StringBuilder msgVbo = new StringBuilder();
+ StringBuilder msgNonVbo = new StringBuilder();
+ msgIndex.append("index buffer ");
+ msgVbo.append("Vbo ");
+ msgNonVbo.append("Non-Vbo ");
+ for (int i = 0; i < numIndexBuffers.length; i++) {
+ msgIndex.append(numIndexBuffers[i]).append(" ");
+ msgVbo.append(fpsVbo[i]).append(" ");
+ msgNonVbo.append(fpsNonVbo[i]).append(" ");
+ }
+ Log.i(TAG, msgIndex.toString());
+ Log.i(TAG, msgVbo.toString());
+ Log.i(TAG, msgNonVbo.toString());
+
+ float[] minMaxVbo = findMinMax(fpsVbo);
+ float[] minMaxNonVbo = findMinMax(fpsNonVbo);
+
+ float delta = minMaxVbo[1] - (1f - FPS_COMPARISON_MARGIN)
+ * minMaxNonVbo[1];
+ assertTrue("VBO performance worse than non-VBO " + msgVbo + msgNonVbo, delta > 0f);
+ assertTrue(
+ "Too much FPS drop for VBO case " + msgVbo,
+ minMaxVbo[0] > (FPS_MIN_MAX_COMPARISON_PERCENTILE * minMaxVbo[1]));
+ assertTrue(
+ "Too much FPS drop for No VBO case " + msgNonVbo,
+ minMaxNonVbo[0] > (FPS_MIN_MAX_COMPARISON_PERCENTILE * minMaxNonVbo[1]));
+ }
+
+ public void testVboVsNonVboPerfGeometry0() throws Exception {
+ doRunVboVsNonVboPerfTest(0);
+ }
+
+ public void testVboVsNonVboPerfGeometry1() throws Exception {
+ doRunVboVsNonVboPerfTest(4);
+ }
+
+ private void runRendering(int numPlanets, boolean useVboVertex, boolean useVboIndex,
+ int indicesPerVertex) throws Exception {
+ Intent intent = new Intent();
+ intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_FRAMES,
+ NUM_FRAMES_TO_RENDER);
+ intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_PLANETS, numPlanets);
+ intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_USE_VBO_VERTICES, useVboVertex);
+ intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_USE_VBO_INDICES, useVboIndex);
+ intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_INDICES_PER_VERTEX, indicesPerVertex);
+
+ setActivityIntent(intent);
+ final GlPlanetsActivity activity = getActivity();
+ boolean waitResult = activity
+ .waitForGlPlanetsCompletionWithTimeout(RENDERING_TIMEOUT);
+ assertTrue("timeout while waiting for rendering completion", waitResult);
+
+ mFps = activity.getFps();
+ mNumTriangles = activity.getNumTriangles();
+
+ cleanUpActivity();
+ }
+
+ private void cleanUpActivity() throws Exception {
+ // finish the current activity and do clean-up so that a new activity
+ // can be launched in the same test run
+ super.tearDown();
+ super.setUp();
+ // wait until clean-up / set-up finishes
+ getInstrumentation().waitForIdleSync();
+ }
+
+ private void doRunVboVsNonVboPerfTest(int numPlanets) throws Exception {
+ runRendering(numPlanets, true, true, 1); // VBO
+ int numTrianglesVbo = mNumTriangles;
+ float fpsVbo = mFps;
+ runRendering(numPlanets, false, false, 1); // non-VBO
+
+ assertTrue("Number of triangles mismatch",
+ numTrianglesVbo == mNumTriangles);
+
+ // Margin amount of error is allowed due to measuring irregularity
+ float delta = fpsVbo - (1f - FPS_COMPARISON_MARGIN) * mFps;
+ StringBuilder testMsg = new StringBuilder();
+ testMsg.append("VBO performance worse than non-VBO ").append(fpsVbo).append(" ");
+ testMsg.append(mFps);
+ assertTrue(testMsg.toString(), delta > 0f);
+ }
+
+ private float[] findMinMax(float[] data) {
+ float min = data[0];
+ float max = data[0];
+
+ for (int i = 1; i < data.length; i++) {
+ if (data[i] > max) max = data[i];
+ if (data[i] < min) min = data[i];
+ }
+ float[] result = {min, max};
+ return result;
+ }
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderer.java b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderer.java
new file mode 100644
index 0000000..5b90089
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderer.java
@@ -0,0 +1,429 @@
+/*
+ * 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.openglperf.cts;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLUtils;
+import android.opengl.Matrix;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.System;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+
+public class PlanetsRenderer implements GLSurfaceView.Renderer {
+
+ private static final String TAG = "PlanetsRenderer";
+ // texture is from
+ // http://en.wikipedia.org/wiki/File:Mercator_projection_SW.jpg
+ private static final String TEXTURE_FILE = "world_512_512.jpg";
+
+ private final Context mContext;
+ private final PlanetsRenderingParam mParam;
+ private final RenderCompletionListener mListener;
+ private final RenderingWatchDog mWatchDog;
+
+ private final Sphere[] mSpheres;
+ private final int mNumSpheres;
+ private final int mNumIndices;
+ private final int mVboVertices[];
+ private final int mVboIndices[];
+
+ // configurations for sun and planets
+ private static final int SPHERE_SLICES = 180;
+ private static final float RADIUS_SUN = 0.4f;
+ private static final float RADIUS_PLANET = 0.08f;
+ private static final float RADIUS_ORBIT = 0.9f;
+
+ private int mWidth;
+ private int mHeight;
+
+ private int mFrameCount = 0;
+ private static final int FPS_DISPLAY_INTERVAL = 50;
+ private long mLastFPSTime;
+ // for total FPS measurement
+ private long mRenderingStartTime;
+ private long mMeasurementStartTime;
+
+ private int mProgram; // shader program
+ private int mMVPMatrixHandle;
+ private float[] mMVPMatrix = new float[16];
+ private float[] mMMatrix = new float[16];
+ private float[] mVMatrix = new float[16];
+ private float[] mProjMatrix = new float[16];
+
+ private int mOffsetHandle;
+ private static final float[] mDefaultOffset = { 0f, 0f, 0f, 1f };
+ private int mPositionHandle;
+ private int mTexCoord0Handle;
+ private int mTextureHandle;
+ private int mTextureId;
+
+ /**
+ * @param numSlices
+ * complexity of sphere used. A sphere will have (numSlices + 1)
+ * x (numSlices x 1) much of vertices
+ * @param useVbo
+ * whether to use Vertex Buffer Object in rendering or not
+ * @param framesToGo
+ * number of frames to render before calling completion to
+ * listener
+ * @param listener
+ */
+ public PlanetsRenderer(Context context, PlanetsRenderingParam param,
+ RenderCompletionListener listener, RenderingWatchDog watchDog) {
+ resetTimer();
+ mContext = context;
+ mParam = param;
+ mWatchDog = watchDog;
+ mNumSpheres = mParam.mNumPlanets + 1; // 1 for sun
+ mNumIndices = mNumSpheres * mParam.mNumIndicesPerVertex;
+ mSpheres = new Sphere[mNumSpheres];
+
+ printParams();
+
+ // for big model, this construction phase takes time...
+ mSpheres[0] = new Sphere(SPHERE_SLICES, 0f, 0f, 0f, RADIUS_SUN,
+ mParam.mNumIndicesPerVertex);
+ for (int i = 1; i < mNumSpheres; i++) {
+ mSpheres[i] = new Sphere(SPHERE_SLICES,
+ RADIUS_ORBIT * (float) Math.sin(((float) i) / (mNumSpheres - 1) * 2 * Math.PI),
+ RADIUS_ORBIT * (float) Math.cos(((float) i) / (mNumSpheres - 1) * 2 * Math.PI),
+ 0f, RADIUS_PLANET, mParam.mNumIndicesPerVertex);
+ }
+ mVboVertices = new int[mNumSpheres];
+ mVboIndices = new int[mNumIndices];
+ mListener = listener;
+ measureTime("construction");
+ }
+
+ public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
+ mProgram = createProgram(getVertexShader(), getFragmentShader());
+ if (mProgram == 0) {
+ // error, cannot proceed
+ throw new IllegalStateException("createProgram failed");
+ }
+ mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
+ mOffsetHandle = GLES20.glGetUniformLocation(mProgram, "uOffset");
+ mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
+ mTexCoord0Handle = GLES20.glGetAttribLocation(mProgram, "vTexCoord0");
+ mTextureHandle = GLES20.glGetUniformLocation(mProgram, "sTexture");
+
+ // Load the texture
+ mTextureId = createTexture2D();
+ }
+
+ public void onDrawFrame(GL10 glUnused) {
+ mWatchDog.reset();
+ long currentTime = System.currentTimeMillis();
+
+ mFrameCount++;
+ if ((mFrameCount % FPS_DISPLAY_INTERVAL == 0) && (mFrameCount != 0)) {
+ float fps = (((float) FPS_DISPLAY_INTERVAL)
+ / ((float) (currentTime - mLastFPSTime)) * 1000.0f);
+ // FPS is not correct if activity is paused/resumed.
+ Log.i(TAG, "FPS " + fps);
+ mLastFPSTime = currentTime;
+ }
+
+ if ((mFrameCount == mParam.mNumFrames) && (mParam.mNumFrames > 0)) {
+ long timePassed = currentTime - mRenderingStartTime;
+ float fps = ((float) mParam.mNumFrames) / ((float) timePassed) * 1000.0f;
+ printGlInfos();
+ printParams();
+ int numTriangles = mNumSpheres * mSpheres[0].getTotalIndices() / 3;
+ Log.i(TAG, "Final FPS " + fps + " Num triangles " + numTriangles);
+ if (mListener != null) {
+ mListener.onRenderCompletion(fps, numTriangles);
+ return;
+ }
+ }
+
+ float angle = 0.090f * ((int) (currentTime % 4000L));
+ Matrix.setRotateM(mMMatrix, 0, angle, 0, 0, 1.0f);
+ Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
+ Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
+
+ GLES20.glUseProgram(mProgram);
+ GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
+
+ // Apply a ModelView Projection transformation
+ GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
+ GLES20.glUniform4f(mOffsetHandle, mDefaultOffset[0], mDefaultOffset[1],
+ mDefaultOffset[2], mDefaultOffset[3]);
+
+ GLES20.glEnableVertexAttribArray(mPositionHandle);
+ GLES20.glEnableVertexAttribArray(mTexCoord0Handle);
+
+ // Bind the texture
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureId);
+ // Set the sampler texture unit to 0
+ GLES20.glUniform1i(mTextureHandle, 0);
+
+ for (int i = 0; i < mNumSpheres; i++) {
+ if (mParam.mUseVboForVertices) {
+ // generating VBOs for each sphere is not efficient way for drawing
+ // multiple spheres
+ // But this is done for testing performance with big VBO buffers.
+ // So please do not copy this code as it is.
+ GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVboVertices[i]);
+ // Load the vertex position
+ GLES20.glVertexAttribPointer(mPositionHandle, 3,
+ GLES20.GL_FLOAT, false, mSpheres[i].getVeticesStride(),
+ 0);
+ // Load the texture coordinate
+ GLES20.glVertexAttribPointer(mTexCoord0Handle, 3,
+ GLES20.GL_FLOAT, false, mSpheres[i].getVeticesStride(),
+ 3 * Sphere.FLOAT_SIZE);
+ } else {
+ // Load the vertex position
+ GLES20.glVertexAttribPointer(mPositionHandle, 3,
+ GLES20.GL_FLOAT, false, mSpheres[i].getVeticesStride(),
+ mSpheres[i].getVertices());
+ // Load the texture coordinate
+ GLES20.glVertexAttribPointer(mTexCoord0Handle, 3,
+ GLES20.GL_FLOAT, false, mSpheres[i].getVeticesStride(),
+ mSpheres[i].getVertices().duplicate().position(3));
+ }
+ int[] numIndices = mSpheres[i].getNumIndices();
+ ShortBuffer[] indices = mSpheres[i].getIndices();
+ if (mParam.mUseVboForIndices) {
+ int indexVboBase = i * mParam.mNumIndicesPerVertex;
+ for (int j = 0; j < numIndices.length; j++) {
+ GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER,
+ mVboIndices[indexVboBase + j]);
+ GLES20.glDrawElements(GLES20.GL_TRIANGLES,
+ numIndices[j], GLES20.GL_UNSIGNED_SHORT,
+ 0);
+ }
+ } else {
+ for (int j = 0; j < numIndices.length; j++) {
+ GLES20.glDrawElements(GLES20.GL_TRIANGLES,
+ numIndices[j], GLES20.GL_UNSIGNED_SHORT,
+ indices[j]);
+ }
+ }
+ }
+ }
+
+ public void onSurfaceChanged(GL10 glUnused, int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ GLES20.glViewport(0, 0, width, height);
+ float ratio = (float) width / height;
+ Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
+ Matrix.setLookAtM(mVMatrix, 0, 0, 3, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+ createVbo();
+
+ // reset timer to remove delays added for FPS calculation.
+ mLastFPSTime = System.currentTimeMillis();
+ mRenderingStartTime = System.currentTimeMillis();
+ }
+
+ protected final String getVertexShader() {
+ // simple shader with MVP matrix and text coord
+ final String vShaderStr =
+ "uniform mat4 uMVPMatrix; \n"
+ + "uniform vec4 uOffset; \n"
+ + "attribute vec4 vPosition; \n"
+ + "attribute vec2 vTexCoord0; \n"
+ + "varying vec2 vTexCoord; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_Position = uMVPMatrix * (vPosition + uOffset); \n"
+ + " vTexCoord = vTexCoord0; \n"
+ + "} \n";
+ return vShaderStr;
+ }
+
+ protected final String getFragmentShader() {
+ // simple shader with one texture for color
+ final String fShaderStr =
+ "precision mediump float; \n"
+ + "varying vec2 vTexCoord; \n"
+ + "uniform sampler2D sTexture; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_FragColor = texture2D( sTexture, vTexCoord );\n"
+ + "} \n";
+ return fShaderStr;
+ }
+
+ private int loadShader(int shaderType, String source) {
+ int shader = GLES20.glCreateShader(shaderType);
+ if (shader != 0) {
+ GLES20.glShaderSource(shader, source);
+ GLES20.glCompileShader(shader);
+ int[] compiled = new int[1];
+ GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
+ if (compiled[0] == 0) {
+ Log.e(TAG, "Could not compile shader " + shaderType + ":");
+ Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
+ GLES20.glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ return shader;
+ }
+
+ private int createProgram(String vertexSource, String fragmentSource) {
+ int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
+ if (vertexShader == 0) {
+ return 0;
+ }
+
+ int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
+ if (pixelShader == 0) {
+ return 0;
+ }
+
+ int program = GLES20.glCreateProgram();
+ if (program != 0) {
+ GLES20.glAttachShader(program, vertexShader);
+ checkGlError("glAttachShader");
+ GLES20.glAttachShader(program, pixelShader);
+ checkGlError("glAttachShader");
+ GLES20.glLinkProgram(program);
+ int[] linkStatus = new int[1];
+ GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
+ if (linkStatus[0] != GLES20.GL_TRUE) {
+ Log.e(TAG, "Could not link program: ");
+ Log.e(TAG, GLES20.glGetProgramInfoLog(program));
+ GLES20.glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ return program;
+ }
+
+ private int createTexture2D() {
+ // Texture object handle
+ int[] textureId = new int[1];
+
+ InputStream in = null;
+ try {
+ in = mContext.getAssets().open(TEXTURE_FILE);
+ Bitmap bitmap = BitmapFactory.decodeStream(in);
+
+ // Generate a texture object
+ GLES20.glGenTextures(1, textureId, 0);
+
+ // Bind the texture object
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId[0]);
+ GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
+
+ // Set the filtering mode
+ GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
+ GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
+ GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
+ GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
+
+ } catch (IOException e) {
+ throw new IllegalStateException("Couldn't load texture '" + TEXTURE_FILE
+ + "'", e);
+ } finally {
+ if (in != null)
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+
+ return textureId[0];
+ }
+
+ private void checkGlError(String op) {
+ int error;
+ while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+ Log.e(TAG, op + ": glError " + error);
+ throw new IllegalStateException(op + ": glError " + error);
+ }
+ }
+
+ private void createVbo() {
+ resetTimer();
+ if (mParam.mUseVboForVertices) {
+ GLES20.glGenBuffers(mNumSpheres, mVboVertices, 0);
+ checkGlError("glGenBuffers Vertex");
+ for (int i = 0; i < mNumSpheres; i++) {
+ GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVboVertices[i]);
+ checkGlError("glBindBuffer Vertex");
+ FloatBuffer vertices = mSpheres[i].getVertices();
+ GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertices.limit()
+ * Sphere.FLOAT_SIZE, vertices, GLES20.GL_STATIC_DRAW);
+ checkGlError("glBufferData Vertex");
+ }
+ }
+ if (mParam.mUseVboForIndices) {
+ GLES20.glGenBuffers(mNumIndices, mVboIndices, 0);
+ checkGlError("glGenBuffers Index");
+ for (int i = 0; i < mNumSpheres; i++) {
+ int[] numIndices = mSpheres[i].getNumIndices();
+ ShortBuffer[] indices = mSpheres[i].getIndices();
+ int indexVboBase = i * mParam.mNumIndicesPerVertex;
+ for (int j = 0; j < numIndices.length; j++) {
+ GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER,
+ mVboIndices[indexVboBase + j]);
+ GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER,
+ indices[j].limit() * Sphere.SHORT_SIZE, indices[j],
+ GLES20.GL_STATIC_DRAW);
+ checkGlError("glBufferData Index");
+
+ }
+ }
+ }
+ GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
+ GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
+ measureTime("VBO creation");
+ }
+
+ private void resetTimer() {
+ mMeasurementStartTime = System.currentTimeMillis();
+ }
+
+ private void measureTime(String description) {
+ long currentTime = System.currentTimeMillis();
+ float timePassedInSecs = (float) (currentTime - mMeasurementStartTime) / 1000f;
+ Log.i(TAG, description + " time in secs: " + timePassedInSecs);
+ }
+
+ private void printGlInfos() {
+ Log.i(TAG, "Vendor " + GLES20.glGetString(GLES20.GL_VENDOR));
+ Log.i(TAG, "Version " + GLES20.glGetString(GLES20.GL_VERSION));
+ Log.i(TAG, "Renderer " + GLES20.glGetString(GLES20.GL_RENDERER));
+ Log.i(TAG, "Extensions " + GLES20.glGetString(GLES20.GL_EXTENSIONS));
+ }
+ private void printParams() {
+ Log.i(TAG, "UseVboForVertex " + mParam.mUseVboForVertices);
+ Log.i(TAG, "UseVboForIndex " + mParam.mUseVboForIndices);
+ Log.i(TAG, "No Spheres " + mNumSpheres);
+ Log.i(TAG, "No indices buffer per vertex " + mParam.mNumIndicesPerVertex);
+ }
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderingParam.java b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderingParam.java
new file mode 100644
index 0000000..5e2dfd0
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsRenderingParam.java
@@ -0,0 +1,30 @@
+/*
+ * 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.openglperf.cts;
+
+public class PlanetsRenderingParam {
+ /** whether to use VBO for vertices data */
+ public boolean mUseVboForVertices = true;
+ /** whether to use VBO for indices data */
+ public boolean mUseVboForIndices = true;
+ /** number of indices buffer per one vertices buffer */
+ public int mNumIndicesPerVertex = 1;
+ /** number of planets to render. There is always a sun */
+ public int mNumPlanets = 0;
+ /** number of frames to render to calculate FPS and finish */
+ public int mNumFrames = 100;
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/PlanetsSurfaceView.java b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsSurfaceView.java
new file mode 100644
index 0000000..2bfd001
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/PlanetsSurfaceView.java
@@ -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.
+ */
+
+package android.openglperf.cts;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+
+class PlanetsSurfaceView extends GLSurfaceView {
+ private final long RENDERING_TIMEOUT = 1900; // in msec, close to 2 secs
+ private final RenderingWatchDog mWatchDog = new RenderingWatchDog(RENDERING_TIMEOUT);
+
+ public PlanetsSurfaceView(Context context, PlanetsRenderingParam param,
+ RenderCompletionListener listener) {
+ super(context);
+
+ setEGLContextClientVersion(2);
+ setRenderer(new PlanetsRenderer(context, param, listener, mWatchDog));
+ }
+
+ @Override
+ public void onPause() {
+ mWatchDog.stop();
+ super.onPause();
+ setRenderMode(RENDERMODE_WHEN_DIRTY);
+ }
+
+ @Override
+ public void onResume() {
+ mWatchDog.start();
+ setRenderMode(RENDERMODE_CONTINUOUSLY);
+ super.onResume();
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/RenderCompletionListener.java b/tests/tests/openglperf/src/android/openglperf/cts/RenderCompletionListener.java
new file mode 100644
index 0000000..1643087
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/RenderCompletionListener.java
@@ -0,0 +1,26 @@
+/*
+ * 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.openglperf.cts;
+
+public interface RenderCompletionListener {
+ /**
+ * @param fps total frame rate
+ * @param numTriangles Number of triangles in geometric model
+ */
+ void onRenderCompletion(float fps, int numTriangles);
+
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/RenderingWatchDog.java b/tests/tests/openglperf/src/android/openglperf/cts/RenderingWatchDog.java
new file mode 100644
index 0000000..4872af2
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/RenderingWatchDog.java
@@ -0,0 +1,85 @@
+/*
+ * 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.openglperf.cts;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import android.util.Log;
+
+import junit.framework.Assert;
+
+/**
+ * class for checking if rendering function is alive or not.
+ * panic if watch-dog is not reset over certain amount of time
+ */
+public class RenderingWatchDog implements Runnable {
+ private static final String TAG = "RenderingWatchDog";
+ private Thread mThread;
+ private Semaphore mSemaphore;
+ private volatile boolean mStopRequested;
+ private final long mTimeoutInMilliSecs;
+
+ public RenderingWatchDog(long timeoutInMilliSecs) {
+ mTimeoutInMilliSecs = timeoutInMilliSecs;
+ }
+
+ /** start watch-dog */
+ public void start() {
+ Log.i(TAG, "start");
+ mStopRequested = false;
+ mSemaphore = new Semaphore(0);
+ mThread = new Thread(this);
+ mThread.start();
+ }
+
+ /** stop watch-dog */
+ public void stop() {
+ Log.i(TAG, "stop");
+ if (mThread == null) {
+ return; // already finished
+ }
+ mStopRequested = true;
+ mSemaphore.release();
+ try {
+ mThread.join();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ mThread = null;
+ mSemaphore = null;
+ }
+
+ /** resets watch-dog, thus prevent it from panic */
+ public void reset() {
+ if (!mStopRequested) { // stop requested, but rendering still on-going
+ mSemaphore.release();
+ }
+ }
+
+ @Override
+ public void run() {
+ while (!mStopRequested) {
+ try {
+ Assert.assertTrue("Watchdog timed-out",
+ mSemaphore.tryAcquire(mTimeoutInMilliSecs, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {
+ // this thread will not be interrupted,
+ // but if it happens, just check the exit condition.
+ }
+ }
+ }
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/Sphere.java b/tests/tests/openglperf/src/android/openglperf/cts/Sphere.java
new file mode 100644
index 0000000..026ba97
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/Sphere.java
@@ -0,0 +1,159 @@
+/*
+ * 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.openglperf.cts;
+
+import java.lang.Math;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+/*
+ * Class for generating a sphere model for given input params
+ * The generated class will have vertices and indices
+ * Vertices data is composed of vertex coordinates in x, y, z followed by
+ * texture coordinates s, t for each vertex
+ * Indices store vertex indices for the whole sphere.
+ * Formula for generating sphere is originally coming from source code of
+ * OpenGL ES2.0 Programming guide
+ * which is available from http://code.google.com/p/opengles-book-samples/,
+ * but some changes were made to make texture look right.
+ */
+public class Sphere {
+ public static final int FLOAT_SIZE = 4;
+ public static final int SHORT_SIZE = 2;
+
+ private FloatBuffer mVertices;
+ private ShortBuffer[] mIndices;
+ private int[] mNumIndices;
+ private int mTotalIndices;
+
+ /*
+ * @param nSlices how many slice in horizontal direction.
+ * The same slice for vertical direction is applied.
+ * nSlices should be > 1 and should be <= 180
+ * @param x,y,z the origin of the sphere
+ * @param r the radius of the sphere
+ */
+ public Sphere(int nSlices, float x, float y, float z, float r, int indicesPerVertex) {
+
+ int iMax = nSlices + 1;
+ int nVertices = iMax * iMax;
+ if (nVertices > Short.MAX_VALUE) {
+ // this cannot be handled in one vertices / indices pair
+ throw new RuntimeException("nSlices " + nSlices + " too big for vertex");
+ }
+ mTotalIndices = nSlices * nSlices * 6;
+ float angleStepI = ((float) Math.PI / nSlices);
+ float angleStepJ = ((2.0f * (float) Math.PI) / nSlices);
+
+ // 3 vertex coords + 2 texture coords
+ mVertices = ByteBuffer.allocateDirect(nVertices * 5 * FLOAT_SIZE)
+ .order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mIndices = new ShortBuffer[indicesPerVertex];
+ mNumIndices = new int[indicesPerVertex];
+ // first evenly distribute to n-1 buffers, then put remaining ones to the last one.
+ int noIndicesPerBuffer = (mTotalIndices / indicesPerVertex / 6) * 6;
+ for (int i = 0; i < indicesPerVertex - 1; i++) {
+ mNumIndices[i] = noIndicesPerBuffer;
+ }
+ mNumIndices[indicesPerVertex - 1] = mTotalIndices - noIndicesPerBuffer *
+ (indicesPerVertex - 1);
+
+ for (int i = 0; i < indicesPerVertex; i++) {
+ mIndices[i] = ByteBuffer.allocateDirect(mNumIndices[i] * SHORT_SIZE)
+ .order(ByteOrder.nativeOrder()).asShortBuffer();
+ }
+ // calling put for each float took too much CPU time, so put by line instead
+ float[] vLineBuffer = new float[iMax * 5];
+ for (int i = 0; i < iMax; i++) {
+ for (int j = 0; j < iMax; j++) {
+ int vertexBase = j * 5;
+ float sini = (float) Math.sin(angleStepI * i);
+ float sinj = (float) Math.sin(angleStepJ * j);
+ float cosi = (float) Math.cos(angleStepI * i);
+ float cosj = (float) Math.cos(angleStepJ * j);
+ // vertex x,y,z
+ vLineBuffer[vertexBase + 0] = x + r * sini * sinj;
+ vLineBuffer[vertexBase + 1] = y + r * sini * cosj;
+ vLineBuffer[vertexBase + 2] = z + r * cosi;
+ // texture s,t
+ vLineBuffer[vertexBase + 3] = (float) j / (float) nSlices;
+ vLineBuffer[vertexBase + 4] = (1.0f - i) / (float)nSlices;
+ }
+ mVertices.put(vLineBuffer, 0, vLineBuffer.length);
+ }
+
+ short[] indexBuffer = new short[max(mNumIndices)];
+ int index = 0;
+ int bufferNum = 0;
+ for (int i = 0; i < nSlices; i++) {
+ for (int j = 0; j < nSlices; j++) {
+ int i1 = i + 1;
+ int j1 = j + 1;
+ if (index >= mNumIndices[bufferNum]) {
+ // buffer ready for moving to target
+ mIndices[bufferNum].put(indexBuffer, 0, mNumIndices[bufferNum]);
+ // move to the next one
+ index = 0;
+ bufferNum++;
+ }
+ indexBuffer[index++] = (short) (i * iMax + j);
+ indexBuffer[index++] = (short) (i1 * iMax + j);
+ indexBuffer[index++] = (short) (i1 * iMax + j1);
+ indexBuffer[index++] = (short) (i * iMax + j);
+ indexBuffer[index++] = (short) (i1 * iMax + j1);
+ indexBuffer[index++] = (short) (i * iMax + j1);
+ }
+ }
+ mIndices[bufferNum].put(indexBuffer, 0, mNumIndices[bufferNum]);
+
+ mVertices.position(0);
+ for (int i = 0; i < indicesPerVertex; i++) {
+ mIndices[i].position(0);
+ }
+ }
+
+ public FloatBuffer getVertices() {
+ return mVertices;
+ }
+
+ public int getVeticesStride() {
+ return 5*FLOAT_SIZE;
+ }
+
+ public ShortBuffer[] getIndices() {
+ return mIndices;
+ }
+
+ public int[] getNumIndices() {
+ return mNumIndices;
+ }
+
+ public int getTotalIndices() {
+ return mTotalIndices;
+ }
+
+
+ private int max(int[] array) {
+ int max = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] > max) max = array[i];
+ }
+ return max;
+ }
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/TextureTestActivity.java b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestActivity.java
new file mode 100644
index 0000000..4d7d641
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestActivity.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.openglperf.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+public class TextureTestActivity extends Activity {
+ private GLSurfaceView mGLView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mGLView = new TextureTestSurfaceView(this);
+ setContentView(mGLView);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mGLView.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mGLView.onResume();
+ }
+}
+
+class TextureTestSurfaceView extends GLSurfaceView {
+
+ public TextureTestSurfaceView(Context context){
+ super(context);
+ setRenderer(new TextureTestRenderer());
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/TextureTestRenderer.java b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestRenderer.java
new file mode 100644
index 0000000..96b2e44
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestRenderer.java
@@ -0,0 +1,184 @@
+/*
+ * 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.openglperf.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.opengl.GLUtils;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+
+import junit.framework.Assert;
+
+/**
+ * This test is for checking an issue
+ * mentioned in https://groups.google.com/group/android-developers/browse_thread/thread/
+ * 9c0ccb1a215586a8/2f28259213340eab?hl=en&lnk=gst&q=opengl+galaxy#2f28259213340eab
+ * The GPU driver seems to change texture coordinates inside glDrawTexfOES, and
+ * texture inside following drawing does not work as expected.
+ * The thread also mentions texture malfunctioning with rotation,
+ * but that was not observed, but the case will cover both.
+ */
+public class TextureTestRenderer implements GLSurfaceView.Renderer {
+ private static final String TAG = "TextureTest";
+ private static final float[] mVerticesData = {
+ // X, Y, Z, s, t
+ -1.0f, -1.0f, 0, 0.6f, 0.f,
+ 1.0f, -1.0f, 0, 0.7f, 0.f,
+ -1.0f, 1.0f, 0, 0.6f, 0.1f,
+ 1.0f, 1.0f, 0, 0.7f, 0.1f,
+ };
+ private static final int FLOAT_SIZE_BYTES = 4;
+ private static final int GEOMETRY_STRIDE = 20;
+
+ private final FloatBuffer mVertices;
+ private final Bitmap mBitmap;
+ private int mTextureID;
+ private boolean mOesDrawTextureSupported = false;
+ private int mWidth;
+ private int mHeight;
+ private float mRotationAngle = 0f;
+
+ public TextureTestRenderer() {
+ mVertices = ByteBuffer.allocateDirect(mVerticesData.length
+ * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mVertices.put(mVerticesData).position(0);
+ // 4x4 texture with 4 colors
+ int[] colors = {
+ Color.RED, Color.RED, Color.BLUE, Color.BLUE,
+ Color.RED, Color.RED, Color.BLUE, Color.BLUE,
+ Color.GREEN, Color.GREEN, Color.CYAN, Color.CYAN,
+ Color.GREEN, Color.GREEN, Color.CYAN, Color.CYAN
+ };
+ mBitmap = Bitmap.createBitmap(colors, 4, 4, Bitmap.Config.ARGB_8888);
+ }
+
+ public void onDrawFrame(GL10 gl) {
+ // Redraw background color
+ gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+ gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
+ GL10.GL_REPLACE);
+
+ // Set GL_MODELVIEW transformation mode
+ gl.glMatrixMode(GL10.GL_MODELVIEW);
+ gl.glLoadIdentity(); // reset the matrix to its default state
+
+ // When using GL_MODELVIEW, you must set the view point
+ GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+ gl.glActiveTexture(GL10.GL_TEXTURE0);
+ gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+ gl.glEnable(GL10.GL_TEXTURE_2D);
+
+ // red for default color
+ gl.glColor4f(1.0f, 0f, 0f, 1.0f);
+ gl.glVertexPointer(3, GL10.GL_FLOAT, GEOMETRY_STRIDE, mVertices);
+ gl.glTexCoordPointer(2, GL10.GL_FLOAT, GEOMETRY_STRIDE, mVertices
+ .duplicate().position(3));
+ if (mOesDrawTextureSupported) {
+ // left / bottom / width / height (negative w/h flip the image)
+ int crop[] = new int[] { 0, 0, 4, 4 };
+
+ ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D,
+ GL11Ext.GL_TEXTURE_CROP_RECT_OES, crop, 0);
+ // 4x4 drawing in left-bottom corner
+ ((GL11Ext) gl).glDrawTexfOES(0, 0, 0, 4, 4);
+ }
+ gl.glPushMatrix();
+ gl.glRotatef(mRotationAngle, 0f, 0f, 1f);
+ mRotationAngle += 10f;
+ if (mRotationAngle > 360f) {
+ mRotationAngle = 0f;
+ }
+ gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
+ gl.glPopMatrix();
+ // for one pixel
+ IntBuffer pixel = ByteBuffer.allocateDirect(4).asIntBuffer();
+ gl.glReadPixels(mWidth / 2, mHeight / 2, 1, 1, GL10.GL_RGBA,
+ GL10.GL_UNSIGNED_BYTE, pixel);
+ pixel.position(0);
+ Log.i(TAG, "pixel read " + Integer.toHexString(pixel.get(0)));
+
+ Assert.assertEquals(0x0000ffff, pixel.get(0)); // BLUE in RGBA
+
+ checkGlError(gl, "onDrawFrame");
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ gl.glViewport(0, 0, width, height);
+
+ // make adjustments for screen ratio
+ float ratio = (float) width / height;
+ gl.glMatrixMode(GL10.GL_PROJECTION); // set matrix to projection mode
+ gl.glLoadIdentity(); // reset the matrix to its default state
+ gl.glFrustumf(-2 * ratio, 2 * ratio, -2, 2, 3, 7);
+ checkGlError(gl, "onSurfaceChanged");
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
+ Log.i(TAG, "extensions: " + extensions);
+ if (extensions.contains("GL_OES_draw_texture")) {
+ mOesDrawTextureSupported = true;
+ }
+ // Set the background frame color
+ gl.glClearColor(0f, 0f, 0f, 1.0f);
+ gl.glEnable(GL10.GL_TEXTURE_2D);
+
+ gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+ gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+
+ int[] textures = new int[1];
+ gl.glGenTextures(1, textures, 0);
+
+ mTextureID = textures[0];
+ gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+
+ gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
+ GL10.GL_NEAREST);
+ gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
+ GL10.GL_NEAREST); // necessary due to low resolution texture
+
+ gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
+ GL10.GL_CLAMP_TO_EDGE);
+ gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
+ GL10.GL_CLAMP_TO_EDGE);
+ GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);
+ checkGlError(gl, "onSurfaceCreated");
+ }
+
+ private void checkGlError(GL10 gl, String op) {
+ int error;
+ while ((error = gl.glGetError()) != GL10.GL_NO_ERROR) {
+ Log.e(TAG, op + ": glError " + error);
+ throw new IllegalStateException(op + ": glError " + error);
+ }
+ }
+}
diff --git a/tests/tests/os/src/android/os/cts/BuildVersionTest.java b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
index a317dce..6cb09bb 100644
--- a/tests/tests/os/src/android/os/cts/BuildVersionTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
@@ -29,7 +29,7 @@
private static final String LOG_TAG = "BuildVersionTest";
private static final Set<String> EXPECTED_RELEASES =
- new HashSet<String>(Arrays.asList("4.0.3"));
+ new HashSet<String>(Arrays.asList("4.0.3", "4.0.4"));
private static final int EXPECTED_SDK = 15;
@SuppressWarnings("deprecation")
diff --git a/tests/tests/os/src/android/os/cts/EnvironmentTest.java b/tests/tests/os/src/android/os/cts/EnvironmentTest.java
index 2081cba..711306e 100644
--- a/tests/tests/os/src/android/os/cts/EnvironmentTest.java
+++ b/tests/tests/os/src/android/os/cts/EnvironmentTest.java
@@ -70,4 +70,15 @@
assertTrue(Environment.getDownloadCacheDirectory().isDirectory());
assertTrue(Environment.getDataDirectory().isDirectory());
}
+
+ /**
+ * TMPDIR being set prevents apps from asking to have temporary files
+ * placed in their own storage, instead forcing their location to
+ * something OS-defined. If TMPDIR points to a global shared directory,
+ * this could compromise the security of the files.
+ */
+ public void testNoTmpDir() {
+ assertNull("environment variable TMPDIR should not be set",
+ System.getenv("TMPDIR"));
+ }
}
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 2e3bbdb..4b86fbb 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -187,18 +187,26 @@
private static final Set<String> OTHER_RANDOM_DIRECTORIES = new HashSet<String>(
Arrays.asList(
"/app-cache/ciq/socket",
+ "/cache/fotapkg",
+ "/cache/fotapkg/tmp",
+ "/data/amit",
"/data/anr",
"/data/app",
"/data/app-private",
"/data/backup",
+ "/data/battd",
+ "/data/bootlogo",
"/data/btips",
"/data/btips/TI",
"/data/btips/TI/opp",
+ "/data/calibration",
+ "/data/clp",
"/data/dalvik-cache",
"/data/data/.drm",
"/data/data/.drm/.wmdrm",
"/data/data/cw",
"/data/data/com.android.htcprofile",
+ "/data/data/com.android.providers.drm/rights",
"/data/data/com.htc.android.qxdm2sd",
"/data/data/com.htc.android.qxdm2sd/bin",
"/data/data/com.htc.android.qxdm2sd/data",
@@ -211,13 +219,29 @@
"/data/data/com.htc.loggers/htclog",
"/data/data/com.htc.loggers/tmp",
"/data/data/com.htc.loggers/htcghost",
- "/data/data/com.android.providers.drm/rights",
+ "/data/data/com.lge.ers/android",
+ "/data/data/com.lge.ers/arm9",
+ "/data/data/com.lge.ers/kernel",
+ "/data/data/recovery",
"/data/dontpanic",
"/data/drm",
"/data/drm/rights",
"/data/dump",
+ "/data/fota",
+ "/data/emt",
+ "/data/gpscfg",
+ "/data/hwvefs",
"/data/htcfs",
+ "/data/internal-device",
+ "/data/internal-device/DCIM",
"/data/local",
+ "/data/local/logs",
+ "/data/local/logs/kernel",
+ "/data/local/logs/logcat",
+ "/data/local/logs/resetlog",
+ "/data/local/logs/smem",
+ "/data/local/rwsystag",
+ "/data/local/tmp",
"/data/local/tmp/com.nuance.android.vsuite.vsuiteapp",
"/data/log",
"/data/lost+found",
@@ -226,13 +250,29 @@
"/data/misc/dhcp",
"/data/misc/wifi",
"/data/misc/wifi/sockets",
+ "/data/misc/wpa_supplicant",
+ "/data/nvcam",
+ "/data/panicreports",
"/data/property",
+ "/data/radio",
"/data/secure",
+ "/data/sensors",
"/data/shared",
+ "/data/simcom",
+ "/data/simcom/btadd",
+ "/data/simcom/simlog",
"/data/system",
+ "/data/tombstones",
+ "/data/tpapi",
+ "/data/tpapi/etc",
+ "/data/tpapi/etc/tpa",
+ "/data/tpapi/etc/tpa/persistent",
+ "/data/tpapi/user.bin",
+ "/data/wapi",
"/data/wifi",
"/data/wiper",
"/data/wpstiles",
+ "/data/xt9",
"/dbdata/databases",
"/efs/.android",
"/mnt_ext",
@@ -240,7 +280,13 @@
"/mnt_ext/badablk3",
"/mnt_ext/cache",
"/mnt_ext/data",
- "/system/etc/security/drm"
+ "/system/etc/dhcpcd/dhcpcd-run-hooks",
+ "/system/etc/security/drm",
+ "/synthesis/hades",
+ "/synthesis/chimaira",
+ "/synthesis/shdisp",
+ "/synthesis/hdmi",
+ "/tmp"
)
);
diff --git a/tests/tests/permission2/AndroidManifest.xml b/tests/tests/permission2/AndroidManifest.xml
index e8d3a3a..8f77fad 100755
--- a/tests/tests/permission2/AndroidManifest.xml
+++ b/tests/tests/permission2/AndroidManifest.xml
@@ -39,6 +39,8 @@
<!-- need app that has CALL_PHONE but not PROCESS_OUTGOING_CALL -->
<uses-permission android:name="android.permission.CALL_PHONE"/>
+ <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
+
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.android.cts.permission2"
android:label="More CTS tests for permissions"/>
diff --git a/tests/tests/permission2/src/android/permission2/cts/ReadSocialStreamPermissionTest.java b/tests/tests/permission2/src/android/permission2/cts/ReadSocialStreamPermissionTest.java
new file mode 100644
index 0000000..eaf6fdf
--- /dev/null
+++ b/tests/tests/permission2/src/android/permission2/cts/ReadSocialStreamPermissionTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.permission2.cts;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.net.Uri;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.StreamItems;
+import android.test.AndroidTestCase;
+
+public class ReadSocialStreamPermissionTest extends AndroidTestCase {
+
+ private ContentResolver mResolver;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResolver = mContext.getContentResolver();
+ }
+
+ public void testReadSocialStreamPermission_byRawContactId() throws Exception {
+ try {
+ mResolver.query(Uri.withAppendedPath(
+ ContentUris.withAppendedId(RawContacts.CONTENT_URI, 1337),
+ Contacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
+ fail("Expected a READ_SOCIAL_STREAM exception");
+ } catch (SecurityException e) {
+ // Expect a READ_SOCIAL_STREAM exception.
+ }
+ }
+
+ public void testReadSocialStreamPermission_byContactId() throws Exception {
+ try {
+ mResolver.query(Uri.withAppendedPath(
+ ContentUris.withAppendedId(Contacts.CONTENT_URI, 1337),
+ Contacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
+ fail("Expected a READ_SOCIAL_STREAM exception");
+ } catch (SecurityException e) {
+ // Expect a READ_SOCIAL_STREAM exception.
+ }
+ }
+
+ public void testReadSocialStreamPermission_byLookUpKey() throws Exception {
+ try {
+ mResolver.query(Contacts.CONTENT_LOOKUP_URI.buildUpon()
+ .appendPath("lookDownKey")
+ .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY)
+ .build(), null, null, null, null);
+ fail("Expected a READ_SOCIAL_STREAM exception");
+ } catch (SecurityException e) {
+ // Expect a READ_SOCIAL_STREAM exception.
+ }
+ }
+
+ public void testReadSocialStreamPermission_byStreamItemId() throws Exception {
+ try {
+ mResolver.query(ContentUris.withAppendedId(StreamItems.CONTENT_URI, 1337),
+ null, null, null, null);
+ fail("Expected a READ_SOCIAL_STREAM exception");
+ } catch (SecurityException e) {
+ // Expect a READ_SOCIAL_STREAM exception.
+ }
+ }
+}
diff --git a/tests/tests/permission2/src/android/permission2/cts/WriteSocialStreamPermissionTest.java b/tests/tests/permission2/src/android/permission2/cts/WriteSocialStreamPermissionTest.java
new file mode 100644
index 0000000..262fcfa
--- /dev/null
+++ b/tests/tests/permission2/src/android/permission2/cts/WriteSocialStreamPermissionTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.permission2.cts;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.net.Uri;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.StreamItems;
+import android.test.AndroidTestCase;
+
+public class WriteSocialStreamPermissionTest extends AndroidTestCase {
+
+ private ContentResolver mResolver;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResolver = mContext.getContentResolver();
+ }
+
+ public void testWriteSocialStreamPermission_byContentDirectory() throws Exception {
+ try {
+ ContentValues values = new ContentValues();
+ mResolver.insert(Uri.withAppendedPath(
+ ContentUris.withAppendedId(RawContacts.CONTENT_URI, 1337),
+ RawContacts.StreamItems.CONTENT_DIRECTORY), values);
+ fail("Expected a WRITE_SOCIAL_STREAM exception");
+ } catch (SecurityException e) {
+ // Expect a WRITE_SOCIAL_STREAM exception.
+ }
+ }
+
+ public void testWriteSocialStreamPermission_byContentUri() throws Exception {
+ try {
+ ContentValues values = new ContentValues();
+ mResolver.insert(StreamItems.CONTENT_URI, values);
+ fail("Expected a WRITE_SOCIAL_STREAM exception");
+ } catch (SecurityException e) {
+ // Expect a WRITE_SOCIAL_STREAM exception.
+ }
+ }
+}
diff --git a/tests/tests/preference2/Android.mk b/tests/tests/preference2/Android.mk
new file mode 100644
index 0000000..4b7b2e5
--- /dev/null
+++ b/tests/tests/preference2/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsPreference2TestCases
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tests/tests/preference2/AndroidManifest.xml b/tests/tests/preference2/AndroidManifest.xml
new file mode 100644
index 0000000..5043e1f
--- /dev/null
+++ b/tests/tests/preference2/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.preference2">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity
+ android:name="android.preference2.cts.PreferenceFragmentActivity" >
+ </activity>
+ <activity
+ android:name="android.preference2.cts.PreferenceStubActivity" >
+ </activity>
+ <activity
+ android:name="android.preference2.cts.PreferenceFromCodeActivity" >
+ </activity>
+ <activity android:name="android.preference2.cts.PreferencesFromXml" />
+ <activity android:name="android.preference2.cts.PreferenceWithHeaders" />
+ </application>
+
+ <!-- This is a self-instrumenting test package. -->
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.cts.preference2"
+ android:label="CTS Test Cases for android.preference"/>
+
+</manifest>
+
diff --git a/tests/tests/preference2/res/drawable-hdpi/ic_launcher.png b/tests/tests/preference2/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..8074c4c
--- /dev/null
+++ b/tests/tests/preference2/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/tests/preference2/res/drawable-ldpi/ic_launcher.png b/tests/tests/preference2/res/drawable-ldpi/ic_launcher.png
new file mode 100755
index 0000000..1095584
--- /dev/null
+++ b/tests/tests/preference2/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/tests/tests/preference2/res/drawable-mdpi/ic_launcher.png b/tests/tests/preference2/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..a07c69f
--- /dev/null
+++ b/tests/tests/preference2/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/tests/preference2/res/drawable-mdpi/ic_settings_applications.png b/tests/tests/preference2/res/drawable-mdpi/ic_settings_applications.png
new file mode 100755
index 0000000..745ff2a
--- /dev/null
+++ b/tests/tests/preference2/res/drawable-mdpi/ic_settings_applications.png
Binary files differ
diff --git a/tests/tests/preference2/res/drawable-mdpi/ic_settings_display.png b/tests/tests/preference2/res/drawable-mdpi/ic_settings_display.png
new file mode 100755
index 0000000..85af393
--- /dev/null
+++ b/tests/tests/preference2/res/drawable-mdpi/ic_settings_display.png
Binary files differ
diff --git a/tests/tests/preference2/res/layout/main.xml b/tests/tests/preference2/res/layout/main.xml
new file mode 100755
index 0000000..a6b7f10
--- /dev/null
+++ b/tests/tests/preference2/res/layout/main.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+
+</LinearLayout>
diff --git a/tests/tests/preference2/res/values/arrays.xml b/tests/tests/preference2/res/values/arrays.xml
new file mode 100755
index 0000000..198d989
--- /dev/null
+++ b/tests/tests/preference2/res/values/arrays.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- Used in View/Spinner1.java -->
+ <string-array name="colors">
+ <item>red</item>
+ <item>orange</item>
+ <item>yellow</item>
+ <item>green</item>
+ <item>blue</item>
+ <item>violet</item>
+ </string-array>
+
+ <!-- Used in View/Spinner1.java -->
+ <string-array name="planets">
+ <item>Mercury</item>
+ <item>Venus</item>
+ <item>Earth</item>
+ <item>Mars</item>
+ <item>Jupiter</item>
+ <item>Saturn</item>
+ <item>Uranus</item>
+ <item>Neptune</item>
+ <item>Pluto</item>
+ </string-array>
+
+ <!-- Used in content/ClipboardSample.java -->
+ <string-array name="clip_data_types">
+ <item>No data in clipboard</item>
+ <item>Text clip</item>
+ <item>Intent clip</item>
+ <item>Uri clip</item>
+ </string-array>
+
+ <!-- Used in App/SearchInvoke.java -->
+ <string-array name="search_menuModes">
+ <item>Search Key</item>
+ <item>Menu Item</item>
+ <item>Type-To-Search</item>
+ <item>Disabled</item>
+ </string-array>
+
+ <!-- Used in app/dialog examples -->
+ <string-array name="select_dialog_items">
+ <item>Command one</item>
+ <item>Command two</item>
+ <item>Command three</item>
+ <item>Command four</item>
+ </string-array>
+
+ <string-array name="select_dialog_items2">
+ <item>Map</item>
+ <item>Satellite</item>
+ <item>Traffic</item>
+ <item>Street view</item>
+ </string-array>
+
+ <string-array name="select_dialog_items3">
+ <item>Every Monday</item>
+ <item>Every Tuesday</item>
+ <item>Every Wednesday</item>
+ <item>Every Thursday</item>
+ <item>Every Friday</item>
+ <item>Every Saturday</item>
+ <item>Every Sunday</item>
+ </string-array>
+
+ <!-- Used in app/menu examples -->
+ <string-array name="entries_list_preference">
+ <item>Alpha Option 01</item>
+ <item>Beta Option 02</item>
+ <item>Charlie Option 03</item>
+ </string-array>
+
+ <!-- Used in app/menu examples -->
+ <string-array name="entryvalues_list_preference">
+ <item>alpha</item>
+ <item>beta</item>
+ <item>charlie</item>
+ </string-array>
+
+ <!-- Used in app/Sample Device Admin -->
+ <string-array name="password_qualities">
+ <item>Unspecified</item>
+ <item>Something</item>
+ <item>Numeric</item>
+ <item>Alphabetic</item>
+ <item>Alphanumeric</item>
+ <item>Complex</item>
+ </string-array>
+
+ <!-- Used in app/Screen Orientation -->
+ <string-array name="screen_orientations">
+ <item>UNSPECIFIED</item>
+ <item>LANDSCAPE</item>
+ <item>PORTRAIT</item>
+ <item>USER</item>
+ <item>BEHIND</item>
+ <item>SENSOR</item>
+ <item>NOSENSOR</item>
+ <item>SENSOR_LANDSCAPE</item>
+ <item>SENSOR_PORTRAIT</item>
+ <item>REVERSE_LANDSCAPE</item>
+ <item>REVERSE_PORTRAIT</item>
+ <item>FULL_SENSOR</item>
+ </string-array>
+
+ <!-- Used in view/Secure View examples -->
+ <string-array name="secure_view_clicked">
+ <item>*bzzt*\nTransferred $1,000,000 to J. Phisher. Thank you!</item>
+ <item>*bzzt*\nSending all life savings to the International Cabal of Evil Penguins.</item>
+ <item>*bzzt*\nOpening portal to R\'lyeh. Long live Cthulhu!</item>
+ <item>*bzzt*\nYou\'re not very good at this, are you?</item>
+ <item>*bzzt*\nGo away...</item>
+ </string-array>
+
+ <!-- Used in view/Split Touch View example -->
+ <string-array name="cheese_responses">
+ <item>I\'m afraid we\'re fresh out.</item>
+ <item>I\'m afraid we never have that at the end of the week, sir. We get it fresh on Monday.
+ </item>
+ <item>Ah. It\'s been on order, sir, for two weeks. I was expecting it this morning.</item>
+ <item>Normally, sir, yes. Today the van broke down.</item>
+ <item>No.</item>
+ <item>No.</item>
+ <item>No.</item>
+ <item>Yes, sir. It\'s, ah ..... it\'s a bit runny.</item>
+ <item>Well, it\'s very runny, actually, sir.</item>
+ <item>I think it\'s a bit runnier than you\'ll like it, sir.</item>
+ <item>Oh... The cat\'s eaten it.</item>
+ <item>No.</item>
+ <item>No.</item>
+ <item>No.</item>
+ <item>Mmm... cheese.</item>
+ </string-array>
+</resources>
diff --git a/tests/tests/preference2/res/values/attrs.xml b/tests/tests/preference2/res/values/attrs.xml
new file mode 100755
index 0000000..e80e204
--- /dev/null
+++ b/tests/tests/preference2/res/values/attrs.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <declare-styleable name="CustPref">
+ <attr name="icon" format="integer"/>
+ <attr name="title" format="string"/>
+ </declare-styleable>
+</resources>
diff --git a/tests/tests/preference2/res/values/colors.xml b/tests/tests/preference2/res/values/colors.xml
new file mode 100755
index 0000000..bfcd0b4
--- /dev/null
+++ b/tests/tests/preference2/res/values/colors.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <color name="white">#FFFFFF</color>
+ <color name="android_orange">#FF9E18</color>
+ <color name="android_yellow">#F2E406</color>
+ <color name="black">#000000</color>
+ <color name="red">#FF0000</color>
+</resources>
diff --git a/tests/tests/preference2/res/values/strings.xml b/tests/tests/preference2/res/values/strings.xml
new file mode 100755
index 0000000..d43d3eb
--- /dev/null
+++ b/tests/tests/preference2/res/values/strings.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <string name="app_name">CtsPreferenceTestCases</string>
+ <string name="test_prefs">Test Preferences</string>
+
+ <string name="preferences_from_xml">Preference/1. Preferences from XML</string>
+ <string name="launching_preferences">Preference/2. Launching preferences</string>
+ <string name="preference_dependencies">Preference/3. Preference dependencies</string>
+ <string name="default_values">Preference/4. Default values</string>
+ <string name="preferences_from_code">Preference/5. Preferences from code</string>
+ <string name="advanced_preferences">Preference/6. Advanced preferences</string>
+ <string name="fragment_preferences">Preference/7. Fragment</string>
+ <string name="preference_with_headers">Preference/8. Headers</string>
+
+ <string name="launch_preference_activity">Launch PreferenceActivity</string>
+ <string name="counter_value_is">The counter value is</string>
+
+ <string name="inline_preferences">In-line preferences</string>
+ <string name="dialog_based_preferences">Dialog-based preferences</string>
+ <string name="launch_preferences">Launch preferences</string>
+ <string name="preference_attributes">Preference attributes</string>
+
+ <string name="title_checkbox_preference">Checkbox preference</string>
+ <string name="summary_checkbox_preference">This is a checkbox</string>
+ <string name="summary_on_checkbox_preference">Checkbox preference On</string>
+ <string name="summary_off_checkbox_preference">Checkbox preference Off</string>
+
+ <string name="title_switch_preference">Switch preference</string>
+ <string name="summary_switch_preference">This is a switch</string>
+ <string name="summary_on_switch_preference">Switch Summary On</string>
+ <string name="summary_off_switch_preference">Switch Summary Off</string>
+ <string name="switchtext_on">Switch Text On</string>
+ <string name="switchtext_off">Switch Text Off</string>
+
+ <string name="summary_switch_preference_yes_no">This is a switch with custom text</string>
+
+ <string name="title_yesno_preference">Yes or no preference</string>
+ <string name="summary_yesno_preference">An example that uses a yes/no dialog</string>
+ <string name="dialog_title_yesno_preference">Do you like bananas?</string>
+
+ <string name="title_edittext_preference">Edit text preference</string>
+ <string name="summary_edittext_preference">An example that uses an edit text dialog</string>
+ <string name="dialog_title_edittext_preference">Enter your favorite animal</string>
+
+ <string name="title_list_preference">List preference</string>
+ <string name="summary_list_preference">An example that uses a list dialog</string>
+ <string name="dialog_title_list_preference">Choose one</string>
+
+ <string name="title_screen_preference">Screen preference</string>
+ <string name="summary_screen_preference">Shows another screen of preferences</string>
+
+ <string name="title_fragment_preference">Fragment preference</string>
+ <string name="summary_fragment_preference">Shows another fragment of preferences</string>
+
+ <string name="title_next_screen_toggle_preference">Toggle preference</string>
+ <string name="summary_next_screen_toggle_preference">
+ Preference that is on the next screen but same hierarchy</string>
+
+ <string name="title_intent_preference">Intent preference</string>
+ <string name="summary_intent_preference">Launches an Activity from an Intent</string>
+
+ <string name="title_my_preference">My preference</string>
+ <string name="summary_my_preference">This is a custom counter preference</string>
+
+ <string name="title_advanced_toggle_preference">Haunted preference</string>
+ <string name="summary_on_advanced_toggle_preference">I\'m on! :)</string>
+ <string name="summary_off_advanced_toggle_preference">I\'m off! :(</string>
+
+ <string name="title_parent_preference">Parent checkbox preference</string>
+ <string name="summary_parent_preference">This is visually a parent</string>
+ <string name="title_child_preference">Child checkbox preference</string>
+ <string name="summary_child_preference">This is visually a child</string>
+
+ <string name="example_preference_dependency">Example preference dependency</string>
+ <string name="title_wifi">WiFi</string>
+ <string name="title_wifi_settings">WiFi settings</string>
+
+ <string name="default_value_list_preference">beta</string>
+ <string name="default_value_edittext_preference">Default value</string>
+ <string name="text_edittext_preference">Edit Text</string>
+ <string name="preset_title">Preset Title</string>
+ <string name="dialog_message">"Dialog Message"</string>
+
+ <string name="title_dialog_preference">Dialog preference</string>
+ <string name="dialogtitle_dialog_preference">Dialog Title</string>
+ <string name="summary_dialog_preference">An example that uses a dialog</string>
+ <string name="positive_button_text">"Accept"</string>
+ <string name="negative_button_text">"Decline"</string>
+
+ <string name="cust_title_dialog_preference">Custom Dialog preference</string>
+ <string name="cust_dialogtitle_dialog_preference">Custom Dialog Title</string>
+</resources>
diff --git a/tests/tests/preference2/res/xml/fragmented_preferences.xml b/tests/tests/preference2/res/xml/fragmented_preferences.xml
new file mode 100755
index 0000000..24537b4
--- /dev/null
+++ b/tests/tests/preference2/res/xml/fragmented_preferences.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This is a primitive example showing the different types of preferences available. -->
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <PreferenceCategory
+ android:title="@string/inline_preferences">
+
+ <CheckBoxPreference
+ android:key="checkbox_preference"
+ android:title="@string/title_checkbox_preference"
+ android:summary="@string/summary_checkbox_preference" />
+
+ <SwitchPreference
+ android:key="checkbox_preference"
+ android:title="@string/title_switch_preference"
+ android:summary="@string/summary_switch_preference" />
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/dialog_based_preferences">
+
+ <EditTextPreference
+ android:key="edittext_preference"
+ android:title="@string/title_edittext_preference"
+ android:summary="@string/summary_edittext_preference"
+ android:dialogTitle="@string/dialog_title_edittext_preference" />
+
+ <ListPreference
+ android:key="list_preference"
+ android:title="@string/title_list_preference"
+ android:summary="@string/summary_list_preference"
+ android:entries="@array/entries_list_preference"
+ android:entryValues="@array/entryvalues_list_preference"
+ android:dialogTitle="@string/dialog_title_list_preference" />
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/launch_preferences">
+
+ <!-- This PreferenceScreen tag sends the user to a new fragment of
+ preferences. If running in a large screen, they can be embedded
+ inside of the overall preferences UI. -->
+ <PreferenceScreen
+ android:fragment="
+ com.example.android.apis.preference.PreferenceWithHeaders$Prefs1FragmentInner"
+ android:title="@string/title_fragment_preference"
+ android:summary="@string/summary_fragment_preference">
+ <!-- Arbitrary key/value pairs can be included for fragment arguments -->
+ <extra android:name="someKey" android:value="somePrefValue" />
+ </PreferenceScreen>
+
+ <!-- This PreferenceScreen tag sends the user to a completely different
+ activity, switching out of the current preferences UI. -->
+ <PreferenceScreen
+ android:title="@string/title_intent_preference"
+ android:summary="@string/summary_intent_preference">
+
+ <intent android:action="android.intent.action.VIEW"
+ android:data="http://www.android.com" />
+
+ </PreferenceScreen>
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/preference_attributes">
+
+ <CheckBoxPreference
+ android:key="parent_checkbox_preference"
+ android:title="@string/title_parent_preference"
+ android:summary="@string/summary_parent_preference" />
+
+ <!-- The visual style of a child is defined by this styled theme attribute. -->
+ <CheckBoxPreference
+ android:key="child_checkbox_preference"
+ android:dependency="parent_checkbox_preference"
+ android:layout="?android:attr/preferenceLayoutChild"
+ android:title="@string/title_child_preference"
+ android:summary="@string/summary_child_preference" />
+
+ </PreferenceCategory>
+
+</PreferenceScreen>
+
diff --git a/tests/tests/preference2/res/xml/fragmented_preferences_inner.xml b/tests/tests/preference2/res/xml/fragmented_preferences_inner.xml
new file mode 100755
index 0000000..fe235db
--- /dev/null
+++ b/tests/tests/preference2/res/xml/fragmented_preferences_inner.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <CheckBoxPreference
+ android:key="next_screen_checkbox_preference"
+ android:title="@string/title_next_screen_toggle_preference"
+ android:summary="@string/summary_next_screen_toggle_preference" />
+</PreferenceScreen>
+
diff --git a/tests/tests/preference2/res/xml/pref_cb.xml b/tests/tests/preference2/res/xml/pref_cb.xml
new file mode 100755
index 0000000..b5f77b9
--- /dev/null
+++ b/tests/tests/preference2/res/xml/pref_cb.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:in="http://schemas.android.com/apk/res/com.android.cts.preference2" >
+
+ <PreferenceCategory android:title="@string/inline_preferences" >
+ <android.preference2.cts.CustomCheckBoxPreference
+ android:id="@+id/custom_check"
+ style="?android:attr/buttonStyleSmall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="25dp"
+ android:key="custom_checkbox_pref_1"
+ in:icon="@drawable/ic_launcher"
+ in:title="@string/preset_title" />
+ <android.preference2.cts.CustomSwitchPreference
+ android:id="@+id/custom_switch"
+ style="?android:attr/buttonStyleSmall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="25dp"
+ android:key="custom_switch_pref_1"
+ in:icon="@drawable/ic_launcher"
+ in:title="@string/preset_title" />
+
+ <android.preference2.cts.CustomDialogPreference
+ android:id="@+id/custom_switch"
+ style="?android:attr/buttonStyleSmall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="25dp"
+ android:key="custom_dialog_pref_1"
+ in:icon="@drawable/ic_launcher"
+ in:title="@string/preset_title" />
+
+ <android.preference2.cts.CustomEditTextPreference
+ android:id="@+id/custom_switch"
+ style="?android:attr/buttonStyleSmall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="25dp"
+ android:key="custom_edittext_pref_1"
+ in:icon="@drawable/ic_launcher"
+ in:title="@string/preset_title" />
+ </PreferenceCategory>
+</PreferenceScreen>
diff --git a/tests/tests/preference2/res/xml/preference_dependencies.xml b/tests/tests/preference2/res/xml/preference_dependencies.xml
new file mode 100755
index 0000000..405cad6
--- /dev/null
+++ b/tests/tests/preference2/res/xml/preference_dependencies.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <PreferenceCategory
+ android:title="@string/example_preference_dependency">
+ <CheckBoxPreference
+ android:key="wifi"
+ android:title="@string/title_wifi" />
+ <EditTextPreference
+ android:layout="?android:attr/preferenceLayoutChild"
+ android:title="@string/title_wifi_settings"
+ android:dependency="wifi" />
+ </PreferenceCategory>
+</PreferenceScreen>
diff --git a/tests/tests/preference2/res/xml/preference_headers.xml b/tests/tests/preference2/res/xml/preference_headers.xml
new file mode 100755
index 0000000..2465f7a
--- /dev/null
+++ b/tests/tests/preference2/res/xml/preference_headers.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<preference-headers
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <header android:fragment="android.preference2.cts.PreferenceWithHeaders$PrefsOneFragment"
+ android:icon="@drawable/ic_settings_applications"
+ android:title="Prefs 1"
+ android:summary="An example of some preferences." />
+
+ <header android:icon="@drawable/ic_settings_display"
+ android:title="Intent"
+ android:summary="Launches an Intent.">
+ <intent android:action="android.intent.action.VIEW"
+ android:data="http://www.android.com" />
+ </header>
+
+</preference-headers>
diff --git a/tests/tests/preference2/res/xml/preferences.xml b/tests/tests/preference2/res/xml/preferences.xml
new file mode 100755
index 0000000..fa35107
--- /dev/null
+++ b/tests/tests/preference2/res/xml/preferences.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This is a primitive example showing the different types of preferences available. -->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <PreferenceCategory
+ android:title="@string/inline_preferences">
+
+ <CheckBoxPreference android:id="@+id/checkbox1"
+ android:key="checkbox_preference"
+ android:title="@string/title_checkbox_preference"
+ android:summary="@string/summary_checkbox_preference" />
+
+ <SwitchPreference
+ android:key="checkbox_preference"
+ android:title="@string/title_switch_preference"
+ android:summary="@string/summary_switch_preference" />
+
+ <SwitchPreference
+ android:key="checkbox_preference"
+ android:title="@string/title_switch_preference"
+ android:summary="@string/summary_switch_preference_yes_no"
+ android:switchTextOn = "YES"
+ android:switchTextOff = "NO" />
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/dialog_based_preferences">
+
+ <EditTextPreference
+ android:key="edittext_preference"
+ android:title="@string/title_edittext_preference"
+ android:summary="@string/summary_edittext_preference"
+ android:dialogTitle="@string/dialog_title_edittext_preference" />
+ <ListPreference
+ android:key="list_preference"
+ android:title="@string/title_list_preference"
+ android:summary="@string/summary_list_preference"
+ android:entries="@array/entries_list_preference"
+ android:entryValues="@array/entryvalues_list_preference"
+ android:dialogTitle="@string/dialog_title_list_preference" />
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/launch_preferences">
+
+ <!-- This PreferenceScreen tag serves as a screen break (similar to page break
+ in word processing). Like for other preference types, we assign a key
+ here so it is able to save and restore its instance state. -->
+ <PreferenceScreen
+ android:key="screen_preference"
+ android:title="@string/title_screen_preference"
+ android:summary="@string/summary_screen_preference">
+
+ <!-- You can place more preferences here that will be shown on the next screen. -->
+
+ <CheckBoxPreference
+ android:key="next_screen_checkbox_preference"
+ android:title="@string/title_next_screen_toggle_preference"
+ android:summary="@string/summary_next_screen_toggle_preference" />
+
+ </PreferenceScreen>
+
+ <PreferenceScreen
+ android:title="@string/title_intent_preference"
+ android:summary="@string/summary_intent_preference">
+
+ <intent android:action="android.intent.action.VIEW"
+ android:data="http://www.android.com" />
+
+ </PreferenceScreen>
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:title="@string/preference_attributes">
+
+ <CheckBoxPreference
+ android:key="parent_checkbox_preference"
+ android:title="@string/title_parent_preference"
+ android:summary="@string/summary_parent_preference" />
+
+ <!-- The visual style of a child is defined by this styled theme attribute. -->
+ <CheckBoxPreference
+ android:key="child_checkbox_preference"
+ android:dependency="parent_checkbox_preference"
+ android:layout="?android:attr/preferenceLayoutChild"
+ android:title="@string/title_child_preference"
+ android:summary="@string/summary_child_preference" />
+ </PreferenceCategory>
+
+</PreferenceScreen>
+
diff --git a/tests/tests/preference2/src/android/preference2/cts/CheckBoxPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/CheckBoxPreferenceTest.java
new file mode 100755
index 0000000..de129e0
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/CheckBoxPreferenceTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.preference2.cts;
+
+import android.preference.CheckBoxPreference;
+import android.test.ActivityInstrumentationTestCase2;
+
+import com.android.cts.preference2.R;
+
+public class CheckBoxPreferenceTest
+ extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
+
+ private PreferenceFromCodeActivity mActivity;
+
+ public CheckBoxPreferenceTest() {
+ super(PreferenceFromCodeActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+
+ public void testNotNull() {
+ CheckBoxPreference checkBoxPref = (CheckBoxPreference) mActivity.findPreference(
+ "checkbox_preference");
+ assertNotNull(checkBoxPref);
+ }
+
+ public void testGetSummary() {
+ CheckBoxPreference checkBoxPref = (CheckBoxPreference) mActivity.findPreference(
+ "checkbox_preference");
+ String summary = (String) checkBoxPref.getSummary();
+ String summaryExp = mActivity.getResources().getString(
+ R.string.summary_checkbox_preference);
+ assertEquals(summaryExp, summary);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomCheckBoxPreference.java b/tests/tests/preference2/src/android/preference2/cts/CustomCheckBoxPreference.java
new file mode 100755
index 0000000..d51eddd
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomCheckBoxPreference.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.preference2.cts;
+
+import com.android.cts.preference2.R;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.preference.CheckBoxPreference;
+import android.util.AttributeSet;
+
+public class CustomCheckBoxPreference extends CheckBoxPreference {
+ private Drawable mIcon;
+ private String mTitle;
+ public CustomCheckBoxPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(attrs);
+ setIcon(mIcon);
+ this.setTitle(mTitle);
+ }
+
+ public CustomCheckBoxPreference(Context context) {
+ super(context);
+ }
+
+ public CustomCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(attrs);
+ setIcon(mIcon);
+ this.setTitle(mTitle);
+ }
+
+ private void init(AttributeSet attrs) {
+ TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.CustPref);
+ mTitle = a.getString(R.styleable.CustPref_title);
+ mIcon = a.getDrawable(R.styleable.CustPref_icon);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomCheckBoxPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/CustomCheckBoxPreferenceTest.java
new file mode 100755
index 0000000..25ba3f3
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomCheckBoxPreferenceTest.java
@@ -0,0 +1,44 @@
+ /*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference2.cts;
+
+import android.preference.CheckBoxPreference;
+import android.test.ActivityInstrumentationTestCase2;
+
+public class CustomCheckBoxPreferenceTest
+ extends ActivityInstrumentationTestCase2<PreferencesFromXml> {
+
+ private PreferencesFromXml mActivity;
+ private CheckBoxPreference mCheckBoxPref;
+
+ public CustomCheckBoxPreferenceTest() {
+ super(PreferencesFromXml.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mCheckBoxPref = (CheckBoxPreference) mActivity.findPreference(
+ "custom_checkbox_pref_1");
+ }
+
+ public void testNotNull() {
+ assertNotNull(mCheckBoxPref);
+ }
+
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomDialogPreference.java b/tests/tests/preference2/src/android/preference2/cts/CustomDialogPreference.java
new file mode 100755
index 0000000..db584ac
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomDialogPreference.java
@@ -0,0 +1,48 @@
+/*
+ * 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.preference2.cts;
+
+import com.android.cts.preference2.R;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.preference.DialogPreference;
+import android.util.AttributeSet;
+
+public class CustomDialogPreference extends DialogPreference {
+ private Drawable mIcon;
+ private String mTitle;
+ public CustomDialogPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(attrs);
+ setIcon(mIcon);
+ this.setTitle(mTitle);
+ }
+
+ public CustomDialogPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(attrs);
+ setIcon(mIcon);
+ this.setTitle(mTitle);
+ }
+
+ private void init(AttributeSet attrs) {
+ TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.CustPref);
+ mTitle = a.getString(R.styleable.CustPref_title);
+ mIcon = a.getDrawable(R.styleable.CustPref_icon);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomDialogPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/CustomDialogPreferenceTest.java
new file mode 100755
index 0000000..5384420
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomDialogPreferenceTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference2.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+public class CustomDialogPreferenceTest
+ extends ActivityInstrumentationTestCase2<PreferencesFromXml> {
+
+ private PreferencesFromXml mActivity;
+ private CustomDialogPreference mDialogPref;
+
+ public CustomDialogPreferenceTest() {
+ super(PreferencesFromXml.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mDialogPref = (CustomDialogPreference) mActivity.findPreference(
+ "custom_dialog_pref_1");
+ }
+
+ public void testNotNull() {
+ assertNotNull(mDialogPref);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomEditTextPreference.java b/tests/tests/preference2/src/android/preference2/cts/CustomEditTextPreference.java
new file mode 100755
index 0000000..51fdf13
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomEditTextPreference.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.preference2.cts;
+
+import com.android.cts.preference2.R;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.preference.EditTextPreference;
+import android.util.AttributeSet;
+
+public class CustomEditTextPreference extends EditTextPreference {
+ private Drawable mIcon;
+ private String mTitle;
+ public CustomEditTextPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(attrs);
+ setIcon(mIcon);
+ this.setTitle(mTitle);
+ }
+
+ public CustomEditTextPreference(Context context) {
+ super(context);
+ }
+
+ public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(attrs);
+ setIcon(mIcon);
+ this.setTitle(mTitle);
+ }
+
+ private void init(AttributeSet attrs) {
+ TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.CustPref);
+ mTitle =a.getString(R.styleable.CustPref_title);
+ mIcon = a.getDrawable(R.styleable.CustPref_icon);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomEditTextPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/CustomEditTextPreferenceTest.java
new file mode 100755
index 0000000..c131539
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomEditTextPreferenceTest.java
@@ -0,0 +1,42 @@
+ /*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference2.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+public class CustomEditTextPreferenceTest
+ extends ActivityInstrumentationTestCase2<PreferencesFromXml> {
+
+ private PreferencesFromXml mActivity;
+ private CustomEditTextPreference mEditTextPref;
+
+ public CustomEditTextPreferenceTest() {
+ super(PreferencesFromXml.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = (PreferencesFromXml)getActivity();
+ mEditTextPref = (CustomEditTextPreference) mActivity.findPreference(
+ "custom_edittext_pref_1");
+ }
+
+ public void testNotNull() {
+ assertNotNull(mEditTextPref);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomSwitchPreference.java b/tests/tests/preference2/src/android/preference2/cts/CustomSwitchPreference.java
new file mode 100755
index 0000000..54e7861
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomSwitchPreference.java
@@ -0,0 +1,53 @@
+/*
+ * 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.preference2.cts;
+
+
+import com.android.cts.preference2.R;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.preference.SwitchPreference;
+import android.util.AttributeSet;
+
+public class CustomSwitchPreference extends SwitchPreference {
+ private Drawable mIcon;
+ private String mTitle;
+ public CustomSwitchPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(attrs);
+ setIcon(mIcon);
+ this.setTitle(mTitle);
+ }
+
+ public CustomSwitchPreference(Context context) {
+ super(context);
+ }
+
+ public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(attrs);
+ setIcon(mIcon);
+ this.setTitle(mTitle);
+ }
+
+ private void init(AttributeSet attrs) {
+ TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.CustPref);
+ mTitle =a.getString(R.styleable.CustPref_title);
+ mIcon = a.getDrawable(R.styleable.CustPref_icon);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/CustomSwitchPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/CustomSwitchPreferenceTest.java
new file mode 100755
index 0000000..937e48f
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/CustomSwitchPreferenceTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference2.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+public class CustomSwitchPreferenceTest
+ extends ActivityInstrumentationTestCase2<PreferencesFromXml> {
+
+ private PreferencesFromXml mActivity;
+ private CustomSwitchPreference mSwitchPref;
+
+ public CustomSwitchPreferenceTest() {
+ super(PreferencesFromXml.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mSwitchPref = (CustomSwitchPreference) mActivity.findPreference(
+ "custom_switch_pref_1");
+ }
+
+ public void testNotNull() {
+ assertNotNull(mSwitchPref);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/DialogPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/DialogPreferenceTest.java
new file mode 100755
index 0000000..1136cee
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/DialogPreferenceTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.preference2.cts;
+
+import android.graphics.drawable.Drawable;
+import android.preference.DialogPreference;
+import android.test.ActivityInstrumentationTestCase2;
+
+import com.android.cts.preference2.R;
+
+public class DialogPreferenceTest
+ extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
+
+ private PreferenceFromCodeActivity mActivity;
+ private DialogPreference mDialogPreference;
+
+ public DialogPreferenceTest() {
+ super(PreferenceFromCodeActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mDialogPreference = (DialogPreference)mActivity.findPreference(
+ "dialog_preference");
+ }
+
+ public void testGetTitle() {
+ String title = (String) mDialogPreference.getTitle();
+ String titleExp = mActivity.getResources().getString(R.string.title_dialog_preference);
+ assertEquals(titleExp, title);
+ }
+
+ public void testGetDialogTitle() {
+ String title = (String) mDialogPreference.getDialogTitle();
+ String titleExp = mActivity.getResources().getString(
+ R.string.dialogtitle_dialog_preference);
+ assertEquals(titleExp, title);
+ }
+
+ public void testGetDialogIcon() {
+ Drawable drawable = mDialogPreference.getDialogIcon();
+ Drawable drawableExp = mActivity.getResources().getDrawable(R.drawable.ic_launcher);
+ assertEquals(drawableExp.getBounds(), drawable.getBounds());
+ }
+
+ public void testGetDialogMessage() {
+ CharSequence dialogMessage = mDialogPreference.getDialogMessage();
+ CharSequence dialogMessageExp = mActivity.getResources().getString(
+ R.string.dialog_message);
+ assertEquals(dialogMessageExp, dialogMessage);
+ }
+
+ public void testGetPositiveButtonText() {
+ CharSequence positiveButtonText = mDialogPreference.getPositiveButtonText();
+ CharSequence postiveButtonTextExp = mActivity.getResources().getString(
+ R.string.positive_button_text);
+ assertEquals(positiveButtonText, postiveButtonTextExp);
+ }
+
+ public void testGetNegativeButtonText() {
+ CharSequence negativeButtonText = mDialogPreference.getNegativeButtonText();
+ CharSequence negativeButtonTextExp = mActivity.getResources().getString(
+ R.string.negative_button_text);
+ assertEquals(negativeButtonText, negativeButtonTextExp);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/EditTextPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/EditTextPreferenceTest.java
new file mode 100755
index 0000000..e0d5c8c
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/EditTextPreferenceTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference2.cts;
+
+import android.preference.EditTextPreference;
+import android.test.ActivityInstrumentationTestCase2;
+import android.widget.EditText;
+
+public class EditTextPreferenceTest
+ extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
+
+ private PreferenceFromCodeActivity mActivity;
+ private EditTextPreference mEditTextPref;
+
+ public EditTextPreferenceTest() {
+ super(PreferenceFromCodeActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mEditTextPref = (EditTextPreference) mActivity.findPreference(
+ "edittext_preference");
+ }
+
+ public void testGetEditText() {
+ EditText editText = mEditTextPref.getEditText();
+ assertNotNull(editText);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/ListPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/ListPreferenceTest.java
new file mode 100755
index 0000000..32596ff
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/ListPreferenceTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.preference2.cts;
+
+import android.preference.ListPreference;
+import android.test.ActivityInstrumentationTestCase2;
+
+import com.android.cts.preference2.R;
+
+public class ListPreferenceTest
+ extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
+
+ private PreferenceFromCodeActivity mActivity;
+ private ListPreference mListPref;
+
+ public ListPreferenceTest() {
+ super(PreferenceFromCodeActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mListPref = (ListPreference) mActivity.findPreference("list_preference");
+ }
+
+ public void testGetEntries() {
+ String[] entries = convertToStringArray((CharSequence[]) mListPref.getEntries());
+ String[] entriesExp = mActivity.getResources().getStringArray(
+ R.array.entries_list_preference);
+ compareArrays(entriesExp, entries);
+ }
+
+ public void testGetEntryValues() {
+ String[] entryValues = convertToStringArray((CharSequence[]) mListPref.getEntryValues());
+ String[] entryValuesExp = mActivity.getResources().getStringArray(
+ R.array.entryvalues_list_preference);
+ compareArrays(entryValuesExp,entryValues);
+ }
+
+ public void testIsEnabled() {
+ boolean isEnabled = mListPref.isEnabled();
+ assertTrue(isEnabled);
+ }
+
+ private synchronized String[] convertToStringArray(CharSequence[] array){
+ String[] strArray = new String[array.length];
+ for(int i = 0; i < array.length; i++){
+ strArray[i] = (String) array[i];
+ }
+ return strArray;
+ }
+
+ private void compareArrays(String[] firstArray,String[] secArray){
+ assertEquals(firstArray.length, secArray.length);
+ for(int i = 0; i < firstArray.length; i++) {
+ assertEquals(firstArray[i], secArray[i]);
+ }
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceCategoryTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceCategoryTest.java
new file mode 100755
index 0000000..33adceb
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceCategoryTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference2.cts;
+
+import android.preference.Preference;
+import android.test.ActivityInstrumentationTestCase2;
+
+public class PreferenceCategoryTest
+ extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
+
+ private PreferenceFromCodeActivity mActivity;
+
+ public PreferenceCategoryTest() {
+ super(PreferenceFromCodeActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+
+ public void testPreferenceCategory() {
+ Preference prefCat = mActivity.findPreference("pref-1");
+ assertNotNull(prefCat);
+ assertTrue(!prefCat.isEnabled());
+
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceFragmentActivity.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceFragmentActivity.java
new file mode 100755
index 0000000..4f12d17
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceFragmentActivity.java
@@ -0,0 +1,48 @@
+/*
+ * 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.preference2.cts;
+
+import android.app.Activity;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.preference.PreferenceFragment;
+
+/**
+ * Demonstration of PreferenceFragment, showing a single fragment in an
+ * activity.
+ */
+public class PreferenceFragmentActivity extends Activity {
+
+ public PrefFragment prefFragment;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ prefFragment = new PrefFragment();
+
+ FragmentTransaction transaction = getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, prefFragment, PrefFragment.TAG);
+ transaction.commit();
+ }
+
+ public class PrefFragment extends PreferenceFragment {
+ public static final String TAG = "Pref-1";
+
+ public PrefFragment() {
+
+ }
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceFragmentTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceFragmentTest.java
new file mode 100755
index 0000000..4c883c2
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceFragmentTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference2.cts;
+
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+import android.preference2.cts.PreferenceFragmentActivity.PrefFragment;
+import android.test.ActivityInstrumentationTestCase2;
+
+public class PreferenceFragmentTest
+ extends ActivityInstrumentationTestCase2<PreferenceFragmentActivity> {
+
+ private PreferenceFragmentActivity mActivity;
+
+ public PreferenceFragmentTest() {
+ super(PreferenceFragmentActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+
+ public void testGetPreferenceManager() {
+ PrefFragment prefFragment = (PrefFragment) mActivity.getFragmentManager().
+ findFragmentByTag(PrefFragment.TAG);
+ PreferenceManager prefManager = prefFragment.getPreferenceManager();
+ assertNotNull(prefManager);
+ }
+
+ public void testGetPreferenceScreen() {
+ PrefFragment prefsFragment = (PrefFragment) mActivity.getFragmentManager().
+ findFragmentByTag(PrefFragment.TAG);
+ PreferenceScreen prefScreen = prefsFragment.getPreferenceScreen();
+ assertNull(prefScreen);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceFromCodeActivity.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceFromCodeActivity.java
new file mode 100755
index 0000000..ee0dde1
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceFromCodeActivity.java
@@ -0,0 +1,114 @@
+/*
+ * 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.preference2.cts;
+
+import com.android.cts.preference2.R;
+
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.preference.SwitchPreference;
+
+public class PreferenceFromCodeActivity extends PreferenceActivity {
+ private Preference mPref;
+ protected PreferenceScreen mPrefScreen;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mPrefScreen = getPreferenceManager().createPreferenceScreen(this);
+ addPreferenceCategory();
+ setPreferenceScreen(mPrefScreen);
+ }
+
+ private void addPreferenceCategory() {
+ PreferenceCategory prefCat = new PreferenceCategory(this);
+ prefCat.setTitle(R.string.inline_preferences);
+ prefCat.setKey("pref-1");
+ mPrefScreen.addPreference(prefCat);
+
+ //CheckBox Preference
+ CheckBoxPreference checkboxPref = new CheckBoxPreference(this);
+ checkboxPref.setKey("checkbox_preference");
+ checkboxPref.setTitle(R.string.title_checkbox_preference);
+ checkboxPref.setSummary(R.string.summary_checkbox_preference);
+ checkboxPref.setSummaryOn(R.string.summary_on_checkbox_preference);
+ checkboxPref.setSummaryOff(R.string.summary_off_checkbox_preference);
+ checkboxPref.setChecked(true);
+ checkboxPref.shouldDisableDependents();
+ prefCat.addPreference(checkboxPref);
+
+ // Switch preference
+ SwitchPreference switchPref = new SwitchPreference(this);
+ switchPref.setKey("switch_preference");
+ switchPref.setTitle(R.string.title_switch_preference);
+ switchPref.setSummary(R.string.summary_switch_preference);
+ switchPref.setSummaryOn(R.string.summary_on_switch_preference);
+ switchPref.setSummaryOff(R.string.summary_off_switch_preference);
+ switchPref.setSwitchTextOff(R.string.switchtext_off);
+ switchPref.setSwitchTextOn(R.string.switchtext_on);
+ prefCat.addPreference(switchPref);
+
+ SwitchPreference switchPref2 = new SwitchPreference(this);
+ switchPref2.setKey("switch_preference_2");
+ switchPref2.setTitle(R.string.title_switch_preference);
+ switchPref2.setSummary(R.string.summary_switch_preference);
+ switchPref2.setSummaryOn(R.string.summary_on_switch_preference);
+ switchPref2.setSummaryOff(R.string.summary_off_switch_preference);
+ prefCat.addPreference(switchPref2);
+
+ // Dialog based preferences
+ PreferenceCategory dialogBasedPrefCat = new PreferenceCategory(this);
+ dialogBasedPrefCat.setTitle(R.string.dialog_based_preferences);
+ mPrefScreen.addPreference(dialogBasedPrefCat);
+
+ // Edit text preference
+ EditTextPreference editTextPref = new EditTextPreference(this);
+ editTextPref.setDialogTitle(R.string.dialog_title_edittext_preference);
+ editTextPref.setKey("edittext_preference");
+ editTextPref.setTitle(R.string.title_edittext_preference);
+ editTextPref.setSummary(R.string.summary_edittext_preference);
+ editTextPref.setText(getResources().getString(R.string.text_edittext_preference));
+ dialogBasedPrefCat.addPreference(editTextPref);
+
+ EditTextPreference dialogPref = new EditTextPreference(this);
+ dialogPref.setDialogTitle(R.string.dialogtitle_dialog_preference);
+ dialogPref.setKey("dialog_preference");
+ dialogPref.setTitle(R.string.title_dialog_preference);
+ dialogPref.setSummary(R.string.summary_dialog_preference);
+ dialogPref.setDialogIcon(R.drawable.ic_launcher);
+ dialogPref.setDialogMessage(R.string.dialog_message);
+ dialogPref.setNegativeButtonText(R.string.negative_button_text);
+ dialogPref.setPositiveButtonText(R.string.positive_button_text);
+
+ dialogBasedPrefCat.addPreference(dialogPref);
+
+ ListPreference listPref = new ListPreference(this);
+ listPref.setEntries(R.array.entries_list_preference);
+ listPref.setEntryValues(R.array.entryvalues_list_preference);
+ listPref.setDialogTitle(R.string.dialog_title_list_preference);
+ listPref.setKey("list_preference");
+ listPref.setTitle(R.string.title_list_preference);
+ listPref.setSummary(R.string.summary_list_preference);
+ dialogBasedPrefCat.addPreference(listPref);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceWithHeaders.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceWithHeaders.java
new file mode 100755
index 0000000..1059700
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceWithHeaders.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference2.cts;
+
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
+import android.widget.Button;
+import com.android.cts.preference2.R;
+import java.util.List;
+
+/**
+ * Demonstration of PreferenceActivity to make a top-level preference
+ * panel with headers.
+ */
+
+public class PreferenceWithHeaders extends PreferenceActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // Add a button to the header list.
+ if (hasHeaders()) {
+ Button button = new Button(this);
+ button.setText("Some action");
+ setListFooter(button);
+ }
+ }
+
+ /**
+ * Populate the activity with the top-level headers.
+ */
+ @Override
+ public void onBuildHeaders(List<Header> target) {
+ loadHeadersFromResource(R.xml.preference_headers, target);
+ }
+
+ public static class PrefsOneFragment extends PreferenceFragment {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
+ }
+ }
+}
+
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceWithHeadersTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceWithHeadersTest.java
new file mode 100755
index 0000000..28bff81
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceWithHeadersTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference2.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+public class PreferenceWithHeadersTest
+ extends ActivityInstrumentationTestCase2<PreferenceWithHeaders> {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+
+ private PreferenceWithHeaders mActivity;
+
+ public PreferenceWithHeadersTest() {
+ super(PreferenceWithHeaders.class);
+ }
+
+ public void testHasHeaders() {
+ assertTrue(mActivity.hasHeaders());
+ }
+
+ public void testOnIsHidingHeaders() {
+ assertFalse(mActivity.onIsHidingHeaders());
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferencesFromXml.java b/tests/tests/preference2/src/android/preference2/cts/PreferencesFromXml.java
new file mode 100755
index 0000000..0a61461
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferencesFromXml.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference2.cts;
+
+import com.android.cts.preference2.R;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+public class PreferencesFromXml extends PreferenceActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.pref_cb);
+ }
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/SwitchPreferenceTest.java b/tests/tests/preference2/src/android/preference2/cts/SwitchPreferenceTest.java
new file mode 100755
index 0000000..3bd42d2
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/SwitchPreferenceTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.preference2.cts;
+
+import android.content.res.Resources;
+import android.preference.SwitchPreference;
+import android.test.ActivityInstrumentationTestCase2;
+
+import com.android.cts.preference2.R;
+
+public class SwitchPreferenceTest
+ extends ActivityInstrumentationTestCase2<PreferenceFromCodeActivity> {
+
+ private PreferenceFromCodeActivity mActivity;
+ private SwitchPreference mSwitchPref;
+ private Resources mResources;
+
+ public SwitchPreferenceTest() {
+ super(PreferenceFromCodeActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mSwitchPref = (SwitchPreference) mActivity.findPreference(
+ "switch_preference");
+ mResources = mActivity.getResources();
+ }
+
+ public void testGetTitle() {
+ String title = (String) mSwitchPref.getTitle();
+ String titleExp = mResources.getString(R.string.title_switch_preference);
+ assertEquals(titleExp, title);
+ }
+
+ public void testGetSummary() {
+ String summary = (String) mSwitchPref.getSummary();
+ String summaryExp = mResources.getString(R.string.summary_switch_preference);
+ assertEquals(summaryExp, summary);
+ }
+
+ public void testGetSummaryOn() {
+ String summaryOn = (String) mSwitchPref.getSummaryOn();
+ String summaryOnExp = mResources.getString(
+ R.string.summary_on_switch_preference);
+ assertEquals(summaryOnExp, summaryOn);
+ }
+
+ public void testSummaryOff() {
+ String summaryOff = (String) mSwitchPref.getSummaryOff();
+ String summaryOffExp = mResources.getString(
+ R.string.summary_off_switch_preference);
+ assertEquals(summaryOffExp, summaryOff);
+ }
+
+ public void testSetSwitchTextOff_One() throws Throwable {
+ final CharSequence switchOff = "SwitchedOff";
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mSwitchPref.setSwitchTextOff(switchOff);
+ }
+ });
+ CharSequence switchOffExp = mSwitchPref.getSwitchTextOff();
+ assertEquals(switchOffExp, switchOff);
+ }
+
+ public void testSetSwitchTextOff_Two() throws Throwable {
+ final CharSequence switchOffExp = mResources.getString(
+ R.string.switchtext_off);
+ CharSequence switchOff = mSwitchPref.getSwitchTextOff();
+ assertEquals(switchOffExp, switchOff);
+ }
+
+ public void testSetSwitchTextOn_One() throws Throwable {
+ final CharSequence switchOn = "SwitchedOff";
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mSwitchPref.setSwitchTextOn(switchOn);
+ }
+ });
+ CharSequence switchOnExp = mSwitchPref.getSwitchTextOn();
+ assertEquals(switchOnExp, switchOn);
+ }
+
+ public void testSetSwitchTextOn_Two() throws Throwable {
+ final CharSequence switchOnExp = mResources.getString(
+ R.string.switchtext_on);
+
+ CharSequence switchOn = mSwitchPref.getSwitchTextOn();
+ assertEquals(switchOnExp, switchOn);
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/CalendarTest.java b/tests/tests/provider/src/android/provider/cts/CalendarTest.java
index e453820..f8babeb 100644
--- a/tests/tests/provider/src/android/provider/cts/CalendarTest.java
+++ b/tests/tests/provider/src/android/provider/cts/CalendarTest.java
@@ -1912,7 +1912,8 @@
String[] projection = new String[] { Instances.BEGIN };
if (false) {
- Cursor instances = getInstances(timeZone, rangeStart, rangeEnd, projection);
+ Cursor instances = getInstances(timeZone, rangeStart, rangeEnd, projection,
+ new long[] { calendarId });
dumpInstances(instances, timeZone, "all");
instances.close();
}
@@ -1923,28 +1924,28 @@
// Find all matching "testevent". The search matches on partial strings, so this
// will also pick up "nontestevent".
instances = getInstancesSearch(timeZone, rangeStart, rangeEnd,
- "testevent", false, projection);
+ "testevent", false, projection, new long[] { calendarId });
count = instances.getCount();
instances.close();
assertEquals(4, count);
// Find all matching "fiddle" and "event". Set the "by day" flag just to be different.
instances = getInstancesSearch(timeZone, rangeStart, rangeEnd,
- "fiddle event", true, projection);
+ "fiddle event", true, projection, new long[] { calendarId });
count = instances.getCount();
instances.close();
assertEquals(2, count);
// Find all matching "fiddle" and "baluchitherium".
instances = getInstancesSearch(timeZone, rangeStart, rangeEnd,
- "baluchitherium fiddle", false, projection);
+ "baluchitherium fiddle", false, projection, new long[] { calendarId });
count = instances.getCount();
instances.close();
assertEquals(0, count);
// Find all matching "event-two".
instances = getInstancesSearch(timeZone, rangeStart, rangeEnd,
- "event-two", false, projection);
+ "event-two", false, projection, new long[] { calendarId });
count = instances.getCount();
instances.close();
assertEquals(1, count);
@@ -2231,10 +2232,10 @@
// Check to see if we have the expected number of instances
String timeZone = eventValues.getAsString(Events.EVENT_TIMEZONE);
int instanceCount = getInstanceCount(timeZone, "2003-08-05T00:00:00",
- "2003-08-31T11:59:59");
+ "2003-08-31T11:59:59", new long[] { calendarId });
if (false) {
Cursor instances = getInstances(timeZone, "2003-08-05T00:00:00", "2003-08-31T11:59:59",
- new String[] { Instances.BEGIN });
+ new String[] { Instances.BEGIN }, new long[] { calendarId });
dumpInstances(instances, timeZone, "initial");
instances.close();
}
@@ -2318,7 +2319,8 @@
String testEnd = "1999-05-16T23:59:59";
String[] projection = { Instances.BEGIN, Instances.START_MINUTE, Instances.END_MINUTE };
- Cursor instances = getInstances(timeZone, testStart, testEnd, projection);
+ Cursor instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "initial");
}
@@ -2363,7 +2365,8 @@
// TODO: compare Reminders, Attendees, ExtendedProperties on one of the exception events
// Re-query the instances and figure out if they look right.
- instances = getInstances(timeZone, testStart, testEnd, projection);
+ instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "with DTSTART exceptions");
}
@@ -2388,7 +2391,8 @@
assertEquals("events deleted", 3, deleteCount);
// Re-query the instances and figure out if they look right.
- instances = getInstances(timeZone, testStart, testEnd, projection);
+ instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "post exception deletion");
}
@@ -2409,7 +2413,8 @@
* Repeat the test, this time modifying DURATION.
*/
- instances = getInstances(timeZone, testStart, testEnd, projection);
+ instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "initial");
}
@@ -2446,7 +2451,8 @@
// TODO: make sure the selfAttendeeStatus change took
// Re-query the instances and figure out if they look right.
- instances = getInstances(timeZone, testStart, testEnd, projection);
+ instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "with DURATION exceptions");
}
@@ -2502,7 +2508,8 @@
// Add some attendees.
addAttendees(account, eventId, seed);
- Cursor instances = getInstances(timeZone, testStart, testEnd, projection);
+ Cursor instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "initial");
}
@@ -2532,7 +2539,8 @@
instances.close();
// Re-query the instances and figure out if they look right.
- instances = getInstances(timeZone, testStart, testEnd, projection);
+ instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "with exceptions");
}
@@ -2669,7 +2677,8 @@
// Check to see how many instances we get. If the recurrence and the exception don't
// get paired up correctly, we'll see too many instances.
- Cursor instances = getInstances(timeZone, testStart, testEnd, projection);
+ Cursor instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId1, calendarId2 });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "with exception");
}
@@ -2756,7 +2765,8 @@
String testEnd = "1999-01-29T23:59:59";
String[] projection = { Instances.BEGIN, Instances.START_MINUTE };
- Cursor instances = getInstances(timeZone, testStart, testEnd, projection);
+ Cursor instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "initial");
}
@@ -2780,7 +2790,8 @@
// Check to see if it took.
- instances = getInstances(timeZone, testStart, testEnd, projection);
+ instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "with new rule");
}
@@ -2849,7 +2860,8 @@
String[] projection = { Instances.BEGIN, Instances.EVENT_LOCATION };
String newLocation = "NEW!";
- Cursor instances = getInstances(timeZone, testStart, testEnd, projection);
+ Cursor instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "initial");
}
@@ -2867,7 +2879,8 @@
// Check results.
assertEquals("full update does not create new ID", eventId, excepEventId);
- instances = getInstances(timeZone, testStart, testEnd, projection);
+ instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
assertEquals("post-update instance count", 3, instances.getCount());
while (instances.moveToNext()) {
assertEquals("new location", newLocation, instances.getString(1));
@@ -2940,7 +2953,7 @@
* @return Cursor with instances (caller should close when done)
*/
private Cursor getInstances(String timeZone, String startWhen, String endWhen,
- String[] projection) {
+ String[] projection, long[] calendarIds) {
Time startTime = new Time(timeZone);
startTime.parse3339(startWhen);
long startMillis = startTime.toMillis(false);
@@ -2954,7 +2967,16 @@
Uri uri = Uri.withAppendedPath(CalendarContract.Instances.CONTENT_URI,
startMillis + "/" + endMillis);
- Cursor instances = mContentResolver.query(uri, projection, null, null,
+ String where = null;
+ for (int i = 0; i < calendarIds.length; i++) {
+ if (i > 0) {
+ where += " OR ";
+ } else {
+ where = "";
+ }
+ where += (Instances.CALENDAR_ID + "=" + calendarIds[i]);
+ }
+ Cursor instances = mContentResolver.query(uri, projection, where, null,
projection[0] + " ASC");
return instances;
@@ -2975,7 +2997,7 @@
* @return Cursor with instances (caller should close when done)
*/
private Cursor getInstancesSearch(String timeZone, String startWhen, String endWhen,
- String search, boolean searchByDay, String[] projection) {
+ String search, boolean searchByDay, String[] projection, long[] calendarIds) {
Time startTime = new Time(timeZone);
startTime.parse3339(startWhen);
long startMillis = startTime.toMillis(false);
@@ -2996,10 +3018,19 @@
startMillis + "/" + endMillis + "/" + search);
}
+ String where = null;
+ for (int i = 0; i < calendarIds.length; i++) {
+ if (i > 0) {
+ where += " OR ";
+ } else {
+ where = "";
+ }
+ where += (Instances.CALENDAR_ID + "=" + calendarIds[i]);
+ }
// We want a list of instances that occur between the specified dates and that match
// the search terms.
- Cursor instances = mContentResolver.query(uri, projection, null, null,
+ Cursor instances = mContentResolver.query(uri, projection, where, null,
projection[0] + " ASC");
return instances;
@@ -3031,9 +3062,10 @@
/**
* Counts the number of instances that appear between the specified start and end times.
*/
- private int getInstanceCount(String timeZone, String startWhen, String endWhen) {
+ private int getInstanceCount(String timeZone, String startWhen, String endWhen,
+ long[] calendarIds) {
Cursor instances = getInstances(timeZone, startWhen, endWhen,
- new String[] { Instances._ID });
+ new String[] { Instances._ID }, calendarIds);
int count = instances.getCount();
instances.close();
return count;
@@ -3194,7 +3226,8 @@
assertTrue(eventId >= 0);
String[] projection = { Instances.BEGIN, Instances.START_MINUTE };
- Cursor instances = getInstances(timeZone, testStart, testEnd, projection);
+ Cursor instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "prep-create");
}
@@ -3204,7 +3237,8 @@
Uri eventUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId);
removeAndVerifyEvent(eventUri, new ContentValues(eventValues), account);
- instances = getInstances(timeZone, testStart, testEnd, projection);
+ instances = getInstances(timeZone, testStart, testEnd, projection,
+ new long[] { calendarId });
if (DEBUG_RECURRENCE) {
dumpInstances(instances, timeZone, "prep-clear");
}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_EmailTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_EmailTest.java
new file mode 100644
index 0000000..3f4bd7e
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_EmailTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.res.Resources;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.test.AndroidTestCase;
+
+public class ContactsContract_CommonDataKinds_EmailTest extends AndroidTestCase {
+
+ private Resources mResources;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResources = mContext.getResources();
+ }
+
+ public void testGetTypeLabel() {
+ assertGetTypeLabel(Email.TYPE_HOME);
+ assertGetTypeLabel(Email.TYPE_MOBILE);
+ assertGetTypeLabel(Email.TYPE_OTHER);
+ assertGetTypeLabel(Email.TYPE_WORK);
+ assertGetTypeLabel(Email.TYPE_CUSTOM);
+ assertCustomTypeLabel("Custom Label");
+ }
+
+ private void assertGetTypeLabel(int type) {
+ int res = Email.getTypeLabelResource(type);
+ assertTrue(res != 0);
+
+ String label = mResources.getString(res);
+ assertEquals(label, Email.getTypeLabel(mResources, type, ""));
+ }
+
+ private void assertCustomTypeLabel(String label) {
+ int res = Email.getTypeLabelResource(Email.TYPE_CUSTOM);
+ assertTrue(res != 0);
+ assertEquals(label, Email.getTypeLabel(mResources, Email.TYPE_CUSTOM, label));
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_EventTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_EventTest.java
new file mode 100644
index 0000000..b996ad2
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_EventTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.cts;
+
+import android.provider.ContactsContract.CommonDataKinds.Event;
+import android.test.AndroidTestCase;
+
+public class ContactsContract_CommonDataKinds_EventTest extends AndroidTestCase {
+
+ public void testGetTypeLabel() {
+ assertGetTypeLabel(Event.TYPE_ANNIVERSARY);
+ assertGetTypeLabel(Event.TYPE_BIRTHDAY);
+ assertGetTypeLabel(Event.TYPE_OTHER);
+ assertGetTypeLabel(Event.TYPE_CUSTOM);
+ assertGetTypeLabel(null);
+ }
+
+ private void assertGetTypeLabel(Integer type) {
+ int res = Event.getTypeResource(type);
+ assertTrue(res != 0);
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_ImTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_ImTest.java
new file mode 100644
index 0000000..eacceaa
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_ImTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.res.Resources;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.test.AndroidTestCase;
+
+public class ContactsContract_CommonDataKinds_ImTest extends AndroidTestCase {
+
+ private Resources mResources;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResources = mContext.getResources();
+ }
+
+ public void testGetProtocolLabel() {
+ assertGetProtocolLabel(Im.PROTOCOL_AIM);
+ assertGetProtocolLabel(Im.PROTOCOL_CUSTOM);
+ assertGetProtocolLabel(Im.PROTOCOL_GOOGLE_TALK);
+ assertGetProtocolLabel(Im.PROTOCOL_ICQ);
+ assertGetProtocolLabel(Im.PROTOCOL_JABBER);
+ assertGetProtocolLabel(Im.PROTOCOL_MSN);
+ assertGetProtocolLabel(Im.PROTOCOL_NETMEETING);
+ assertGetProtocolLabel(Im.PROTOCOL_QQ);
+ assertGetProtocolLabel(Im.PROTOCOL_SKYPE);
+ assertGetProtocolLabel(Im.PROTOCOL_YAHOO);
+ assertCustomProtocolLabel("Custom Label");
+ }
+
+ public void testGetTypeLabel() {
+ assertGetTypeLabel(Im.TYPE_HOME);
+ assertGetTypeLabel(Im.TYPE_WORK);
+ assertGetTypeLabel(Im.TYPE_OTHER);
+ assertGetTypeLabel(Im.TYPE_CUSTOM);
+ assertCustomTypeLabel("Custom Label");
+ }
+
+ private void assertGetProtocolLabel(int type) {
+ int res = Im.getProtocolLabelResource(type);
+ assertTrue(res != 0);
+
+ String label = mResources.getString(res);
+ assertEquals(label, Im.getProtocolLabel(mResources, type, ""));
+ }
+
+ private void assertCustomProtocolLabel(String label) {
+ int res = Im.getProtocolLabelResource(Im.PROTOCOL_CUSTOM);
+ assertTrue(res != 0);
+ assertEquals(label, Im.getProtocolLabel(mResources, Im.PROTOCOL_CUSTOM, label));
+ }
+
+ private void assertGetTypeLabel(int type) {
+ int res = Im.getTypeLabelResource(type);
+ assertTrue(res != 0);
+
+ String label = mResources.getString(res);
+ assertEquals(label, Im.getTypeLabel(mResources, type, ""));
+ }
+
+ private void assertCustomTypeLabel(String label) {
+ int res = Im.getTypeLabelResource(Im.TYPE_CUSTOM);
+ assertTrue(res != 0);
+ assertEquals(label, Im.getTypeLabel(mResources, Im.TYPE_CUSTOM, label));
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_OrganizationTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_OrganizationTest.java
new file mode 100644
index 0000000..2de3b05
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_OrganizationTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.res.Resources;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.test.AndroidTestCase;
+
+public class ContactsContract_CommonDataKinds_OrganizationTest extends AndroidTestCase {
+
+ private Resources mResources;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResources = mContext.getResources();
+ }
+
+ public void testGetTypeLabel() {
+ assertGetTypeLabel(Organization.TYPE_WORK);
+ assertGetTypeLabel(Organization.TYPE_OTHER);
+ assertGetTypeLabel(Organization.TYPE_CUSTOM);
+ assertCustomTypeLabel("Custom Label");
+ }
+
+ private void assertGetTypeLabel(int type) {
+ int res = Organization.getTypeLabelResource(type);
+ assertTrue(res != 0);
+
+ String label = mResources.getString(res);
+ assertEquals(label, Organization.getTypeLabel(mResources, type, ""));
+ }
+
+ private void assertCustomTypeLabel(String label) {
+ int res = Organization.getTypeLabelResource(Im.TYPE_CUSTOM);
+ assertTrue(res != 0);
+ assertEquals(label, Organization.getTypeLabel(mResources, Im.TYPE_CUSTOM, label));
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_PhoneTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_PhoneTest.java
new file mode 100644
index 0000000..433a32e
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_PhoneTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.res.Resources;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.test.AndroidTestCase;
+
+public class ContactsContract_CommonDataKinds_PhoneTest extends AndroidTestCase {
+
+ private Resources mResources;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResources = mContext.getResources();
+ }
+
+ public void testGetTypeLabel() {
+ assertGetTypeLabel(Phone.TYPE_ASSISTANT);
+ assertGetTypeLabel(Phone.TYPE_CALLBACK);
+ assertGetTypeLabel(Phone.TYPE_CAR);
+ assertGetTypeLabel(Phone.TYPE_COMPANY_MAIN);
+ assertGetTypeLabel(Phone.TYPE_FAX_HOME);
+ assertGetTypeLabel(Phone.TYPE_FAX_WORK);
+ assertGetTypeLabel(Phone.TYPE_HOME);
+ assertGetTypeLabel(Phone.TYPE_ISDN);
+ assertGetTypeLabel(Phone.TYPE_MAIN);
+ assertGetTypeLabel(Phone.TYPE_MMS);
+ assertGetTypeLabel(Phone.TYPE_MOBILE);
+ assertGetTypeLabel(Phone.TYPE_OTHER);
+ assertGetTypeLabel(Phone.TYPE_OTHER_FAX);
+ assertGetTypeLabel(Phone.TYPE_PAGER);
+ assertGetTypeLabel(Phone.TYPE_RADIO);
+ assertGetTypeLabel(Phone.TYPE_TELEX);
+ assertGetTypeLabel(Phone.TYPE_TTY_TDD);
+ assertGetTypeLabel(Phone.TYPE_WORK);
+ assertGetTypeLabel(Phone.TYPE_WORK_MOBILE);
+ assertGetTypeLabel(Phone.TYPE_WORK_PAGER);
+ assertGetTypeLabel(Phone.TYPE_CUSTOM);
+ assertCustomTypeLabel("Custom Label");
+ }
+
+ private void assertGetTypeLabel(int type) {
+ int res = Phone.getTypeLabelResource(type);
+ assertTrue(res != 0);
+
+ String label = mResources.getString(res);
+ assertEquals(label, Phone.getTypeLabel(mResources, type, ""));
+ }
+
+ private void assertCustomTypeLabel(String label) {
+ int res = Phone.getTypeLabelResource(Phone.TYPE_CUSTOM);
+ assertTrue(res != 0);
+ assertEquals(label, Phone.getTypeLabel(mResources, Phone.TYPE_CUSTOM, label));
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_RelationTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_RelationTest.java
new file mode 100644
index 0000000..f5e27ce
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_RelationTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.res.Resources;
+import android.provider.ContactsContract.CommonDataKinds.Relation;
+import android.test.AndroidTestCase;
+
+public class ContactsContract_CommonDataKinds_RelationTest extends AndroidTestCase {
+
+ private Resources mResources;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResources = mContext.getResources();
+ }
+
+ public void testGetTypeLabel() {
+ assertGetTypeLabel(Relation.TYPE_ASSISTANT);
+ assertGetTypeLabel(Relation.TYPE_BROTHER);
+ assertGetTypeLabel(Relation.TYPE_CHILD);
+ assertGetTypeLabel(Relation.TYPE_DOMESTIC_PARTNER);
+ assertGetTypeLabel(Relation.TYPE_FATHER);
+ assertGetTypeLabel(Relation.TYPE_FRIEND);
+ assertGetTypeLabel(Relation.TYPE_MANAGER);
+ assertGetTypeLabel(Relation.TYPE_MOTHER);
+ assertGetTypeLabel(Relation.TYPE_PARENT);
+ assertGetTypeLabel(Relation.TYPE_PARTNER);
+ assertGetTypeLabel(Relation.TYPE_REFERRED_BY);
+ assertGetTypeLabel(Relation.TYPE_RELATIVE);
+ assertGetTypeLabel(Relation.TYPE_SISTER);
+ assertGetTypeLabel(Relation.TYPE_SPOUSE);
+ assertGetTypeLabel(Relation.TYPE_CUSTOM);
+ assertCustomTypeLabel("Custom Label");
+ }
+
+ private void assertGetTypeLabel(int type) {
+ int res = Relation.getTypeLabelResource(type);
+ assertTrue(res != 0);
+
+ String label = mResources.getString(res);
+ assertEquals(label, Relation.getTypeLabel(mResources, type, ""));
+ }
+
+ private void assertCustomTypeLabel(String label) {
+ int res = Relation.getTypeLabelResource(Relation.TYPE_CUSTOM);
+ assertTrue(res != 0);
+ assertEquals(label, Relation.getTypeLabel(mResources, Relation.TYPE_CUSTOM, label));
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_SipAddressTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_SipAddressTest.java
new file mode 100644
index 0000000..1406b40
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_SipAddressTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.res.Resources;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
+import android.test.AndroidTestCase;
+
+public class ContactsContract_CommonDataKinds_SipAddressTest extends AndroidTestCase {
+
+ private Resources mResources;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResources = mContext.getResources();
+ }
+
+ public void testGetTypeLabel() {
+ assertGetTypeLabel(SipAddress.TYPE_HOME);
+ assertGetTypeLabel(SipAddress.TYPE_OTHER);
+ assertGetTypeLabel(SipAddress.TYPE_WORK);
+ assertGetTypeLabel(SipAddress.TYPE_CUSTOM);
+ assertCustomTypeLabel("Custom Label");
+ }
+
+ private void assertGetTypeLabel(int type) {
+ int res = SipAddress.getTypeLabelResource(type);
+ assertTrue(res != 0);
+
+ String label = mResources.getString(res);
+ assertEquals(label, SipAddress.getTypeLabel(mResources, type, ""));
+ }
+
+ private void assertCustomTypeLabel(String label) {
+ int res = SipAddress.getTypeLabelResource(SipAddress.TYPE_CUSTOM);
+ assertTrue(res != 0);
+ assertEquals(label, SipAddress.getTypeLabel(mResources, SipAddress.TYPE_CUSTOM, label));
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_StructuredPostalTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_StructuredPostalTest.java
new file mode 100644
index 0000000..18a64ce
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_CommonDataKinds_StructuredPostalTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.res.Resources;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.test.AndroidTestCase;
+
+public class ContactsContract_CommonDataKinds_StructuredPostalTest extends AndroidTestCase {
+
+ private Resources mResources;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResources = mContext.getResources();
+ }
+
+ public void testGetTypeLabel() {
+ assertGetTypeLabel(StructuredPostal.TYPE_HOME);
+ assertGetTypeLabel(StructuredPostal.TYPE_OTHER);
+ assertGetTypeLabel(StructuredPostal.TYPE_WORK);
+ assertGetTypeLabel(StructuredPostal.TYPE_CUSTOM);
+ assertCustomTypeLabel("Custom Label");
+ }
+
+ private void assertGetTypeLabel(int type) {
+ int res = StructuredPostal.getTypeLabelResource(type);
+ assertTrue(res != 0);
+
+ String label = mResources.getString(res);
+ assertEquals(label, StructuredPostal.getTypeLabel(mResources, type, ""));
+ }
+
+ private void assertCustomTypeLabel(String label) {
+ int res = StructuredPostal.getTypeLabelResource(StructuredPostal.TYPE_CUSTOM);
+ assertTrue(res != 0);
+ assertEquals(label, StructuredPostal.getTypeLabel(mResources,
+ StructuredPostal.TYPE_CUSTOM, label));
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java
index a3c6a25..2220d96 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java
@@ -16,17 +16,15 @@
package android.provider.cts;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
import android.app.Instrumentation;
import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.Context;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
@@ -35,7 +33,6 @@
import java.util.List;
-@TestTargetClass(ContactsContract.Contacts.class)
public class ContactsContract_ContactsTest extends InstrumentationTestCase {
private ContentResolver mContentResolver;
private ContactsContract_TestDataBuilder mBuilder;
@@ -54,12 +51,6 @@
mBuilder.cleanup();
}
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Test markAsContacted(ContentResolver resolver, long contactId)",
- method = "markAsContacted",
- args = {android.content.ContentResolver.class, long.class}
- )
public void testMarkAsContacted() throws Exception {
TestRawContact rawContact = mBuilder.newRawContact().insert().load();
TestContact contact = rawContact.getContact().load();
@@ -88,5 +79,24 @@
assertFalse("Device does not support the activity intent: " + intent,
resolveInfos.isEmpty());
}
+
+ public void testLookupUri() throws Exception {
+ TestRawContact rawContact = mBuilder.newRawContact().insert().load();
+ TestContact contact = rawContact.getContact().load();
+
+ Uri contactUri = contact.getUri();
+ long contactId = contact.getId();
+ String lookupKey = contact.getString(Contacts.LOOKUP_KEY);
+
+ Uri lookupUri = Contacts.getLookupUri(contactId, lookupKey);
+ assertEquals(ContentUris.withAppendedId(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
+ lookupKey), contactId), lookupUri);
+
+ Uri lookupUri2 = Contacts.getLookupUri(mContentResolver, contactUri);
+ assertEquals(lookupUri, lookupUri2);
+
+ Uri contactUri2 = Contacts.lookupContact(mContentResolver, lookupUri);
+ assertEquals(contactUri, contactUri2);
+ }
}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_PhotoTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_PhotoTest.java
index 68ed1b8..edab42f 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_PhotoTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_PhotoTest.java
@@ -22,6 +22,8 @@
import android.content.IContentProvider;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.Contacts;
+import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
import android.provider.cts.ContactsContract_TestDataBuilder.TestData;
import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
import android.test.InstrumentationTestCase;
@@ -35,12 +37,13 @@
private static final byte[] EMPTY_TEST_PHOTO_DATA = "".getBytes();
+ private ContentResolver mResolver;
+
@Override
protected void setUp() throws Exception {
super.setUp();
- ContentResolver contentResolver =
- getInstrumentation().getTargetContext().getContentResolver();
- IContentProvider provider = contentResolver.acquireProvider(ContactsContract.AUTHORITY);
+ mResolver = getInstrumentation().getTargetContext().getContentResolver();
+ IContentProvider provider = mResolver.acquireProvider(ContactsContract.AUTHORITY);
mBuilder = new ContactsContract_TestDataBuilder(provider);
}
@@ -51,7 +54,13 @@
}
public void testAddPhoto() throws Exception {
- TestRawContact rawContact = mBuilder.newRawContact().insert();
+ TestRawContact rawContact = mBuilder.newRawContact().insert().load();
+ TestContact contact = rawContact.getContact().load();
+
+ assertNull(Contacts.openContactPhotoInputStream(mResolver, contact.getUri()));
+ assertNull(Contacts.openContactPhotoInputStream(mResolver, contact.getUri(), true));
+ assertNull(Contacts.openContactPhotoInputStream(mResolver, contact.getUri(), false));
+
TestData photoData = rawContact.newDataRow(Photo.CONTENT_ITEM_TYPE)
.with(Photo.PHOTO, getTestPhotoData())
.insert();
@@ -59,14 +68,28 @@
photoData.load();
photoData.assertColumn(Photo.RAW_CONTACT_ID, rawContact.getId());
photoData.assertBlobColumnNotNull(Photo.PHOTO);
+
+ assertPhotoStream(Contacts.openContactPhotoInputStream(mResolver, contact.getUri()));
+ assertPhotoStream(Contacts.openContactPhotoInputStream(mResolver, contact.getUri(), true));
+ assertPhotoStream(Contacts.openContactPhotoInputStream(mResolver, contact.getUri(), false));
}
public void testAddEmptyPhoto() throws Exception {
- TestRawContact rawContact = mBuilder.newRawContact().insert();
+ TestRawContact rawContact = mBuilder.newRawContact().insert().load();
+ TestContact contact = rawContact.getContact().load();
+
+ assertNull(Contacts.openContactPhotoInputStream(mResolver, contact.getUri()));
+ assertNull(Contacts.openContactPhotoInputStream(mResolver, contact.getUri(), true));
+ assertNull(Contacts.openContactPhotoInputStream(mResolver, contact.getUri(), false));
+
TestData photoData = rawContact.newDataRow(Photo.CONTENT_ITEM_TYPE)
.with(Photo.PHOTO, EMPTY_TEST_PHOTO_DATA)
.insert();
assertNotNull(photoData.load());
+
+ assertNull(Contacts.openContactPhotoInputStream(mResolver, contact.getUri()));
+ assertNull(Contacts.openContactPhotoInputStream(mResolver, contact.getUri(), true));
+ assertNull(Contacts.openContactPhotoInputStream(mResolver, contact.getUri(), false));
}
private byte[] getTestPhotoData() {
@@ -89,5 +112,17 @@
}
return os.toByteArray();
}
+
+ private void assertPhotoStream(InputStream photoStream) throws IOException {
+ try {
+ assertNotNull(photoStream);
+ byte[] actualBytes = readInputStreamFully(photoStream);
+ assertTrue(actualBytes.length > 0);
+ } finally {
+ if (photoStream != null) {
+ photoStream.close();
+ }
+ }
+ }
}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_StatusUpdatesTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_StatusUpdatesTest.java
new file mode 100644
index 0000000..2f3cdeb
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_StatusUpdatesTest.java
@@ -0,0 +1,189 @@
+/*
+ * 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.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.StatusUpdates;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+
+public class ContactsContract_StatusUpdatesTest extends AndroidTestCase {
+
+ private static final String ACCOUNT_TYPE = "com.android.cts.provider";
+ private static final String ACCOUNT_NAME = "ContactsContract_StatusUpdatesTest";
+
+ private ContentResolver mResolver;
+ private long dataId;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResolver = mContext.getContentResolver();
+
+ ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+
+ ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
+ .withValue(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
+ .withValue(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
+ .build());
+
+ ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
+ .withValueBackReference(Data.RAW_CONTACT_ID, 0)
+ .withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE)
+ .withValue(Im.TYPE, Im.TYPE_HOME)
+ .withValue(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK)
+ .build());
+
+ ContentProviderResult[] results = mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+ assertNotNull(results[0].uri);
+ assertNotNull(results[1].uri);
+
+ dataId = ContentUris.parseId(results[1].uri);
+ }
+
+ public void testInsertStatus() throws Exception {
+ Uri uri = insertStatusUpdate(dataId, StatusUpdates.DO_NOT_DISTURB, null, null);
+ assertPresence(uri, StatusUpdates.DO_NOT_DISTURB);
+ assertStatus(uri, null);
+ assertHasTimestamp(uri, false);
+ assertRowCount(uri, 1);
+
+ Uri uri2 = insertStatusUpdate(dataId, StatusUpdates.AVAILABLE, null, null);
+ assertEquals(uri, uri2);
+
+ assertPresence(uri, StatusUpdates.AVAILABLE);
+ assertStatus(uri, null);
+ assertHasTimestamp(uri, false);
+ assertRowCount(uri, 1);
+
+ Uri uri3 = insertStatusUpdate(dataId, StatusUpdates.AWAY, "Grabbing a byte", null);
+ assertEquals(uri2, uri3);
+
+ assertPresence(uri, StatusUpdates.AWAY);
+ assertStatus(uri, "Grabbing a byte");
+ assertHasTimestamp(uri, false);
+ assertRowCount(uri, 1);
+
+ // Inserting a new status message causes a timestamp to be inserted
+ Uri uri4 = insertStatusUpdate(dataId, StatusUpdates.IDLE, "Taking a bit of a break", null);
+ assertEquals(uri3, uri4);
+
+ assertPresence(uri, StatusUpdates.IDLE);
+ assertStatus(uri, "Taking a bit of a break");
+ assertHasTimestamp(uri, true);
+ assertRowCount(uri, 1);
+ }
+
+ private Uri insertStatusUpdate(long dataId, int presence, String status, Long timestamp)
+ throws Exception {
+ ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+ ops.add(ContentProviderOperation.newInsert(StatusUpdates.CONTENT_URI)
+ .withValue(StatusUpdates.DATA_ID, dataId)
+ .withValue(StatusUpdates.PRESENCE, presence)
+ .withValue(StatusUpdates.STATUS, status)
+ .withValue(StatusUpdates.STATUS_TIMESTAMP, timestamp)
+ .withValue(StatusUpdates.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK)
+ .withValue(StatusUpdates.IM_HANDLE, "mrBugDroid1337")
+ .build());
+
+ ContentProviderResult[] results = mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+ assertNotNull(results[0].uri);
+ return results[0].uri;
+ }
+
+ private void assertRowCount(Uri uri, int count) throws Exception {
+ ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+ ops.add(ContentProviderOperation.newAssertQuery(uri)
+ .withExpectedCount(count)
+ .build());
+
+ mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+ }
+
+ private void assertPresence(Uri uri, int status) throws Exception {
+ ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+ ops.add(ContentProviderOperation.newAssertQuery(uri)
+ .withValue(StatusUpdates.PRESENCE, status)
+ .withExpectedCount(1)
+ .build());
+
+ mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+ }
+
+ private void assertStatus(Uri uri, String status) throws Exception {
+ ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+ ops.add(ContentProviderOperation.newAssertQuery(uri)
+ .withValue(StatusUpdates.STATUS, status)
+ .withExpectedCount(1)
+ .build());
+
+ mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+ }
+
+ private void assertHasTimestamp(Uri uri, boolean hasTimestmap) throws Exception {
+ Cursor cursor = mResolver.query(uri, null, null, null, null);
+ try {
+ assertTrue(cursor.moveToNext());
+
+ if (hasTimestmap) {
+ assertNotNull(cursor.getString(cursor.getColumnIndexOrThrow(
+ StatusUpdates.STATUS_TIMESTAMP)));
+ } else {
+ assertNull(cursor.getString(cursor.getColumnIndexOrThrow(
+ StatusUpdates.STATUS_TIMESTAMP)));
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ public void testGetPresencePrecedence() {
+ assertPrecedence(StatusUpdates.AVAILABLE);
+ assertPrecedence(StatusUpdates.AWAY);
+ assertPrecedence(StatusUpdates.DO_NOT_DISTURB);
+ assertPrecedence(StatusUpdates.IDLE);
+ assertPrecedence(StatusUpdates.INVISIBLE);
+ assertPrecedence(StatusUpdates.OFFLINE);
+ }
+
+ private void assertPrecedence(int status) {
+ assertTrue(StatusUpdates.getPresencePrecedence(status) >= 0);
+ }
+
+ public void testGetPresenceIconresourceId() {
+ assertResource(StatusUpdates.AVAILABLE);
+ assertResource(StatusUpdates.AWAY);
+ assertResource(StatusUpdates.DO_NOT_DISTURB);
+ assertResource(StatusUpdates.IDLE);
+ assertResource(StatusUpdates.INVISIBLE);
+ assertResource(StatusUpdates.OFFLINE);
+ }
+
+ private void assertResource(int status) {
+ assertTrue(0 != StatusUpdates.getPresenceIconResourceId(status));
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_StreamItemsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_StreamItemsTest.java
new file mode 100644
index 0000000..5ca04ab
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_StreamItemsTest.java
@@ -0,0 +1,174 @@
+/*
+ * 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.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.StreamItems;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+
+public class ContactsContract_StreamItemsTest extends AndroidTestCase {
+
+ private static final String ACCOUNT_TYPE = "com.android.cts";
+ private static final String ACCOUNT_NAME = "ContactsContract_StreamItemsTest";
+
+ private static final String INSERT_TEXT = "Wrote a test for the StreamItems class";
+ private static final long INSERT_TIMESTAMP = 3007;
+ private static final String INSERT_COMMENTS = "1337 people reshared this";
+
+ private static final String UPDATE_TEXT = "Wrote more tests for the StreamItems class";
+ private static final long UPDATE_TIMESTAMP = 8008;
+ private static final String UPDATE_COMMENTS = "3007 people reshared this";
+
+ private ContentResolver mResolver;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResolver = mContext.getContentResolver();
+ }
+
+ public void testContentDirectoryUri() throws Exception {
+ // Create a contact to attach the stream item to it.
+ ContentValues values = new ContentValues();
+ values.put(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE);
+ values.put(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME);
+
+ Uri contactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
+ long rawContactId = ContentUris.parseId(contactUri);
+ assertTrue(rawContactId != -1);
+
+ // Attach a stream item to the contact.
+ values.clear();
+ values.put(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE);
+ values.put(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME);
+ values.put(StreamItems.TEXT, INSERT_TEXT);
+ values.put(StreamItems.TIMESTAMP, INSERT_TIMESTAMP);
+ values.put(StreamItems.COMMENTS, INSERT_COMMENTS);
+
+ Uri contactStreamUri = Uri.withAppendedPath(
+ ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
+ RawContacts.StreamItems.CONTENT_DIRECTORY);
+ Uri streamItemUri = mResolver.insert(contactStreamUri, values);
+ long streamItemId = ContentUris.parseId(streamItemUri);
+ assertTrue(streamItemId != -1);
+
+ // Check that the provider returns the stream id in it's URI.
+ assertEquals(streamItemUri,
+ ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId).buildUpon()
+ .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY)
+ .appendPath(Long.toString(streamItemId))
+ .build());
+
+ // Check that the provider stored what we put into it.
+ assertInsertedItem(streamItemUri);
+
+ // Update the stream item.
+ values.clear();
+ values.put(Data.RAW_CONTACT_ID, rawContactId);
+ values.put(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE);
+ values.put(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME);
+ values.put(StreamItems.TEXT, UPDATE_TEXT);
+ values.put(StreamItems.TIMESTAMP, UPDATE_TIMESTAMP);
+ values.put(StreamItems.COMMENTS, UPDATE_COMMENTS);
+
+ assertEquals(1, mResolver.update(streamItemUri, values, null, null));
+ assertUpdatedItem(streamItemUri);
+ }
+
+ public void testContentUri() throws Exception {
+ // Create a contact with one stream item in it.
+ ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+
+ ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
+ .withValue(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
+ .withValue(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
+ .build());
+
+ ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_URI)
+ .withValueBackReference(Data.RAW_CONTACT_ID, 0)
+ .withValue(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
+ .withValue(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
+ .withValue(StreamItems.TEXT, INSERT_TEXT)
+ .withValue(StreamItems.TIMESTAMP, INSERT_TIMESTAMP)
+ .withValue(StreamItems.COMMENTS, INSERT_COMMENTS)
+ .build());
+
+ ContentProviderResult[] results = mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+ long rawContactId = ContentUris.parseId(results[0].uri);
+ assertTrue(rawContactId != -1);
+
+ Uri streamItemUri = results[1].uri;
+ long streamItemId = ContentUris.parseId(streamItemUri);
+ assertTrue(streamItemId != -1);
+
+ // Check that the provider returns the stream id in it's URI.
+ assertEquals(streamItemUri,
+ ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId));
+
+ // Check that the provider stored what we put into it.
+ assertInsertedItem(streamItemUri);
+
+ // Update the stream item.
+ ops.clear();
+ ops.add(ContentProviderOperation.newUpdate(streamItemUri)
+ .withValue(Data.RAW_CONTACT_ID, rawContactId)
+ .withValue(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
+ .withValue(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
+ .withValue(StreamItems.TEXT, UPDATE_TEXT)
+ .withValue(StreamItems.TIMESTAMP, UPDATE_TIMESTAMP)
+ .withValue(StreamItems.COMMENTS, UPDATE_COMMENTS)
+ .build());
+
+ results = mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+ assertEquals(Integer.valueOf(1), results[0].count);
+ assertUpdatedItem(streamItemUri);
+ }
+
+ private void assertInsertedItem(Uri itemUri) {
+ assertStreamItem(itemUri, INSERT_TEXT, INSERT_TIMESTAMP, INSERT_COMMENTS);
+ }
+
+ private void assertUpdatedItem(Uri itemUri) {
+ assertStreamItem(itemUri, UPDATE_TEXT, UPDATE_TIMESTAMP, UPDATE_COMMENTS);
+ }
+
+ private void assertStreamItem(Uri uri, String text, long timestamp, String comments) {
+ Cursor cursor = mResolver.query(uri, null, null, null, null);
+ try {
+ assertTrue(cursor.moveToFirst());
+ assertEquals(text, cursor.getString(
+ cursor.getColumnIndexOrThrow(StreamItems.TEXT)));
+ assertEquals(timestamp, cursor.getLong(
+ cursor.getColumnIndexOrThrow(StreamItems.TIMESTAMP)));
+ assertEquals(comments, cursor.getString(
+ cursor.getColumnIndexOrThrow(StreamItems.COMMENTS)));
+ } finally {
+ cursor.close();
+ }
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_TestDataBuilder.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_TestDataBuilder.java
index c73830e..e1feda6 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_TestDataBuilder.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_TestDataBuilder.java
@@ -198,6 +198,10 @@
return mCursor.getLong(mCursor.getColumnIndex(columnName));
}
+ public String getString(String columnName) {
+ return mCursor.getString(mCursor.getColumnIndex(columnName));
+ }
+
public void assertColumn(String columnName, long value) {
assertEquals(value, mCursor.getLong(getColumnIndex(columnName)));
}
diff --git a/tests/tests/provider/src/android/provider/cts/Contacts_PeopleTest.java b/tests/tests/provider/src/android/provider/cts/Contacts_PeopleTest.java
index 0f36626..b9d26e6 100644
--- a/tests/tests/provider/src/android/provider/cts/Contacts_PeopleTest.java
+++ b/tests/tests/provider/src/android/provider/cts/Contacts_PeopleTest.java
@@ -40,6 +40,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.List;
@TestTargetClass(android.provider.Contacts.People.class)
public class Contacts_PeopleTest extends InstrumentationTestCase {
@@ -209,9 +210,16 @@
cursor.close();
mRowsAdded.add(People.addToGroup(mContentResolver, personId, groupId));
cursor = People.queryGroups(mContentResolver, personId);
- cursor.moveToFirst();
- assertEquals(personId, cursor.getInt(MEMBERSHIP_PERSON_ID_INDEX));
- assertEquals(groupId, cursor.getInt(MEMBERSHIP_GROUP_ID_INDEX));
+ boolean found = false;
+ while (cursor.moveToNext()) {
+ assertEquals(personId, cursor.getInt(MEMBERSHIP_PERSON_ID_INDEX));
+ if (cursor.getInt(MEMBERSHIP_GROUP_ID_INDEX) == groupId) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(found);
+
cursor.close();
// People: test_people_2, Group: test_group_1
@@ -223,14 +231,24 @@
String groupName = "test_group_1";
mRowsAdded.add(People.addToGroup(mContentResolver, personId, groupName));
cursor = People.queryGroups(mContentResolver, personId);
- cursor.moveToFirst();
- assertEquals(personId, cursor.getInt(MEMBERSHIP_PERSON_ID_INDEX));
- groupId = cursor.getInt(MEMBERSHIP_GROUP_ID_INDEX);
+ List<Integer> groupIds = new ArrayList<Integer>();
+ while (cursor.moveToNext()) {
+ assertEquals(personId, cursor.getInt(MEMBERSHIP_PERSON_ID_INDEX));
+ groupIds.add(cursor.getInt(MEMBERSHIP_GROUP_ID_INDEX));
+ }
cursor.close();
- cursor = mProvider.query(Groups.CONTENT_URI, GROUPS_PROJECTION,
- Groups._ID + "=" + groupId, null, null);
- cursor.moveToFirst();
- assertEquals(groupName, cursor.getString(GROUPS_NAME_INDEX));
+
+ found = false;
+ for (int id : groupIds) {
+ cursor = mProvider.query(Groups.CONTENT_URI, GROUPS_PROJECTION,
+ Groups._ID + "=" + id, null, null);
+ cursor.moveToFirst();
+ if (groupName.equals(cursor.getString(GROUPS_NAME_INDEX))) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(found);
cursor.close();
} catch (RemoteException e) {
fail("Unexpected RemoteException");
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/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
index 8e8d650..5203326 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
@@ -18,11 +18,6 @@
import com.android.cts.stub.R;
-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;
@@ -31,18 +26,14 @@
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
-import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.provider.MediaStore.Images.Thumbnails;
import android.test.InstrumentationTestCase;
import java.io.File;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
import java.util.ArrayList;
-@TestTargetClass(MediaStore.Images.Media.class)
public class MediaStore_Images_MediaTest extends InstrumentationTestCase {
private static final String MIME_TYPE_JPEG = "image/jpeg";
@@ -87,33 +78,7 @@
mRowsAdded = new ArrayList<Uri>();
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "This test will fail if there is no sdcard attached because the method "
- + "{@link Images#Media#insertImage(ContentResolver, String, String, String)} "
- + "will store images on the sdcard",
- method = "insertImage",
- args = {ContentResolver.class, String.class, String.class, String.class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "query",
- args = {ContentResolver.class, Uri.class, String[].class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "query",
- args = {ContentResolver.class, Uri.class, String[].class, String.class, String.class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "query",
- args = {ContentResolver.class, Uri.class, String[].class, String.class, String[].class,
- String.class}
- )
- })
- public void testInsertImageWithImagePath() {
+ public void testInsertImageWithImagePath() throws Exception {
Cursor c = Media.query(mContentResolver, Media.EXTERNAL_CONTENT_URI, null, null,
"_id ASC");
int previousCount = c.getCount();
@@ -184,21 +149,7 @@
c.close();
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "This test will fail if there is no sdcard attached because the method "
- + "will store images on the sdcard",
- method = "insertImage",
- args = {ContentResolver.class, Bitmap.class, String.class, String.class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getBitmap",
- args = {ContentResolver.class, Uri.class}
- )
- })
- public void testInsertImageWithBitmap() {
+ public void testInsertImageWithBitmap() throws Exception {
// insert the image by bitmap
Bitmap src = BitmapFactory.decodeResource(mContext.getResources(), R.raw.scenery);
String stringUrl = null;
@@ -215,27 +166,15 @@
null, "_id ASC");
c.moveToFirst();
// get the bimap by the path
- Bitmap result = null;
- try {
- result = Media.getBitmap(mContentResolver,
+ Bitmap result = Media.getBitmap(mContentResolver,
Uri.fromFile(new File(c.getString(c.getColumnIndex(Media.DATA)))));
- } catch (FileNotFoundException e) {
- fail(e.getMessage());
- } catch (IOException e) {
- fail(e.getMessage());
- }
+
// can not check the identity between the result and source bitmap because
// source bitmap is compressed before it is saved as result bitmap
- assertNotNull(result);
assertEquals(src.getWidth(), result.getWidth());
assertEquals(src.getHeight(), result.getHeight());
}
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getContentUri",
- args = {String.class}
- )
public void testGetContentUri() {
assertNotNull(mContentResolver.query(Media.getContentUri("internal"), null, null, null,
null));
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
index 98ad62e..7ec7937 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
@@ -18,11 +18,6 @@
import com.android.cts.stub.R;
-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;
@@ -31,15 +26,12 @@
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
-import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.provider.MediaStore.Images.Thumbnails;
import android.test.InstrumentationTestCase;
-import android.util.Log;
import java.util.ArrayList;
-@TestTargetClass(MediaStore.Images.Thumbnails.class)
public class MediaStore_Images_ThumbnailsTest extends InstrumentationTestCase {
private ArrayList<Uri> mRowsAdded;
@@ -75,19 +67,7 @@
mRowsAdded = new ArrayList<Uri>();
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "queryMiniThumbnails",
- args = {ContentResolver.class, Uri.class, int.class, String[].class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "query",
- args = {ContentResolver.class, Uri.class, String[].class}
- )
- })
- public void testQueryInternalThumbnails() {
+ public void testQueryInternalThumbnails() throws Exception {
Cursor c = Thumbnails.queryMiniThumbnails(mContentResolver,
Thumbnails.INTERNAL_CONTENT_URI, Thumbnails.MICRO_KIND, null);
int previousMicroKindCount = c.getCount();
@@ -125,18 +105,6 @@
c.close();
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "queryMiniThumbnail",
- args = {ContentResolver.class, long.class, int.class, String[].class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "query",
- args = {ContentResolver.class, Uri.class, String[].class}
- )
- })
public void testQueryExternalMiniThumbnails() {
// insert the image by bitmap
Bitmap src = BitmapFactory.decodeResource(mContext.getResources(), R.raw.scenery);
@@ -174,11 +142,6 @@
c.close();
}
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getContentUri",
- args = {String.class}
- )
public void testGetContentUri() {
assertNotNull(mContentResolver.query(Thumbnails.getContentUri("internal"), null, null,
null, null));
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
index 31d9f2c..366fc57 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
@@ -18,23 +18,17 @@
import com.android.cts.stub.R;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
-import android.provider.MediaStore;
import android.provider.MediaStore.Video;
import android.provider.MediaStore.Video.VideoColumns;
import android.test.InstrumentationTestCase;
import java.util.ArrayList;
-@TestTargetClass(MediaStore.Video.class)
public class MediaStore_VideoTest extends InstrumentationTestCase {
private static final String TEST_VIDEO_3GP = "testVideo.3gp";
@@ -64,12 +58,7 @@
mRowsAdded = new ArrayList<Uri>();
}
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "query",
- args = {ContentResolver.class, Uri.class, String[].class}
- )
- public void testQuery() {
+ public void testQuery() throws Exception {
ContentValues values = new ContentValues();
String valueOfData = mHelper.copy(R.raw.testvideo, TEST_VIDEO_3GP);
values.put(VideoColumns.DATA, valueOfData);
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
new file mode 100644
index 0000000..935b255
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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 com.android.cts.stub.R;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Environment;
+import android.provider.MediaStore.Video.Media;
+import android.provider.MediaStore.Video.Thumbnails;
+import android.provider.MediaStore.Video.VideoColumns;
+import android.test.AndroidTestCase;
+
+import java.io.File;
+import java.io.IOException;
+
+public class MediaStore_Video_ThumbnailsTest extends AndroidTestCase {
+
+ private ContentResolver mResolver;
+
+ private FileCopyHelper mFileHelper;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mResolver = mContext.getContentResolver();
+ mFileHelper = new FileCopyHelper(mContext);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mFileHelper.clear();
+ super.tearDown();
+ }
+
+ public void testGetContentUri() {
+ Uri internalUri = Thumbnails.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME);
+ Uri externalUri = Thumbnails.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME);
+ assertEquals(Thumbnails.INTERNAL_CONTENT_URI, internalUri);
+ assertEquals(Thumbnails.EXTERNAL_CONTENT_URI, externalUri);
+ }
+
+ public void testGetThumbnail() throws Exception {
+ // Insert a video into the provider.
+ Uri videoUri = insertVideo();
+ long videoId = ContentUris.parseId(videoUri);
+ assertTrue(videoId != -1);
+ assertEquals(ContentUris.withAppendedId(Media.EXTERNAL_CONTENT_URI, videoId),
+ videoUri);
+
+ // Get the current thumbnail count for future comparison.
+ int count = getThumbnailCount(Thumbnails.EXTERNAL_CONTENT_URI);
+
+ // Calling getThumbnail should generate a new thumbnail.
+ assertNotNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MINI_KIND, null));
+ assertNotNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MICRO_KIND, null));
+
+ try {
+ Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.FULL_SCREEN_KIND, null);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Full screen thumbnails not supported by getThumbnail...
+ }
+
+ // Check that an additional thumbnails have been registered.
+ int count2 = getThumbnailCount(Thumbnails.EXTERNAL_CONTENT_URI);
+ assertTrue(count2 > count);
+ }
+
+ private Uri insertVideo() throws IOException {
+ File file = new File(Environment.getExternalStorageDirectory(), "testVideo.3gp");
+ mFileHelper.copyToExternalStorage(R.raw.testvideo, file);
+
+ ContentValues values = new ContentValues();
+ values.put(VideoColumns.DATA, file.getAbsolutePath());
+ return mResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
+ }
+
+ private int getThumbnailCount(Uri uri) {
+ Cursor cursor = mResolver.query(uri, null, null, null, null);
+ try {
+ return cursor.getCount();
+ } finally {
+ cursor.close();
+ }
+ }
+}
diff --git a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
index 3822035..f278b0f 100644
--- a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
+++ b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
@@ -83,7 +83,13 @@
"android.tests.devicesetup",
// APK for the Android core tests runner used only during CTS
- "android.core.tests.runner"
+ "android.core.tests.runner",
+
+ // Wifi test utility used by Tradefed...
+ "com.android.tradefed.utils.wifi",
+
+ // Game used for CTS testing...
+ "com.replica.replicaisland"
));
private boolean isWhitelistedPackage(String packageName) {
diff --git a/tests/tests/security/src/android/security/cts/VoldExploitTest.java b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
index ab14f12..d4ea884 100644
--- a/tests/tests/security/src/android/security/cts/VoldExploitTest.java
+++ b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
@@ -269,12 +269,18 @@
/**
* Poll /proc/net/netlink until all the "Rmem" fields contain
- * "0". This indicates that there are no outstanding unreceived
- * netlink messages.
+ * "0" or approximately 10 seconds have passed.
+ *
+ * This indicates that either the netlink message was received,
+ * or the process took too long to process the incoming netlink
+ * message.
+ *
+ * See http://code.google.com/p/android/issues/detail?id=25099
+ * for information on why the timeout is needed.
*/
private static void confirmNetlinkMsgReceived() {
try {
- while(true) {
+ for (int ct = 0; ct < 200; ct++) {
boolean foundAllZeros = true;
for (List<String> i : parseNetlink()) {
// Column 5 is the "Rmem" field, which is the
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
index 1c45735..23891e0 100644
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
@@ -455,11 +455,6 @@
// Test isWellFormedSmsAddress
assertTrue(PhoneNumberUtils.isWellFormedSmsAddress("+17005554141"));
- // KT allow a to be a dialable character, the network portion of 'android' is 'a'
- if (TelephonyUtils.isKt(tm)) {
- assertTrue(PhoneNumberUtils.isWellFormedSmsAddress("android"));
- } else {
- assertFalse(PhoneNumberUtils.isWellFormedSmsAddress("android"));
- }
+ assertFalse(PhoneNumberUtils.isWellFormedSmsAddress("android"));
}
}
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index c0c26ef..6c9a152 100755
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -84,7 +84,8 @@
"302370", // Fido
"30237", // Fido
"311490", // Virgin Mobile
- "310000" // Tracfone
+ "310000", // Tracfone
+ "46003" // China Telecom
);
// List of network operators that doesn't support Data(binary) SMS message
@@ -158,19 +159,24 @@
assertNotNull(dividedMessages);
int numParts;
if (TelephonyUtils.isSkt(mTelephonyManager)) {
- numParts = 5;
+ assertTrue(isComplete(dividedMessages, 5) || isComplete(dividedMessages, 3));
} else if (TelephonyUtils.isKt(mTelephonyManager)) {
- numParts = 4;
+ assertTrue(isComplete(dividedMessages, 4) || isComplete(dividedMessages, 3));
} else {
- numParts = 3;
+ assertTrue(isComplete(dividedMessages, 3));
}
- assertEquals(numParts, dividedMessages.size());
+ }
+
+ private boolean isComplete(List<String> dividedMessages, int numParts) {
+ if (dividedMessages.size() != numParts) {
+ return false;
+ }
String actualMessage = "";
for (int i = 0; i < numParts; i++) {
actualMessage += dividedMessages.get(i);
}
- assertEquals(LONG_TEXT, actualMessage);
+ return LONG_TEXT.equals(actualMessage);
}
@TestTargets({
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
index 27f290b..4b5b55a 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
@@ -65,6 +65,8 @@
private static final int STATUS_ON_ICC_DEF = -1;
private static final int TPLAYER_LENGTH_FOR_PDU = 23;
private static final long TIMESTAMP_MILLIS = 1149631383000l;
+ private static final int SEPTETS_SKT = 80;
+ private static final int SEPTETS_KT = 90;
@Override
protected void setUp() throws Exception {
@@ -188,7 +190,7 @@
int[] result = SmsMessage.calculateLength(sms.getMessageBody(), true);
assertEquals(SMS_NUMBER1, result[0]);
assertEquals(sms.getMessageBody().length(), result[1]);
- assertEquals(getNumSeptets() - sms.getMessageBody().length(), result[2]);
+ assertRemaining(sms.getMessageBody().length(), result[2]);
assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
assertEquals(pdu, toHexString(sms.getPdu()));
@@ -220,7 +222,7 @@
result = SmsMessage.calculateLength(msgBody, false);
assertEquals(SMS_NUMBER2, result[0]);
assertEquals(sms.getMessageBody().length(), result[1]);
- assertEquals(getNumSeptets() - sms.getMessageBody().length(), result[2]);
+ assertRemaining(sms.getMessageBody().length(), result[2]);
assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
// Test createFromPdu Ucs to Sms
@@ -231,20 +233,26 @@
result = SmsMessage.calculateLength(sms.getMessageBody(), true);
assertEquals(SMS_NUMBER3, result[0]);
assertEquals(sms.getMessageBody().length(), result[1]);
- assertEquals(getNumSeptets() - sms.getMessageBody().length(), result[2]);
+ assertRemaining(sms.getMessageBody().length(), result[2]);
assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
}
- private int getNumSeptets() {
+ private void assertRemaining(int messageLength, int remaining) {
if (TelephonyUtils.isSkt(mTelephonyManager)) {
- return 80;
+ assertTrue(checkRemaining(SEPTETS_SKT, messageLength, remaining)
+ || checkRemaining(SmsMessage.MAX_USER_DATA_SEPTETS, messageLength, remaining));
} else if (TelephonyUtils.isKt(mTelephonyManager)) {
- return 90;
+ assertTrue(checkRemaining(SEPTETS_KT, messageLength, remaining)
+ || checkRemaining(SmsMessage.MAX_USER_DATA_SEPTETS, messageLength, remaining));
} else {
- return SmsMessage.MAX_USER_DATA_SEPTETS;
+ assertTrue(checkRemaining(SmsMessage.MAX_USER_DATA_SEPTETS, messageLength, remaining));
}
}
+ private boolean checkRemaining(int total, int messageLength, int remaining) {
+ return total - messageLength == remaining;
+ }
+
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
diff --git a/tests/tests/text/src/android/text/cts/TextUtilsTest.java b/tests/tests/text/src/android/text/cts/TextUtilsTest.java
index 2e675ff..e85424f 100755
--- a/tests/tests/text/src/android/text/cts/TextUtilsTest.java
+++ b/tests/tests/text/src/android/text/cts/TextUtilsTest.java
@@ -1197,7 +1197,7 @@
@ToBeFixed(bug = "1695243", explanation = "the javadoc for htmlEncode() is incomplete." +
"1. doesn't discuss the case that parameter is expectional.")
public void testHtmlEncode() {
- assertEquals("<_html_>\\ &"'string'"",
+ assertEquals("<_html_>\\ &"'string'"",
TextUtils.htmlEncode("<_html_>\\ &\"'string'\""));
try {
diff --git a/tests/tests/textureview/Android.mk b/tests/tests/textureview/Android.mk
new file mode 100644
index 0000000..d379e66
--- /dev/null
+++ b/tests/tests/textureview/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsTextureViewTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tests/tests/textureview/AndroidManifest.xml b/tests/tests/textureview/AndroidManifest.xml
new file mode 100644
index 0000000..0ed1d46
--- /dev/null
+++ b/tests/tests/textureview/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.textureview"
+ >
+
+ <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+ <uses-permission android:name="android.permission.GET_TASKS" />
+ <uses-permission android:name="android.permission.REORDER_TASKS" />
+ <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
+
+ <instrumentation
+ android:targetPackage="com.android.cts.textureview"
+ android:name="android.test.InstrumentationTestRunner" />
+
+ <application
+ android:label="@string/app_name"
+ android:hardwareAccelerated="true">
+ <activity
+ android:name="android.textureview.cts.TextureViewTestActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+</manifest>
diff --git a/tests/tests/textureview/res/values/strings.xml b/tests/tests/textureview/res/values/strings.xml
new file mode 100644
index 0000000..f4d9f96
--- /dev/null
+++ b/tests/tests/textureview/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <string name="app_name">TextureViewTest</string>
+</resources>
diff --git a/tests/tests/textureview/src/android/textureview/cts/GLProducerThread.java b/tests/tests/textureview/src/android/textureview/cts/GLProducerThread.java
new file mode 100644
index 0000000..3248597
--- /dev/null
+++ b/tests/tests/textureview/src/android/textureview/cts/GLProducerThread.java
@@ -0,0 +1,147 @@
+/*
+ * 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.textureview.cts;
+
+import android.graphics.SurfaceTexture;
+import android.opengl.GLUtils;
+
+import java.lang.Thread;
+import java.util.concurrent.Semaphore;
+
+import junit.framework.Assert;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+import javax.microedition.khronos.opengles.GL;
+
+import static android.opengl.GLES20.*;
+
+public class GLProducerThread extends Thread {
+ private Thread mProducerThread;
+ private final int mFrames;
+ private final int mDelayMs;
+ private final Semaphore mSemaphore;
+ private final SurfaceTexture mSurfaceTexture;
+
+ private EGL10 mEgl;
+ private EGLDisplay mEglDisplay = EGL10.EGL_NO_DISPLAY;
+ private EGLContext mEglContext = EGL10.EGL_NO_CONTEXT;
+ private EGLSurface mEglSurface = EGL10.EGL_NO_SURFACE;
+ private GL mGl;
+
+ private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+ private static final int EGL_OPENGL_ES2_BIT = 4;
+
+ GLProducerThread(SurfaceTexture surfaceTexture, int frames, int delayMs, Semaphore semaphore) {
+ mFrames = frames;
+ mDelayMs = delayMs;
+ mSemaphore = semaphore;
+ mSurfaceTexture = surfaceTexture;
+ }
+
+ private void initGL() {
+ mEgl = (EGL10) EGLContext.getEGL();
+
+ mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+ if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
+ throw new RuntimeException("eglGetDisplay() failed "
+ + GLUtils.getEGLErrorString(mEgl.eglGetError()));
+ }
+
+ int[] version = new int[2];
+ if (!mEgl.eglInitialize(mEglDisplay, version)) {
+ throw new RuntimeException("eglInitialize() failed " +
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
+ }
+
+ int[] configAttribs = {
+ EGL10.EGL_BUFFER_SIZE, 32,
+ EGL10.EGL_ALPHA_SIZE, 8,
+ EGL10.EGL_BLUE_SIZE, 8,
+ EGL10.EGL_GREEN_SIZE, 8,
+ EGL10.EGL_RED_SIZE, 8,
+ EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
+ EGL10.EGL_NONE
+ };
+
+ int[] numConfigs = new int[1];
+ EGLConfig[] configs = new EGLConfig[1];
+ if (!mEgl.eglChooseConfig(mEglDisplay, configAttribs, configs, 1, numConfigs) || numConfigs[0] == 0) {
+ throw new RuntimeException("eglChooseConfig() failed");
+ }
+
+ int[] contextAttribs = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL10.EGL_NONE };
+
+ mEglContext = mEgl.eglCreateContext(mEglDisplay, configs[0], EGL10.EGL_NO_CONTEXT, contextAttribs);
+
+ mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, configs[0], mSurfaceTexture, null);
+
+ if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
+ int error = mEgl.eglGetError();
+ if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
+ throw new RuntimeException("eglCreateWindowSurface() returned EGL_BAD_NATIVE_WINDOW.");
+ }
+ throw new RuntimeException("eglCreateWindowSurface() failed "
+ + GLUtils.getEGLErrorString(error));
+ }
+
+ if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+ throw new RuntimeException("eglMakeCurrent() failed "
+ + GLUtils.getEGLErrorString(mEgl.eglGetError()));
+ }
+
+ mGl = mEglContext.getGL();
+ }
+
+ void destroyGL() {
+ mEgl.eglDestroyContext(mEglDisplay, mEglContext);
+ mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+ mEglContext = EGL10.EGL_NO_CONTEXT;
+ mEglSurface = EGL10.EGL_NO_SURFACE;
+ }
+
+ @Override
+ public void run() {
+ initGL();
+ final int numColors = 4;
+ final float[][] color =
+ { { 1.0f, 0.0f, 0.0f },
+ { 0.0f, 1.0f, 0.0f },
+ { 0.0f, 0.0f, 1.0f },
+ { 1.0f, 1.0f, 1.0f } };
+
+ for (int index = 0, frame = 0;
+ frame < mFrames; index = (index + 1) % numColors, frame++) {
+ glClearColor(color[index][0], color[index][1], color[index][2], 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
+ Assert.assertEquals(EGL10.EGL_SUCCESS, mEgl.eglGetError());
+ try {
+ sleep(mDelayMs);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ mSemaphore.release();
+ destroyGL();
+ }
+}
diff --git a/tests/tests/textureview/src/android/textureview/cts/TextureViewTest.java b/tests/tests/textureview/src/android/textureview/cts/TextureViewTest.java
new file mode 100644
index 0000000..ee5ab71
--- /dev/null
+++ b/tests/tests/textureview/src/android/textureview/cts/TextureViewTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.textureview.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+public class TextureViewTest extends
+ ActivityInstrumentationTestCase2<TextureViewTestActivity> {
+
+ public TextureViewTest() {
+ super(TextureViewTestActivity.class);
+ }
+
+ public void testTextureViewStress48Hz() {
+ TextureViewTestActivity.mFrames = 600;
+ TextureViewTestActivity.mDelayMs = 1000/48;
+ if (!getActivity().waitForCompletion())
+ fail("Did not complete 48Hz test.");
+ }
+
+ public void testTextureViewStress60Hz() {
+ TextureViewTestActivity.mFrames = 600;
+ TextureViewTestActivity.mDelayMs = 1000/60;
+ if (!getActivity().waitForCompletion())
+ fail("Did not complete 60Hz test.");
+ }
+
+ public void testTextureViewStress70Hz() {
+ TextureViewTestActivity.mFrames = 600;
+ TextureViewTestActivity.mDelayMs = 1000/70;
+ if (!getActivity().waitForCompletion())
+ fail("Did not complete 70Hz test.");
+ }
+
+ public void testTextureViewStress200Hz() {
+ TextureViewTestActivity.mFrames = 600;
+ TextureViewTestActivity.mDelayMs = 1000/200;
+ if (!getActivity().waitForCompletion())
+ fail("Did not complete 200Hz test.");
+ }
+
+}
diff --git a/tests/tests/textureview/src/android/textureview/cts/TextureViewTestActivity.java b/tests/tests/textureview/src/android/textureview/cts/TextureViewTestActivity.java
new file mode 100644
index 0000000..f2a698b
--- /dev/null
+++ b/tests/tests/textureview/src/android/textureview/cts/TextureViewTestActivity.java
@@ -0,0 +1,83 @@
+/*
+ * 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.textureview.cts;
+
+import android.animation.ObjectAnimator;
+import android.animation.AnimatorSet;
+import android.app.Activity;
+import android.graphics.SurfaceTexture;
+import android.os.Bundle;
+import android.view.TextureView;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import junit.framework.Assert;
+
+public class TextureViewTestActivity extends Activity implements TextureView.SurfaceTextureListener {
+ public static int mFrames = -1;
+ public static int mDelayMs = -1;
+
+ private TextureView mTexView;
+ private Thread mProducerThread;
+ private final Semaphore mSemaphore = new Semaphore(0);
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Assert.assertTrue(mFrames > 0);
+ Assert.assertTrue(mDelayMs > 0);
+ mTexView = new TextureView(this);
+ mTexView.setSurfaceTextureListener(this);
+ setContentView(mTexView);
+ ObjectAnimator rotate = ObjectAnimator.ofFloat(mTexView, "rotationY", 180);
+ ObjectAnimator fadeIn = ObjectAnimator.ofFloat(mTexView, "alpha", 0.3f, 1f);
+ ObjectAnimator scaleY = ObjectAnimator.ofFloat(mTexView, "scaleY", 0.3f, 1f);
+ AnimatorSet animSet = new AnimatorSet();
+ animSet.play(rotate).with(fadeIn).with(scaleY);
+ animSet.setDuration(mFrames * mDelayMs);
+ animSet.start();
+ }
+
+ public Boolean waitForCompletion() {
+ Boolean success = false;
+ int timeout = mFrames * mDelayMs * 4;
+ try {
+ success = mSemaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Assert.fail();
+ }
+ return success;
+ }
+
+ @Override
+ public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+ mProducerThread = new GLProducerThread(surface, mFrames, mDelayMs, mSemaphore);
+ mProducerThread.start();
+ }
+
+ @Override
+ public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+ }
+
+ @Override
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+ mProducerThread = null;
+ return true;
+ }
+
+ @Override
+ public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+ }
+}
diff --git a/tests/tests/view/src/android/view/cts/View_AnimationTest.java b/tests/tests/view/src/android/view/cts/View_AnimationTest.java
index 144e670..d06bf31 100644
--- a/tests/tests/view/src/android/view/cts/View_AnimationTest.java
+++ b/tests/tests/view/src/android/view/cts/View_AnimationTest.java
@@ -161,8 +161,11 @@
return mAnimation.hasStarted();
}
}.run();
-
- view.clearAnimation();
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ view.clearAnimation();
+ }
+ });
Thread.sleep(TIME_OUT);
assertTrue(mAnimation.hasStarted());
assertTrue(mAnimation.hasEnded());
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java b/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java
index 92ef3fe..f997c13 100755
--- a/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java
+++ b/tests/tests/view/src/android/view/inputmethod/cts/InputMethodManagerTest.java
@@ -28,7 +28,6 @@
import android.os.IBinder;
import android.os.ResultReceiver;
import android.test.ActivityInstrumentationTestCase2;
-import android.test.UiThreadTest;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
@@ -146,16 +145,21 @@
args = {IBinder.class, int.class, int.class}
)
})
- @UiThreadTest
- public void testInputMethodManager() {
+ public void testInputMethodManager() throws Throwable {
Window window = mActivity.getWindow();
- EditText view = (EditText) window.findViewById(R.id.entry);
- assertTrue(view.requestFocus());
+ final EditText view = (EditText) window.findViewById(R.id.entry);
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ view.requestFocus();
+ }
+ });
+ getInstrumentation().waitForIdleSync();
assertTrue(view.isFocused());
BaseInputConnection connection = new BaseInputConnection(view, false);
Context context = mInstrumentation.getTargetContext();
- InputMethodManager imManager = (InputMethodManager) context
+ final InputMethodManager imManager = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
assertTrue(imManager.isActive());
assertTrue(imManager.isAcceptingText());
@@ -166,34 +170,40 @@
connection.reportFullscreenMode(true);
assertTrue(imManager.isFullscreenMode());
- IBinder token = view.getWindowToken();
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ IBinder token = view.getWindowToken();
- // Show and hide input method.
- assertTrue(imManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT));
- assertTrue(imManager.hideSoftInputFromWindow(token, 0));
+ // Show and hide input method.
+ assertTrue(imManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT));
+ assertTrue(imManager.hideSoftInputFromWindow(token, 0));
- Handler handler = new Handler();
- ResultReceiver receiver = new ResultReceiver(handler);
- assertTrue(imManager.showSoftInput(view, 0, receiver));
- receiver = new ResultReceiver(handler);
- assertTrue(imManager.hideSoftInputFromWindow(token, 0, receiver));
+ Handler handler = new Handler();
+ ResultReceiver receiver = new ResultReceiver(handler);
+ assertTrue(imManager.showSoftInput(view, 0, receiver));
+ receiver = new ResultReceiver(handler);
+ assertTrue(imManager.hideSoftInputFromWindow(token, 0, receiver));
- imManager.showSoftInputFromInputMethod(token, InputMethodManager.SHOW_FORCED);
- imManager.hideSoftInputFromInputMethod(token, InputMethodManager.HIDE_NOT_ALWAYS);
+ imManager.showSoftInputFromInputMethod(token, InputMethodManager.SHOW_FORCED);
+ imManager.hideSoftInputFromInputMethod(token, InputMethodManager.HIDE_NOT_ALWAYS);
- // status: hide to show to hide
- imManager.toggleSoftInputFromWindow(token, 0, InputMethodManager.HIDE_NOT_ALWAYS);
- imManager.toggleSoftInputFromWindow(token, 0, InputMethodManager.HIDE_NOT_ALWAYS);
+ // status: hide to show to hide
+ imManager.toggleSoftInputFromWindow(token, 0, InputMethodManager.HIDE_NOT_ALWAYS);
+ imManager.toggleSoftInputFromWindow(token, 0, InputMethodManager.HIDE_NOT_ALWAYS);
- List<InputMethodInfo> enabledImList = imManager.getEnabledInputMethodList();
- if (enabledImList != null && enabledImList.size() > 0) {
- imManager.setInputMethod(token, enabledImList.get(0).getId());
- // cannot test whether setting was successful
- }
+ List<InputMethodInfo> enabledImList = imManager.getEnabledInputMethodList();
+ if (enabledImList != null && enabledImList.size() > 0) {
+ imManager.setInputMethod(token, enabledImList.get(0).getId());
+ // cannot test whether setting was successful
+ }
- List<InputMethodInfo> imList = imManager.getInputMethodList();
- if (imList != null && enabledImList != null) {
- assertTrue(imList.size() >= enabledImList.size());
- }
+ List<InputMethodInfo> imList = imManager.getInputMethodList();
+ if (imList != null && enabledImList != null) {
+ assertTrue(imList.size() >= enabledImList.size());
+ }
+ }
+ });
+ getInstrumentation().waitForIdleSync();
}
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
index b2bdfc8..a31e0c0 100644
--- a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
+++ b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
@@ -56,6 +56,12 @@
public static final String EXT_WEB_URL1 = "http://www.example.com/";
+ public static final String LOCAL_FILESYSTEM_URL = "file:///etc/hosts";
+
+ // Must match the title of the page at
+ // android/frameworks/base/core/res/res/raw/loaderror.html
+ public static final String WEBPAGE_NOT_AVAILABLE_TITLE = "Webpage not available";
+
public static final String getFileUrl(String assetName) {
if (assetName.contains(":") || assetName.startsWith("/")) {
throw new IllegalArgumentException();
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 639f795..05e668b 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -214,7 +214,6 @@
args = {boolean.class}
)
})
- @ToBeFixed(explanation = "Cannot block file access using setAllowFileAccess(false)")
public void testAccessAllowFileAccess() {
assertTrue(mSettings.getAllowFileAccess());
@@ -225,11 +224,15 @@
fileUrl = TestHtmlConstants.getFileUrl(TestHtmlConstants.BR_TAG_URL);
mSettings.setAllowFileAccess(false);
assertFalse(mSettings.getAllowFileAccess());
+
loadUrl(fileUrl);
- // direct file:// access still works with access disabled
+ // android_asset URLs should still be loaded when even with file access
+ // disabled.
assertEquals(TestHtmlConstants.BR_TAG_TITLE, mWebView.getTitle());
- // ToBeFixed: How does this API prevent file access?
+ // Files on the file system should not be loaded.
+ loadUrl(TestHtmlConstants.LOCAL_FILESYSTEM_URL);
+ assertEquals(TestHtmlConstants.WEBPAGE_NOT_AVAILABLE_TITLE, mWebView.getTitle());
}
@TestTargets({
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index c714d8a..a091c05 100755
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -19,8 +19,6 @@
import com.android.cts.stub.R;
import com.android.internal.util.FastMath;
-import android.graphics.Path;
-import android.graphics.RectF;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
@@ -38,7 +36,9 @@
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Paint;
+import android.graphics.Path;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
@@ -56,8 +56,8 @@
import android.text.SpannableString;
import android.text.TextPaint;
import android.text.TextUtils;
-import android.text.TextWatcher;
import android.text.TextUtils.TruncateAt;
+import android.text.TextWatcher;
import android.text.method.ArrowKeyMovementMethod;
import android.text.method.DateKeyListener;
import android.text.method.DateTimeKeyListener;
@@ -70,22 +70,22 @@
import android.text.method.QwertyKeyListener;
import android.text.method.SingleLineTransformationMethod;
import android.text.method.TextKeyListener;
+import android.text.method.TextKeyListener.Capitalize;
import android.text.method.TimeKeyListener;
import android.text.method.TransformationMethod;
-import android.text.method.TextKeyListener.Capitalize;
import android.text.style.URLSpan;
import android.text.style.cts.MockURLSpanTestActivity;
import android.text.util.Linkify;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
-import android.view.ViewGroup;
-import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnLongClickListener;
+import android.view.ViewGroup;
import android.view.animation.cts.DelayedCheck;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
@@ -3972,16 +3972,21 @@
method = "isInputMethodTarget",
args = {}
)
- @UiThreadTest
- public void testIsInputMethodTarget() {
+ public void testIsInputMethodTarget() throws Throwable {
mTextView = findTextView(R.id.textview_text);
assertFalse(mTextView.isInputMethodTarget());
assertFalse(mTextView.isFocused());
- mTextView.setFocusable(true);
- mTextView.requestFocus();
- assertTrue(mTextView.isFocused());
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mTextView.setFocusable(true);
+ mTextView.requestFocus();
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ assertTrue(mTextView.isFocused());
assertTrue(mTextView.isInputMethodTarget());
}
diff --git a/tools/cts-native-xml-generator/src/com/android/cts/nativexml/Generator.java b/tools/cts-native-xml-generator/src/com/android/cts/nativexml/Generator.java
index 3a75e49..7c074b8 100644
--- a/tools/cts-native-xml-generator/src/com/android/cts/nativexml/Generator.java
+++ b/tools/cts-native-xml-generator/src/com/android/cts/nativexml/Generator.java
@@ -59,9 +59,12 @@
if (mOutputPath != null) {
File outputFile = new File(mOutputPath);
File outputDir = outputFile.getParentFile();
- if (!outputDir.exists() && !outputDir.mkdirs()) {
- System.err.println("Couldn't make output directory: " + mOutputPath);
- System.exit(1);
+ if (!outputDir.exists()) {
+ outputDir.mkdirs();
+ if (!outputDir.exists()) {
+ System.err.println("Couldn't make output directory: " + outputDir);
+ System.exit(1);
+ }
}
output = new FileOutputStream(outputFile);
}
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
index dd9681a..c06c21e 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
@@ -30,7 +30,7 @@
public static final String OPEN_GL_ES_VERSION = "openGlEsVersion";
public static final String PROCESSES = "processes";
public static final String FEATURES = "features";
- public static final String PHONE_NUMBER = "phoneNumber";
+ public static final String PHONE_NUMBER = "subscriberId";
public static final String LOCALES = "locales";
public static final String IMSI = "imsi";
public static final String IMEI = "imei";
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
index ca0c803..c9fcc83 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
@@ -185,6 +185,10 @@
screenSize = "large";
break;
+ case Configuration.SCREENLAYOUT_SIZE_XLARGE:
+ screenSize = "xlarge";
+ break;
+
case Configuration.SCREENLAYOUT_SIZE_UNDEFINED:
screenSize = "undefined";
break;
@@ -200,10 +204,13 @@
case DisplayMetrics.DENSITY_MEDIUM:
return "mdpi";
+ case DisplayMetrics.DENSITY_TV:
+ return "tvdpi";
+
case DisplayMetrics.DENSITY_HIGH:
return "hdpi";
- case 320:
+ case DisplayMetrics.DENSITY_XHIGH:
return "xdpi";
default:
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
index c28631b..b536102 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
@@ -31,7 +31,7 @@
@Option(name="cts-install-path", description="the path to the cts installation to use")
private String mCtsRootDirPath = System.getProperty("CTS_ROOT");
- public static final String CTS_BUILD_VERSION = "4.0.3_r1";
+ public static final String CTS_BUILD_VERSION = "4.0.3_r2";
/**
* {@inheritDoc}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
index 82fa0d7..bd7a983 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
@@ -203,7 +203,8 @@
private void listResults(CtsBuildHelper ctsBuild) {
TableFormatter tableFormatter = new TableFormatter();
List<List<String>> table = new ArrayList<List<String>>();
- table.add(Arrays.asList("Session","Pass", "Fail","Not Executed","Start time","Plan name"));
+ table.add(Arrays.asList("Session","Pass", "Fail","Not Executed","Start time","Plan name",
+ "Device serial(s)"));
ITestResultRepo testResultRepo = new TestResultRepo(ctsBuild.getResultsDir());
for (ITestSummary result : testResultRepo.getSummaries()) {
table.add(Arrays.asList(Integer.toString(result.getId()),
@@ -211,7 +212,8 @@
Integer.toString(result.getNumFailed()),
Integer.toString(result.getNumIncomplete()),
result.getTimestamp(),
- result.getTestPlan()));
+ result.getTestPlan(),
+ result.getDeviceSerials()));
}
tableFormatter.displayTable(table, new PrintWriter(System.out, true));
}
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/DeviceInfoResult.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/DeviceInfoResult.java
index d5f4530..17b62ca 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/DeviceInfoResult.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/DeviceInfoResult.java
@@ -39,7 +39,7 @@
class DeviceInfoResult extends AbstractXmlPullParser {
static final String TAG = "DeviceInfo";
private static final String ns = CtsXmlResultReporter.ns;
- private static final String BUILD_TAG = "BuildInfo";
+ static final String BUILD_TAG = "BuildInfo";
private static final String PHONE_TAG = "PhoneSubInfo";
private static final String SCREEN_TAG = "Screen";
private static final String FEATURE_INFO_TAG = "FeatureInfo";
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/ITestSummary.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/ITestSummary.java
index 509e564..98494ee 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/ITestSummary.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/ITestSummary.java
@@ -57,4 +57,9 @@
*/
String getStartTime();
+ /**
+ * @return a comma separated list of device serials associated with result
+ */
+ String getDeviceSerials();
+
}
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/result/TestSummaryXml.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestSummaryXml.java
index af37184..36f3297 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/TestSummaryXml.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestSummaryXml.java
@@ -20,6 +20,8 @@
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import android.tests.getinfo.DeviceInfoConstants;
+
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -35,6 +37,7 @@
private int mNumPassed = 0;
private String mPlan = "NA";
private String mStartTime = "unknown";
+ private String mDeviceSerials = "unknown";
/**
* @param id
@@ -105,13 +108,17 @@
mPlan = getAttribute(parser, CtsXmlResultReporter.PLAN_ATTR);
mStartTime = getAttribute(parser, CtsXmlResultReporter.STARTTIME_ATTR);
} else if (eventType == XmlPullParser.START_TAG && parser.getName().equals(
+ DeviceInfoResult.BUILD_TAG)) {
+ mDeviceSerials = getAttribute(parser, DeviceInfoConstants.SERIAL_NUMBER);
+ } else if (eventType == XmlPullParser.START_TAG && parser.getName().equals(
TestResults.SUMMARY_TAG)) {
mNumFailed = parseIntAttr(parser, TestResults.FAILED_ATTR) +
parseIntAttr(parser, TestResults.TIMEOUT_ATTR);
mNumNotExecuted = parseIntAttr(parser, TestResults.NOT_EXECUTED_ATTR);
mNumPassed = parseIntAttr(parser, TestResults.PASS_ATTR);
+ // abort after parsing Summary, which should be the last tag
return;
- }
+ }
eventType = parser.next();
}
throw new XmlPullParserException("Could not find Summary tag");
@@ -124,5 +131,12 @@
public String getStartTime() {
return mStartTime;
}
-}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getDeviceSerials() {
+ return mDeviceSerials;
+ }
+}
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 3e83343..98978fd 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -106,14 +106,11 @@
packages.append(doc.GetAttr('TestPackage', 'appPackageName'))
plan = tools.TestPlan(packages)
- plan.Exclude(r'android\.core\.vm-tests-tf')
- plan.Exclude('android\.performance.*')
- self.__WritePlan(plan, 'CTS')
-
plan.Exclude('android\.core\.vm-tests')
plan.Exclude('android\.performance.*')
plan.Include(r'android\.core\.vm-tests-tf')
self.__WritePlan(plan, 'CTS-TF')
+ self.__WritePlan(plan, 'CTS')
plan.Exclude(r'android\.tests\.sigtest')
plan.Exclude(r'android\.core.*')
@@ -124,11 +121,6 @@
self.__WritePlan(plan, 'Java')
plan = tools.TestPlan(packages)
- plan.Include(r'android\.core\.vm-tests')
- plan.Exclude(r'android\.core\.vm-tests-tf')
- self.__WritePlan(plan, 'VM')
-
- plan = tools.TestPlan(packages)
plan.Include(r'android\.core\.vm-tests-tf')
self.__WritePlan(plan, 'VM-TF')