am d4446193: Merge "Add missing features of JELLY_BEAN and JELLY_BEAN_MR1 to feature summary list"
# By Leo Liao
# Via Gerrit Code Review (1) and Leo Liao (1)
* commit 'd4446193dfb4434d417cdbb7da4d3524735f403a':
Add missing features of JELLY_BEAN and JELLY_BEAN_MR1 to feature summary list
diff --git a/CtsBuild.mk b/CtsBuild.mk
index 6e57086..d396006 100644
--- a/CtsBuild.mk
+++ b/CtsBuild.mk
@@ -36,10 +36,6 @@
$(foreach lib,$(1),$(HOST_OUT_JAVA_LIBRARIES)/$(lib).jar)
endef
-define cts-get-ui-lib-paths
- $(foreach lib,$(1),$(CTS_TESTCASES_OUT)/$(lib).jar)
-endef
-
define cts-get-native-paths
$(foreach exe,$(1),$(call intermediates-dir-for,EXECUTABLES,$(exe))/$(exe))
endef
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 2b61134..5511ebd 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -38,7 +38,6 @@
CtsTestStubs \
SignatureTest \
TestDeviceSetup \
- CtsUiAutomatorApp \
$(cts_security_apps_list)
cts_external_packages := \
@@ -116,23 +115,17 @@
NativeMediaTest_SL \
NativeMediaTest_XA
-cts_ui_tests := \
- CtsUiAutomatorTests
-
# All the files that will end up under the repository/testcases
# directory of the final CTS distribution.
CTS_TEST_CASES := $(call cts-get-lib-paths,$(cts_host_libraries)) \
$(call cts-get-package-paths,$(cts_test_packages)) \
- $(call cts-get-native-paths,$(cts_native_exes)) \
- $(call cts-get-ui-lib-paths,$(cts_ui_tests))
+ $(call cts-get-native-paths,$(cts_native_exes))
# All the XMLs that will end up under the repository/testcases
# and that need to be created before making the final CTS distribution.
CTS_TEST_XMLS := $(call cts-get-test-xmls,$(cts_host_libraries)) \
$(call cts-get-test-xmls,$(cts_test_packages)) \
- $(call cts-get-test-xmls,$(cts_native_exes)) \
- $(call cts-get-test-xmls,$(cts_ui_tests))
-
+ $(call cts-get-test-xmls,$(cts_native_exes))
# The following files will be placed in the tools directory of the CTS distribution
CTS_TOOLS_LIST :=
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index bce422d..6cd196c 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="1337">
+ android:versionName="4.2_r3">
<!-- Using 10 for more complete NFC support... -->
<uses-sdk android:minSdkVersion="10"></uses-sdk>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/formats/CameraFormatsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/formats/CameraFormatsActivity.java
index 9fb74c9..9989057 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/formats/CameraFormatsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/formats/CameraFormatsActivity.java
@@ -28,12 +28,14 @@
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
+import android.view.Surface;
import android.view.TextureView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
@@ -62,6 +64,7 @@
private SurfaceTexture mPreviewTexture;
private int mPreviewTexWidth;
private int mPreviewTexHeight;
+ private int mPreviewRotation;
private ImageView mFormatView;
@@ -331,9 +334,40 @@
mNextPreviewFormat = mPreviewFormats.get(0);
mFormatSpinner.setSelection(0);
+
+ // Set up correct display orientation
+
+ CameraInfo info =
+ new CameraInfo();
+ Camera.getCameraInfo(id, info);
+ int rotation = getWindowManager().getDefaultDisplay().getRotation();
+ int degrees = 0;
+ switch (rotation) {
+ case Surface.ROTATION_0: degrees = 0; break;
+ case Surface.ROTATION_90: degrees = 90; break;
+ case Surface.ROTATION_180: degrees = 180; break;
+ case Surface.ROTATION_270: degrees = 270; break;
+ }
+
+ if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+ mPreviewRotation = (info.orientation + degrees) % 360;
+ mPreviewRotation = (360 - mPreviewRotation) % 360; // compensate the mirror
+ } else { // back-facing
+ mPreviewRotation = (info.orientation - degrees + 360) % 360;
+ }
+ if (mPreviewRotation != 0 && mPreviewRotation != 180) {
+ Log.w(TAG,
+ "Display orientation correction is not 0 or 180, as expected!");
+ }
+
+ mCamera.setDisplayOrientation(mPreviewRotation);
+
+ // Start up preview if display is ready
+
if (mPreviewTexture != null) {
startPreview();
}
+
}
private void shutdownCamera() {
@@ -539,15 +573,22 @@
int w = mPreviewSize.width;
int h = mPreviewSize.height;
// RGBA output
+ int rgbInc = 1;
+ if (mPreviewRotation == 180) {
+ rgbInc = -1;
+ }
int index = 0;
for (int y = 0; y < h; y++) {
int rgbIndex = y * w;
+ if (mPreviewRotation == 180) {
+ rgbIndex = w * (h - y) - 1;
+ }
for (int x = 0; x < mPreviewSize.width/3; x++) {
int r = data[index + 0] & 0xFF;
int g = data[index + 1] & 0xFF;
int b = data[index + 2] & 0xFF;
rgbData[rgbIndex] = Color.rgb(r,g,b);
- rgbIndex += 1;
+ rgbIndex += rgbInc;
index += 3;
}
}
@@ -561,6 +602,11 @@
int h = mPreviewSize.height;
// RGBA output
int rgbIndex = 0;
+ int rgbInc = 1;
+ if (mPreviewRotation == 180) {
+ rgbIndex = h * w - 1;
+ rgbInc = -1;
+ }
int yIndex = 0;
int uvRowIndex = w*h;
int uvRowInc = 0;
@@ -579,7 +625,7 @@
rgbData[rgbIndex] =
Color.rgb(yv, uv, vv);
- rgbIndex += 1;
+ rgbIndex += rgbInc;
yIndex += 1;
uIndex += uvInc;
vIndex += uvInc;
@@ -599,6 +645,12 @@
int h = mPreviewSize.height;
// RGBA output
int rgbIndex = 0;
+ int rgbInc = 1;
+ if (mPreviewRotation == 180) {
+ rgbIndex = h * w - 1;
+ rgbInc = -1;
+ }
+
int yStride = (int)Math.ceil(w / 16.0) * 16;
int uvStride = (int)Math.ceil(yStride/2/16.0) * 16;
int ySize = yStride * h;
@@ -630,7 +682,7 @@
rgbData[rgbIndex] =
Color.rgb(yv, uv, vv);
- rgbIndex += 1;
+ rgbIndex += rgbInc;
yIndex += 1;
}
}
@@ -645,13 +697,19 @@
int uIndex = 1;
int vIndex = 3;
int rgbIndex = 0;
+ int rgbInc = 1;
+ if (mPreviewRotation == 180) {
+ rgbIndex = h * w - 1;
+ rgbInc = -1;
+ }
+
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int yv = data[yIndex] & 0xFF;
int uv = data[uIndex] & 0xFF;
int vv = data[vIndex] & 0xFF;
rgbData[rgbIndex] = Color.rgb(yv,uv,vv);
- rgbIndex += 1;
+ rgbIndex += rgbInc;
yIndex += 2;
if ( (x & 0x1) == 1 ) {
uIndex += 4;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GpsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GpsTestActivity.java
index 31b5854..bb12b2b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/location/GpsTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GpsTestActivity.java
@@ -95,25 +95,25 @@
case 1:
// Test GPS with minTime = 0
mLocationVerifier = new LocationVerifier(this, mLocationManager,
- LocationManager.GPS_PROVIDER, 0, 10);
+ LocationManager.GPS_PROVIDER, 0, 8);
mLocationVerifier.start();
break;
case 2:
// Test GPS with minTime = 1s
mLocationVerifier = new LocationVerifier(this, mLocationManager,
- LocationManager.GPS_PROVIDER, 1000, 10);
+ LocationManager.GPS_PROVIDER, 1 * 1000, 8);
mLocationVerifier.start();
break;
case 3:
// Test GPS with minTime = 5s
mLocationVerifier = new LocationVerifier(this, mLocationManager,
- LocationManager.GPS_PROVIDER, 5 * 1000, 4);
+ LocationManager.GPS_PROVIDER, 5 * 1000, 8);
mLocationVerifier.start();
break;
case 4:
// Test GPS with minTime = 15s
mLocationVerifier = new LocationVerifier(this, mLocationManager,
- LocationManager.GPS_PROVIDER, 15 * 1000, 4);
+ LocationManager.GPS_PROVIDER, 15 * 1000, 8);
mLocationVerifier.start();
break;
case 5:
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
index be0ef01..3315ba3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
@@ -23,23 +23,45 @@
import android.os.Handler;
import android.os.Message;
+import java.util.List;
+import java.util.ArrayList;
+
public class LocationVerifier implements Handler.Callback {
+
public static final String TAG = "CtsVerifierLocation";
private static final int MSG_TIMEOUT = 1;
+ /** Timing failures on first NUM_IGNORED_UPDATES updates are ignored. */
+ private static final int NUM_IGNORED_UPDATES = 2;
+
+ /* In active mode, the mean computed for the deltas should not be smaller
+ * than mInterval * ACTIVE_MIN_MEAN_RATIO */
+ private static final double ACTIVE_MIN_MEAN_RATIO = 0.75;
+
+ /* In passive mode, the mean computed for the deltas should not be smaller
+ * than mInterval * PASSIVE_MIN_MEAN_RATIO */
+ private static final double PASSIVE_MIN_MEAN_RATIO = 0.1;
+
+ /**
+ * The standard deviation computed for the deltas should not be bigger
+ * than mInterval * ALLOWED_STDEV_ERROR_RATIO
+ * or MIN_STDEV_MS, whichever is higher.
+ */
+ private static final double ALLOWED_STDEV_ERROR_RATIO = 0.50;
+ private static final long MIN_STDEV_MS = 1000;
+
private final LocationManager mLocationManager;
private final PassFailLog mCb;
private final String mProvider;
private final long mInterval;
- private final long mMinActiveInterval;
- private final long mMinPassiveInterval;
private final long mTimeout;
private final Handler mHandler;
private final int mRequestedUpdates;
private final ActiveListener mActiveListener;
private final PassiveListener mPassiveListener;
+ private boolean isTestOutcomeSet = false;
private long mLastActiveTimestamp = -1;
private long mLastPassiveTimestamp = -1;
private int mNumActiveUpdates = 0;
@@ -47,6 +69,9 @@
private boolean mRunning = false;
private boolean mActiveLocationArrive = false;
+ private List<Long> mActiveDeltas = new ArrayList();
+ private List<Long> mPassiveDeltas = new ArrayList();
+
private class ActiveListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
@@ -60,33 +85,17 @@
long delta = timestamp - mLastActiveTimestamp;
mLastActiveTimestamp = timestamp;
- if (location.getAccuracy() <= 0.0) {
- fail(mProvider + " location has invalid accuracy: " + location.getAccuracy());
- }
- if (location.getElapsedRealtimeNanos() <= 0) {
- fail(mProvider + " location has invalid elapsed realtime: " +
- location.getElapsedRealtimeNanos());
- }
-
- if (mNumActiveUpdates != 1 && delta < mMinActiveInterval) {
- fail(mProvider + " location updated too fast: " + delta + "ms < " +
- mMinActiveInterval + "ms");
+ if (mNumActiveUpdates <= NUM_IGNORED_UPDATES ) {
+ mCb.log("(ignored) active " + mProvider + " update (" + delta + "ms)");
return;
}
+ mActiveDeltas.add(delta);
mCb.log("active " + mProvider + " update (" + delta + "ms)");
- if (!mProvider.equals(location.getProvider())) {
- fail("wrong provider in callback, actual: " + location.getProvider() +
- " expected: " + mProvider);
- return;
- }
-
if (mNumActiveUpdates >= mRequestedUpdates) {
- if (mNumPassiveUpdates < mRequestedUpdates - 1) {
- fail("passive location updates not working (expected: " + mRequestedUpdates +
- " received: " + mNumPassiveUpdates + ")");
- }
+ assertMeanAndStdev(mProvider, mActiveDeltas, ACTIVE_MIN_MEAN_RATIO);
+ assertMeanAndStdev(LocationManager.PASSIVE_PROVIDER, mPassiveDeltas, PASSIVE_MIN_MEAN_RATIO);
pass();
}
}
@@ -99,6 +108,45 @@
public void onProviderDisabled(String provider) { }
}
+ private void assertMeanAndStdev(String provider, List<Long> deltas, double minMeanRatio) {
+ double mean = computeMean(deltas);
+ double stdev = computeStdev(mean, deltas);
+
+ double minMean = mInterval * minMeanRatio;
+ if (mean < minMean) {
+ fail(provider + " provider mean too small: " + mean
+ + " (min: " + minMean + ")");
+ return;
+ }
+
+ double maxStdev = Math.max(MIN_STDEV_MS, mInterval * ALLOWED_STDEV_ERROR_RATIO);
+ if (stdev > maxStdev) {
+ fail (provider + " provider stdev too big: "
+ + stdev + " (max: " + maxStdev + ")");
+ return;
+ }
+
+ mCb.log(provider + " provider mean: " + mean);
+ mCb.log(provider + " provider stdev: " + stdev);
+ }
+
+ private double computeMean(List<Long> deltas) {
+ long accumulator = 0;
+ for (long d : deltas) {
+ accumulator += d;
+ }
+ return accumulator / deltas.size();
+ }
+
+ private double computeStdev(double mean, List<Long> deltas) {
+ double accumulator = 0;
+ for (long d : deltas) {
+ double diff = d - mean;
+ accumulator += diff * diff;
+ }
+ return Math.sqrt(accumulator / (deltas.size() - 1));
+ }
+
private class PassiveListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
@@ -119,25 +167,12 @@
long delta = timestamp - mLastPassiveTimestamp;
mLastPassiveTimestamp = timestamp;
- if (location.getAccuracy() <= 0.0) {
- fail(mProvider + " location has invalid accuracy: " + location.getAccuracy());
- }
- if (location.getElapsedRealtimeNanos() <= 0) {
- fail(mProvider + " location has invalid elapsed realtime: " +
- location.getElapsedRealtimeNanos());
- }
-
- if (mNumPassiveUpdates != 1 && delta < mMinPassiveInterval) {
- fail("passive " + mProvider + " location updated too fast: " + delta + "ms < " +
- mMinPassiveInterval + "ms");
- mCb.log("when passive updates are much much faster than active updates it " +
- "suggests the location provider implementation is not power efficient");
- if (LocationManager.GPS_PROVIDER.equals(mProvider)) {
- mCb.log("check GPS_CAPABILITY_SCHEDULING in GPS driver");
- }
+ if (mNumPassiveUpdates <= NUM_IGNORED_UPDATES) {
+ mCb.log("(ignored) passive " + mProvider + " update (" + delta + "ms)");
return;
}
+ mPassiveDeltas.add(delta);
mCb.log("passive " + mProvider + " update (" + delta + "ms)");
}
@@ -153,15 +188,9 @@
String provider, long requestedInterval, int numUpdates) {
mProvider = provider;
mInterval = requestedInterval;
- // Updates can be up to 100ms ahead of schedule
- mMinActiveInterval = Math.max(0, requestedInterval - 100);
- // Allow passive updates to be up to 10x faster than active updates,
- // beyond that it is very likely the implementation is not taking
- // advantage of the interval to be power efficient
- mMinPassiveInterval = mMinActiveInterval / 10;
// timeout at 60 seconds after interval time
mTimeout = requestedInterval + 60 * 1000;
- mRequestedUpdates = numUpdates;
+ mRequestedUpdates = numUpdates + NUM_IGNORED_UPDATES;
mLocationManager = locationManager;
mCb = cb;
mHandler = new Handler(this);
@@ -192,13 +221,19 @@
}
private void pass() {
- stop();
- mCb.pass();
+ if (!isTestOutcomeSet) {
+ stop();
+ mCb.pass();
+ isTestOutcomeSet = true;
+ }
}
private void fail(String s) {
- stop();
- mCb.fail(s);
+ if (!isTestOutcomeSet) {
+ stop();
+ mCb.fail(s);
+ isTestOutcomeSet = true;
+ }
}
private void scheduleTimeout() {
diff --git a/build/config.mk b/build/config.mk
index a121dc5..c9fa709 100644
--- a/build/config.mk
+++ b/build/config.mk
@@ -15,4 +15,3 @@
BUILD_CTS_EXECUTABLE := cts/build/test_executable.mk
BUILD_CTS_PACKAGE := cts/build/test_package.mk
BUILD_CTS_HOST_JAVA_LIBRARY := cts/build/test_host_java_library.mk
-BUILD_CTS_UI_JAVA_LIBRARY := cts/build/test_uiautomator.mk
diff --git a/build/test_uiautomator.mk b/build/test_uiautomator.mk
deleted file mode 100644
index 255f70b..0000000
--- a/build/test_uiautomator.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-# Builds a uiautomator library and defines a rule to generate the associated test
-# package XML needed by CTS.
-#
-
-include $(BUILD_JAVA_LIBRARY)
-
-cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
-cts_library_jar := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar
-
-$(cts_library_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
-$(cts_library_jar): $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE))/javalib.jar | $(ACP)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(hide) $(ACP) -fp $(call intermediates-dir-for,JAVA_LIBRARIES,$(PRIVATE_MODULE))/javalib.jar $@
-
-$(cts_library_xml): PRIVATE_PATH := $(LOCAL_PATH)/src
-$(cts_library_xml): PRIVATE_TEST_APP_PACKAGE := $(LOCAL_CTS_TEST_APP_PACKAGE)
-$(cts_library_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
-$(cts_library_xml): PRIVATE_TEST_APK := $(LOCAL_CTS_TEST_APK)
-$(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
-$(cts_library_xml): PRIVATE_JAR_PATH := $(LOCAL_MODULE).jar
-$(cts_library_xml): $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE))/javalib.jar $(CTS_EXPECTATIONS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
- $(hide) echo Generating test description for uiautomator library $(PRIVATE_LIBRARY)
- $(hide) mkdir -p $(CTS_TESTCASES_OUT)
- $(hide) $(CTS_JAVA_TEST_SCANNER) -s $(PRIVATE_PATH) \
- -d $(CTS_JAVA_TEST_SCANNER_DOCLET) | \
- $(CTS_XML_GENERATOR) -t uiAutomator \
- -i $(PRIVATE_TEST_APK) \
- -j $(PRIVATE_JAR_PATH) \
- -a $(PRIVATE_TEST_PACKAGE) \
- -n $(PRIVATE_LIBRARY) \
- -p $(PRIVATE_TEST_PACKAGE) \
- -r $(PRIVATE_TEST_APP_PACKAGE) \
- -e $(CTS_EXPECTATIONS) \
- -o $@
diff --git a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FileUtil.java b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FileUtil.java
index 2cb3854..14fc45a 100644
--- a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FileUtil.java
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FileUtil.java
@@ -118,10 +118,14 @@
* @throws IOException
*/
public static void writeFile(File file, byte[] data, boolean append) throws IOException {
- FileOutputStream out = new FileOutputStream(file, append);
- out.write(data);
- out.flush();
- out.close();
+ final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd"); // force O_SYNC
+ if (append) {
+ randomFile.seek(randomFile.length());
+ } else {
+ randomFile.seek(0L);
+ }
+ randomFile.write(data);
+ randomFile.close();
}
/**
@@ -276,7 +280,7 @@
final int runsInOneGo = 16;
final int readsInOneMeasure = totalReadCount / runsInOneGo;
- final RandomAccessFile randomFile = new RandomAccessFile(file, "rw");
+ final RandomAccessFile randomFile = new RandomAccessFile(file, "rw"); // do not need O_SYNC
double[] rdAmount = new double[runsInOneGo];
double[] wrAmount = new double[runsInOneGo];
double[] times = FileUtil.measureIO(runsInOneGo, rdAmount, wrAmount, new MeasureRun() {
@@ -326,7 +330,7 @@
final int runsInOneGo = 16;
final int writesInOneMeasure = totalWriteCount / runsInOneGo; // 32MB at a time
- final RandomAccessFile randomFile = new RandomAccessFile(file, "rw");
+ final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd"); // force O_SYNC
double[] rdAmount = new double[runsInOneGo];
double[] wrAmount = new double[runsInOneGo];
double[] times = FileUtil.measureIO(runsInOneGo, rdAmount, wrAmount, new MeasureRun() {
@@ -370,16 +374,16 @@
int numberRepeatInOneRun = (int)(fileSize / bufferSize);
double[] mbpsAll = new double[numberRepetition * numberRepeatInOneRun];
for (int i = 0; i < numberRepetition; i++) {
- final FileOutputStream out = new FileOutputStream(file);
+ final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd"); // force O_SYNC
+ randomFile.seek(0L);
double[] times = MeasureTime.measure(numberRepeatInOneRun, new MeasureRun() {
@Override
public void run(int i) throws IOException {
- out.write(data);
- out.flush();
+ randomFile.write(data);
}
});
- out.close();
+ randomFile.close();
double[] mbps = ReportLog.calcRatePerSecArray((double)bufferSize / 1024 / 1024,
times);
report.printArray(i + "-th round MB/s",
diff --git a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/TestTest.java b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/TestTest.java
index 6800d6f..e333200 100644
--- a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/TestTest.java
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/TestTest.java
@@ -31,7 +31,7 @@
protected void tearDown() throws Exception {
super.tearDown();
}
-
+/* code for testing PTS logging. Disabled.
@TimeoutReq(minutes = 15)
public void testPass() {
double[] array = new double[] {1.0, 2.0, 3.0};
@@ -49,4 +49,5 @@
getReportLog().printSummary("This should not be shown", 0, 0);
throw new Exception("failed");
}
+*/
}
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
index 21c0271..517b71a 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
@@ -652,8 +652,8 @@
AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, arguments));
// Verify the selection position.
- assertEquals(1, Selection.getSelectionStart(textView.getText()));
- assertEquals(1, Selection.getSelectionEnd(textView.getText()));
+ assertEquals(0, Selection.getSelectionStart(textView.getText()));
+ assertEquals(0, Selection.getSelectionEnd(textView.getText()));
}
@MediumTest
diff --git a/tests/tests/media/res/raw/test1m1s.mp3 b/tests/tests/media/res/raw/test1m1s.mp3
new file mode 100644
index 0000000..d54a9df
--- /dev/null
+++ b/tests/tests/media/res/raw/test1m1s.mp3
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
new file mode 100644
index 0000000..e9d0b5f
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -0,0 +1,292 @@
+/*
+ * 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.media.cts;
+
+import com.android.cts.media.R;
+
+import android.content.Context;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+
+public class EncoderTest extends AndroidTestCase {
+ private static final String TAG = "EncoderTest";
+ private static final boolean VERBOSE = false;
+
+ private static final int kNumInputBytes = 256 * 1024;
+ private static final long kTimeoutUs = 10000;
+
+ @Override
+ public void setContext(Context context) {
+ super.setContext(context);
+ }
+
+ public void testAMRNBEncoders() {
+ LinkedList<MediaFormat> formats = new LinkedList<MediaFormat>();
+
+ final int kBitRates[] =
+ { 4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200 };
+
+ for (int j = 0; j < kBitRates.length; ++j) {
+ MediaFormat format = new MediaFormat();
+ format.setString(MediaFormat.KEY_MIME, "audio/3gpp");
+ format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 8000);
+ format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates[j]);
+ formats.push(format);
+ }
+
+ testEncoderWithFormats("audio/3gpp", formats);
+ }
+
+ public void testAMRWBEncoders() {
+ LinkedList<MediaFormat> formats = new LinkedList<MediaFormat>();
+
+ final int kBitRates[] =
+ { 6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850 };
+
+ for (int j = 0; j < kBitRates.length; ++j) {
+ MediaFormat format = new MediaFormat();
+ format.setString(MediaFormat.KEY_MIME, "audio/amr-wb");
+ format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 16000);
+ format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates[j]);
+ formats.push(format);
+ }
+
+ testEncoderWithFormats("audio/amr-wb", formats);
+ }
+
+ public void testAACEncoders() {
+ LinkedList<MediaFormat> formats = new LinkedList<MediaFormat>();
+
+ final int kAACProfiles[] = {
+ 2 /* OMX_AUDIO_AACObjectLC */,
+ 5 /* OMX_AUDIO_AACObjectHE */,
+ 39 /* OMX_AUDIO_AACObjectELD */
+ };
+
+ final int kSampleRates[] = { 8000, 11025, 22050, 44100, 48000 };
+ final int kBitRates[] = { 64000, 128000 };
+
+ for (int k = 0; k < kAACProfiles.length; ++k) {
+ for (int i = 0; i < kSampleRates.length; ++i) {
+ if (kAACProfiles[k] == 5 && kSampleRates[i] < 22050) {
+ // Is this right? HE does not support sample rates < 22050Hz?
+ continue;
+ }
+ for (int j = 0; j < kBitRates.length; ++j) {
+ for (int ch = 1; ch <= 2; ++ch) {
+ MediaFormat format = new MediaFormat();
+ format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
+
+ format.setInteger(
+ MediaFormat.KEY_AAC_PROFILE, kAACProfiles[k]);
+
+ format.setInteger(
+ MediaFormat.KEY_SAMPLE_RATE, kSampleRates[i]);
+
+ format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, ch);
+ format.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates[j]);
+ formats.push(format);
+ }
+ }
+ }
+ }
+
+ testEncoderWithFormats("audio/mp4a-latm", formats);
+ }
+
+ private void testEncoderWithFormats(
+ String mime, List<MediaFormat> formats) {
+ List<String> componentNames = getEncoderNamesForType(mime);
+
+ for (String componentName : componentNames) {
+ Log.d(TAG, "testing component '" + componentName + "'");
+ for (MediaFormat format : formats) {
+ Log.d(TAG, " testing format '" + format + "'");
+ assertEquals(mime, format.getString(MediaFormat.KEY_MIME));
+ testEncoder(componentName, format);
+ }
+ }
+ }
+
+ private List<String> getEncoderNamesForType(String mime) {
+ LinkedList<String> names = new LinkedList<String>();
+
+ int n = MediaCodecList.getCodecCount();
+ for (int i = 0; i < n; ++i) {
+ MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+
+ if (!info.isEncoder()) {
+ continue;
+ }
+
+ if (!info.getName().startsWith("OMX.")) {
+ // Unfortunately for legacy reasons, "AACEncoder", a
+ // non OMX component had to be in this list for the video
+ // editor code to work... but it cannot actually be instantiated
+ // using MediaCodec.
+ Log.d(TAG, "skipping '" + info.getName() + "'.");
+ continue;
+ }
+
+ String[] supportedTypes = info.getSupportedTypes();
+
+ for (int j = 0; j < supportedTypes.length; ++j) {
+ if (supportedTypes[j].equalsIgnoreCase(mime)) {
+ names.push(info.getName());
+ break;
+ }
+ }
+ }
+
+ return names;
+ }
+
+ private int queueInputBuffer(
+ MediaCodec codec, ByteBuffer[] inputBuffers, int index) {
+ ByteBuffer buffer = inputBuffers[index];
+ buffer.clear();
+
+ int size = buffer.limit();
+
+ byte[] zeroes = new byte[size];
+ buffer.put(zeroes);
+
+ codec.queueInputBuffer(index, 0 /* offset */, size, 0 /* timeUs */, 0);
+
+ return size;
+ }
+
+ private void dequeueOutputBuffer(
+ MediaCodec codec, ByteBuffer[] outputBuffers,
+ int index, MediaCodec.BufferInfo info) {
+ codec.releaseOutputBuffer(index, false /* render */);
+ }
+
+ private void testEncoder(String componentName, MediaFormat format) {
+ MediaCodec codec = MediaCodec.createByCodecName(componentName);
+
+ try {
+ codec.configure(
+ format,
+ null /* surface */,
+ null /* crypto */,
+ MediaCodec.CONFIGURE_FLAG_ENCODE);
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "codec '" + componentName + "' failed configuration.");
+
+ assertTrue("codec '" + componentName + "' failed configuration.", false);
+ }
+
+ codec.start();
+ ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
+ ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
+
+ int numBytesSubmitted = 0;
+ boolean doneSubmittingInput = false;
+ int numBytesDequeued = 0;
+
+ while (true) {
+ int index;
+
+ if (!doneSubmittingInput) {
+ index = codec.dequeueInputBuffer(kTimeoutUs /* timeoutUs */);
+
+ if (index != MediaCodec.INFO_TRY_AGAIN_LATER) {
+ if (numBytesSubmitted >= kNumInputBytes) {
+ codec.queueInputBuffer(
+ index,
+ 0 /* offset */,
+ 0 /* size */,
+ 0 /* timeUs */,
+ MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+
+ if (VERBOSE) {
+ Log.d(TAG, "queued input EOS.");
+ }
+
+ doneSubmittingInput = true;
+ } else {
+ int size = queueInputBuffer(
+ codec, codecInputBuffers, index);
+
+ numBytesSubmitted += size;
+
+ if (VERBOSE) {
+ Log.d(TAG, "queued " + size + " bytes of input data.");
+ }
+ }
+ }
+ }
+
+ MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+ index = codec.dequeueOutputBuffer(info, kTimeoutUs /* timeoutUs */);
+
+ if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
+ } else if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+ } else if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+ codecOutputBuffers = codec.getOutputBuffers();
+ } else {
+ dequeueOutputBuffer(codec, codecOutputBuffers, index, info);
+
+ numBytesDequeued += info.size;
+
+ if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+ if (VERBOSE) {
+ Log.d(TAG, "dequeued output EOS.");
+ }
+ break;
+ }
+
+ if (VERBOSE) {
+ Log.d(TAG, "dequeued " + info.size + " bytes of output data.");
+ }
+ }
+ }
+
+ if (VERBOSE) {
+ Log.d(TAG, "queued a total of " + numBytesSubmitted + "bytes, "
+ + "dequeued " + numBytesDequeued + " bytes.");
+ }
+
+ int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+ int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+ int inBitrate = sampleRate * channelCount * 16; // bit/sec
+ int outBitrate = format.getInteger(MediaFormat.KEY_BIT_RATE);
+
+ float desiredRatio = (float)outBitrate / (float)inBitrate;
+ float actualRatio = (float)numBytesDequeued / (float)numBytesSubmitted;
+
+ if (actualRatio < 0.9 * desiredRatio || actualRatio > 1.1 * desiredRatio) {
+ Log.w(TAG, "desiredRatio = " + desiredRatio
+ + ", actualRatio = " + actualRatio);
+ }
+
+ codec.release();
+ codec = null;
+ }
+}
+
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
index e6abe31..0973c1a 100755
--- a/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecListTest.java
@@ -17,10 +17,11 @@
package android.media.cts;
-import android.media.MediaCodecList;
+import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecInfo.CodecProfileLevel;
import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecList;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -53,6 +54,63 @@
assertTrue("/etc/media_codecs.xml does not exist", file.exists());
}
+ // Each component advertised by MediaCodecList should at least be
+ // instantiate-able.
+ public void testComponentInstantiation() {
+ Log.d(TAG, "testComponentInstantiation");
+
+ int codecCount = MediaCodecList.getCodecCount();
+ for (int i = 0; i < codecCount; ++i) {
+ MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+
+ Log.d(TAG, (i + 1) + ": " + info.getName());
+ Log.d(TAG, " isEncoder = " + info.isEncoder());
+
+ if (!info.getName().startsWith("OMX.")) {
+ // Unfortunately for legacy reasons, "AACEncoder", a
+ // non OMX component had to be in this list for the video
+ // editor code to work... but it cannot actually be instantiated
+ // using MediaCodec.
+ Log.d(TAG, " skipping...");
+ continue;
+ }
+
+ MediaCodec codec = MediaCodec.createByCodecName(info.getName());
+
+ codec.release();
+ codec = null;
+ }
+ }
+
+ // For each type advertised by any of the components we should be able
+ // to get capabilities.
+ public void testGetCapabilities() {
+ Log.d(TAG, "testGetCapabilities");
+
+ int codecCount = MediaCodecList.getCodecCount();
+ for (int i = 0; i < codecCount; ++i) {
+ MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
+
+ Log.d(TAG, (i + 1) + ": " + info.getName());
+ Log.d(TAG, " isEncoder = " + info.isEncoder());
+
+ if (!info.getName().startsWith("OMX.")) {
+ // Unfortunately for legacy reasons, "AACEncoder", a
+ // non OMX component had to be in this list for the video
+ // editor code to work... but it cannot actually be instantiated
+ // using MediaCodec.
+ Log.d(TAG, " skipping...");
+ continue;
+ }
+
+ String[] types = info.getSupportedTypes();
+ for (int j = 0; j < types.length; ++j) {
+ Log.d(TAG, "calling getCapabilitiesForType " + types[j]);
+ CodecCapabilities cap = info.getCapabilitiesForType(types[j]);
+ }
+ }
+ }
+
public void testRequiredMediaCodecList() {
List<CodecType> requiredList = getRequiredCodecTypes();
List<CodecType> supportedList = getSupportedCodecTypes();
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 97bd731..dda78f8 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.media.TimedText;
import android.media.audiofx.AudioEffect;
import android.media.audiofx.Visualizer;
+import android.media.cts.MediaPlayerTestBase.Monitor;
import android.net.Uri;
import android.os.Environment;
import android.os.PowerManager;
@@ -142,59 +143,141 @@
playVideoTest(R.raw.testvideo, 352, 288);
}
- public void testSetNextMediaPlayer() throws Exception {
- AssetFileDescriptor afd = mResources.openRawResourceFd(R.raw.sine1320hz5sec);
+ private void initMediaPlayer(MediaPlayer player) throws Exception {
+ AssetFileDescriptor afd = mResources.openRawResourceFd(R.raw.test1m1s);
try {
- mMediaPlayer.reset();
- mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
- afd.getLength());
- mMediaPlayer.prepare();
- mMediaPlayer2.reset();
- mMediaPlayer2.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
- afd.getLength());
- mMediaPlayer2.prepare();
+ player.reset();
+ player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+ player.prepare();
+ player.seekTo(56000);
} finally {
afd.close();
}
+ }
- mOnCompletionCalled.reset();
- mOnInfoCalled.reset();
+ public void testSetNextMediaPlayer() throws Exception {
+ initMediaPlayer(mMediaPlayer);
- mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ final Monitor mTestCompleted = new Monitor();
+
+ Thread timer = new Thread(new Runnable() {
+
@Override
- public void onCompletion(MediaPlayer mp) {
- assertEquals(mMediaPlayer, mp);
- mOnCompletionCalled.signal();
- }
- });
- mMediaPlayer2.setOnInfoListener(new MediaPlayer.OnInfoListener() {
- @Override
- public boolean onInfo(MediaPlayer mp, int what, int extra) {
- assertEquals(mMediaPlayer2, mp);
- if (what == MediaPlayer.MEDIA_INFO_STARTED_AS_NEXT) {
- mOnInfoCalled.signal();
+ public void run() {
+ long startTime = SystemClock.elapsedRealtime();
+ while(true) {
+ SystemClock.sleep(SLEEP_TIME);
+ if (mTestCompleted.isSignalled()) {
+ // done
+ return;
+ }
+ long now = SystemClock.elapsedRealtime();
+ if ((now - startTime) > 25000) {
+ // We've been running for 25 seconds and still aren't done, so we're stuck
+ // somewhere. Signal ourselves to dump the thread stacks.
+ android.os.Process.sendSignal(android.os.Process.myPid(), 3);
+ SystemClock.sleep(2000);
+ fail("Test is stuck, see ANR stack trace for more info. You may need to" +
+ " create /data/anr first");
+ return;
+ }
}
- return false;
}
});
+ timer.start();
+
try {
+ for (int i = 0; i < 3; i++) {
+
+ initMediaPlayer(mMediaPlayer2);
+ mOnCompletionCalled.reset();
+ mOnInfoCalled.reset();
+ mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ @Override
+ public void onCompletion(MediaPlayer mp) {
+ assertEquals(mMediaPlayer, mp);
+ mOnCompletionCalled.signal();
+ }
+ });
+ mMediaPlayer2.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+ @Override
+ public boolean onInfo(MediaPlayer mp, int what, int extra) {
+ assertEquals(mMediaPlayer2, mp);
+ if (what == MediaPlayer.MEDIA_INFO_STARTED_AS_NEXT) {
+ mOnInfoCalled.signal();
+ }
+ return false;
+ }
+ });
+
+ mMediaPlayer.setNextMediaPlayer(mMediaPlayer2);
+ mMediaPlayer.start();
+ assertTrue(mMediaPlayer.isPlaying());
+ assertFalse(mOnCompletionCalled.isSignalled());
+ assertFalse(mMediaPlayer2.isPlaying());
+ assertFalse(mOnInfoCalled.isSignalled());
+ while(mMediaPlayer.isPlaying()) {
+ Thread.sleep(SLEEP_TIME);
+ }
+ // wait a little longer in case the callbacks haven't quite made it through yet
+ Thread.sleep(100);
+ assertTrue(mMediaPlayer2.isPlaying());
+ assertTrue(mOnCompletionCalled.isSignalled());
+ assertTrue(mOnInfoCalled.isSignalled());
+
+ // At this point the 1st player is done, and the 2nd one is playing.
+ // Now swap them, and go through the loop again.
+ MediaPlayer tmp = mMediaPlayer;
+ mMediaPlayer = mMediaPlayer2;
+ mMediaPlayer2 = tmp;
+ }
+
+ // Now test that setNextMediaPlayer(null) works. 1 is still playing, 2 is done
+ mOnCompletionCalled.reset();
+ mOnInfoCalled.reset();
+ initMediaPlayer(mMediaPlayer2);
mMediaPlayer.setNextMediaPlayer(mMediaPlayer2);
- mMediaPlayer.start();
+
+ mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ @Override
+ public void onCompletion(MediaPlayer mp) {
+ assertEquals(mMediaPlayer, mp);
+ mOnCompletionCalled.signal();
+ }
+ });
+ mMediaPlayer2.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+ @Override
+ public boolean onInfo(MediaPlayer mp, int what, int extra) {
+ assertEquals(mMediaPlayer2, mp);
+ if (what == MediaPlayer.MEDIA_INFO_STARTED_AS_NEXT) {
+ mOnInfoCalled.signal();
+ }
+ return false;
+ }
+ });
assertTrue(mMediaPlayer.isPlaying());
assertFalse(mOnCompletionCalled.isSignalled());
assertFalse(mMediaPlayer2.isPlaying());
assertFalse(mOnInfoCalled.isSignalled());
+ Thread.sleep(SLEEP_TIME);
+ mMediaPlayer.setNextMediaPlayer(null);
while(mMediaPlayer.isPlaying()) {
Thread.sleep(SLEEP_TIME);
}
- assertTrue(mMediaPlayer2.isPlaying());
+ // wait a little longer in case the callbacks haven't quite made it through yet
+ Thread.sleep(100);
+ assertFalse(mMediaPlayer.isPlaying());
+ assertFalse(mMediaPlayer2.isPlaying());
assertTrue(mOnCompletionCalled.isSignalled());
- assertTrue(mOnInfoCalled.isSignalled());
+ assertFalse(mOnInfoCalled.isSignalled());
+
} finally {
mMediaPlayer.reset();
mMediaPlayer2.reset();
}
+ mTestCompleted.signal();
+
}
// The following tests are all a bit flaky, which is why they're retried a
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
index f714a07..c13f041 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
@@ -22,6 +22,12 @@
import android.os.Environment;
import android.test.AndroidTestCase;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
public class MediaScannerNotificationTest extends AndroidTestCase {
public void testMediaScannerNotification() throws Exception {
@@ -38,10 +44,81 @@
mContext.registerReceiver(startedReceiver, startedIntentFilter);
mContext.registerReceiver(finishedReceiver, finshedIntentFilter);
+ String [] temps = new String[] { "avi", "gif", "jpg", "dat", "mp3", "mp4", "txt" };
+ String tmpPath = createTempFiles(temps);
+
mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
startedReceiver.waitForBroadcast();
finishedReceiver.waitForBroadcast();
+
+ checkTempFiles(tmpPath, temps);
+
+ // add .nomedia file and scan again
+ File noMedia = new File(tmpPath, ".nomedia");
+ try {
+ noMedia.createNewFile();
+ } catch (IOException e) {
+ fail("couldn't create .nomedia file");
+ }
+ startedReceiver.reset();
+ finishedReceiver.reset();
+ mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ + Environment.getExternalStorageDirectory())));
+ startedReceiver.waitForBroadcast();
+ finishedReceiver.waitForBroadcast();
+
+ checkTempFiles(tmpPath, temps);
+ assertTrue(noMedia.delete());
+ deleteTempFiles(tmpPath, temps);
+
+ // scan one more time just to clean everything up nicely
+ startedReceiver.reset();
+ finishedReceiver.reset();
+ mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ + Environment.getExternalStorageDirectory())));
+ startedReceiver.waitForBroadcast();
+ finishedReceiver.waitForBroadcast();
+
+ }
+
+ String createTempFiles(String [] extensions) {
+ String externalPath = Environment.getExternalStorageDirectory().getAbsolutePath();
+ File tmpDir = new File(externalPath, "" + System.nanoTime());
+ String tmpPath = tmpDir.getAbsolutePath();
+ assertFalse(tmpPath + " already exists", tmpDir.exists());
+ assertTrue("failed to create " + tmpDir, tmpDir.mkdirs());
+
+ for (int i = 0; i < extensions.length; i++) {
+ File foo = new File(tmpPath, "foobar." + extensions[i]);
+ try {
+ // create a non-empty file
+ foo.createNewFile();
+ FileOutputStream out = new FileOutputStream(foo);
+ out.write(0x12);
+ out.flush();
+ out.close();
+ assertTrue(foo.length() != 0);
+ } catch (IOException e) {
+ fail("Error creating " + foo.getAbsolutePath() + ": " + e);
+ }
+ }
+ return tmpPath;
+ }
+
+ void checkTempFiles(String tmpPath, String [] extensions) {
+ for (int i = 0; i < extensions.length; i++) {
+ File foo = new File(tmpPath, "foobar." + extensions[i]);
+ assertTrue(foo.getAbsolutePath() + " no longer exists or was truncated",
+ foo.length() != 0);
+ }
+ }
+
+ void deleteTempFiles(String tmpPath, String [] extensions) {
+ for (int i = 0; i < extensions.length; i++) {
+ assertTrue(new File(tmpPath, "foobar." + extensions[i]).delete());
+ }
+ assertTrue(new File(tmpPath).delete());
}
}
diff --git a/tests/tests/media/src/android/media/cts/RingtoneTest.java b/tests/tests/media/src/android/media/cts/RingtoneTest.java
index 024f44d..6e3a1e9 100644
--- a/tests/tests/media/src/android/media/cts/RingtoneTest.java
+++ b/tests/tests/media/src/android/media/cts/RingtoneTest.java
@@ -21,6 +21,7 @@
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
+import android.net.Uri;
import android.provider.Settings;
import android.test.AndroidTestCase;
@@ -32,6 +33,7 @@
private int mOriginalVolume;
private int mOriginalRingerMode;
private int mOriginalStreamType;
+ private Uri mDefaultRingUri;
@Override
protected void setUp() throws Exception {
@@ -49,6 +51,9 @@
AudioManager.FLAG_ALLOW_RINGER_MODES);
// make sure that we are not in silent mode
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+
+ mDefaultRingUri = RingtoneManager.getActualDefaultRingtoneUri(mContext,
+ RingtoneManager.TYPE_RINGTONE);
}
@Override
@@ -63,6 +68,8 @@
mAudioManager.setStreamVolume(AudioManager.STREAM_RING, mOriginalVolume,
AudioManager.FLAG_ALLOW_RINGER_MODES);
}
+ RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE,
+ mDefaultRingUri);
super.tearDown();
}
@@ -79,8 +86,20 @@
mRingtone.setStreamType(AudioManager.STREAM_RING);
assertEquals(AudioManager.STREAM_RING, mRingtone.getStreamType());
+ // test both the "None" ringtone and an actual ringtone
+ RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE, null);
+ mRingtone = RingtoneManager.getRingtone(mContext, Settings.System.DEFAULT_RINGTONE_URI);
+ assertTrue(mRingtone.getStreamType() == AudioManager.STREAM_RING);
mRingtone.play();
- assertTrue(mRingtone.isPlaying());
+ assertFalse(mRingtone.isPlaying());
+
+ Uri uri = RingtoneManager.getValidRingtoneUri(mContext);
+ assertNotNull("ringtone was unexpectedly null", uri);
+ RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE, uri);
+ mRingtone = RingtoneManager.getRingtone(mContext, Settings.System.DEFAULT_RINGTONE_URI);
+ assertTrue(mRingtone.getStreamType() == AudioManager.STREAM_RING);
+ mRingtone.play();
+ assertTrue("couldn't play ringtone " + uri, mRingtone.isPlaying());
mRingtone.stop();
assertFalse(mRingtone.isPlaying());
}
diff --git a/tests/tests/media/src/android/media/cts/ScannerNotificationReceiver.java b/tests/tests/media/src/android/media/cts/ScannerNotificationReceiver.java
index 4357bee..9d91671 100644
--- a/tests/tests/media/src/android/media/cts/ScannerNotificationReceiver.java
+++ b/tests/tests/media/src/android/media/cts/ScannerNotificationReceiver.java
@@ -30,7 +30,7 @@
private static final int TIMEOUT_MS = 4 * 60 * 1000;
private final String mAction;
- private final CountDownLatch mLatch = new CountDownLatch(1);
+ private CountDownLatch mLatch = new CountDownLatch(1);
ScannerNotificationReceiver(String action) {
mAction = action;
@@ -51,6 +51,10 @@
}
}
+ void reset() {
+ mLatch = new CountDownLatch(1);
+ }
+
private int countFiles(File dir) {
int count = 0;
File[] files = dir.listFiles();
@@ -65,4 +69,4 @@
}
return count;
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java b/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java
index c349ac0..1b4ed62 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/CodecTest.java
@@ -808,6 +808,9 @@
return false;
}
}
+ if (!mOnCompleteSuccess && !mPlaybackError) {
+ Log.e(TAG, "wait timed-out without onCompletion notification");
+ }
terminateMessageLooper();
} catch (Exception e) {
Log.v(TAG, "playMediaSample Exception:" + e.getMessage());
diff --git a/tests/tests/os/src/android/os/cts/BuildVersionTest.java b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
index 9876694..dfa8301 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.2"));
+ new HashSet<String>(Arrays.asList("4.2", "4.2.1", "4.2.2"));
private static final int EXPECTED_SDK = 17;
@SuppressWarnings("deprecation")
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 1b09fb2..32fd18d 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -25,6 +25,7 @@
import java.io.File;
import java.io.FileFilter;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
@@ -392,6 +393,7 @@
"/data/drm/IDM/HTTP",
"/data/drm/rights",
"/data/dump",
+ "/data/efslog",
"/data/emt",
"/data/factory",
"/data/fics",
@@ -408,6 +410,8 @@
"/data/install",
"/data/internal-device",
"/data/internal-device/DCIM",
+ "/data/last_alog",
+ "/data/last_klog",
"/data/local",
"/data/local/logs",
"/data/local/logs/kernel",
@@ -517,6 +521,46 @@
writableDirs.isEmpty());
}
+ @LargeTest
+ public void testReadingSysFilesDoesntFail() throws Exception {
+ tryToReadFromAllIn(new File("/sys"));
+ }
+
+ private static void tryToReadFromAllIn(File dir) throws IOException {
+ assertTrue(dir.isDirectory());
+
+ if (isSymbolicLink(dir)) {
+ // don't examine symbolic links.
+ return;
+ }
+
+ File[] files = dir.listFiles();
+
+ if (files != null) {
+ for (File f : files) {
+ if (f.isDirectory()) {
+ tryToReadFromAllIn(f);
+ } else {
+ tryFileRead(f);
+ }
+ }
+ }
+ }
+
+ private static void tryFileRead(File f) {
+ byte[] b = new byte[1024];
+ try {
+ System.out.println("looking at " + f.getCanonicalPath());
+ FileInputStream fis = new FileInputStream(f);
+ while(fis.read(b) != -1) {
+ // throw away data
+ }
+ fis.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
private static final Set<File> SYS_EXCEPTIONS = new HashSet<File>(
Arrays.asList(
new File("/sys/kernel/debug/tracing/trace_marker")
diff --git a/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java b/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
index 1fd6bfe..877a89e 100755
--- a/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
@@ -16,9 +16,7 @@
package android.permission2.cts;
-import android.content.Context;
import android.content.Intent;
-import android.os.Bundle;
import android.test.AndroidTestCase;
/**
@@ -62,13 +60,33 @@
"android.intent.action.NETWORK_SET_TIMEZONE",
"android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS",
"android.intent.action.ACTION_MDN_STATE_CHANGED",
- "android.provider.Telephony.SPN_STRINGS_UPDATED"
+ "android.provider.Telephony.SPN_STRINGS_UPDATED",
+ "android.intent.action.ANY_DATA_STATE",
+ "com.android.server.WifiManager.action.START_SCAN",
+ "com.android.server.WifiManager.action.DELAYED_DRIVER_STOP",
+ "android.net.wifi.WIFI_STATE_CHANGED",
+ "android.net.wifi.WIFI_AP_STATE_CHANGED",
+ "android.net.wifi.SCAN_RESULTS",
+ "android.net.wifi.RSSI_CHANGED",
+ "android.net.wifi.STATE_CHANGE",
+ "android.net.wifi.LINK_CONFIGURATION_CHANGED",
+ "android.net.wifi.CONFIGURED_NETWORKS_CHANGE",
+ "android.net.wifi.supplicant.CONNECTION_CHANGE",
+ "android.net.wifi.supplicant.STATE_CHANGE",
+ "android.net.wifi.p2p.STATE_CHANGED",
+ "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE",
+ "android.net.wifi.p2p.THIS_DEVICE_CHANGED",
+ "android.net.wifi.p2p.PEERS_CHANGED",
+ "android.net.wifi.p2p.CONNECTION_STATE_CHANGE",
+ "android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED",
+ "android.net.conn.TETHER_STATE_CHANGED",
+ "android.net.conn.INET_CONDITION_ACTION"
};
/**
* Verify that protected broadcast actions can't be sent.
*/
- public void testProcessOutgoingCall() {
+ public void testSendProtectedBroadcasts() {
for (String action : BROADCASTS) {
try {
Intent intent = new Intent(action);
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index 40f844c..f36be9d 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -22,6 +22,8 @@
LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_JNI_SHARED_LIBRARIES := libctssecurity_jni
+
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsSecurityTestCases
@@ -31,3 +33,5 @@
LOCAL_SDK_VERSION := current
include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/uiautomator/test-apps/Android.mk b/tests/tests/security/jni/Android.mk
similarity index 60%
rename from tests/uiautomator/test-apps/Android.mk
rename to tests/tests/security/jni/Android.mk
index e790e1e..ee185c5 100644
--- a/tests/uiautomator/test-apps/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -12,4 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-include $(call all-subdir-makefiles)
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libctssecurity_jni
+
+# Don't include this package in any configuration by default.
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ CtsSecurityJniOnLoad.cpp \
+ android_security_cts_CharDeviceTest.cpp
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+
+LOCAL_SHARED_LIBRARIES := libnativehelper liblog
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
new file mode 100644
index 0000000..045581f
--- /dev/null
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -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.
+ */
+
+#include <jni.h>
+#include <stdio.h>
+
+extern int register_android_security_cts_CharDeviceTest(JNIEnv*);
+
+jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+ JNIEnv *env = NULL;
+
+ if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
+ return JNI_ERR;
+ }
+
+ if (register_android_security_cts_CharDeviceTest(env)) {
+ return JNI_ERR;
+ }
+
+ return JNI_VERSION_1_4;
+}
diff --git a/tests/tests/security/jni/android_security_cts_CharDeviceTest.cpp b/tests/tests/security/jni/android_security_cts_CharDeviceTest.cpp
new file mode 100644
index 0000000..9aea4b3
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_CharDeviceTest.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+#include <jni.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <cutils/log.h>
+
+#define PHYS_OFFSET 0x40000000
+
+/*
+ * Native methods used by
+ * cts/tests/tests/permission/src/android/security/cts/CharDeviceTest.java
+ */
+
+jboolean android_security_cts_CharDeviceTest_doExynosWriteTest(JNIEnv* env, jobject thiz)
+{
+ int page_size = sysconf(_SC_PAGE_SIZE);
+ int length = page_size * page_size;
+ int fd = open("/dev/exynos-mem", O_RDWR);
+ if (fd < 0) {
+ return true;
+ }
+
+ char *addr = (char *)
+ mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PHYS_OFFSET);
+
+ if (addr == MAP_FAILED) {
+ goto done2;
+ }
+
+ /*
+ * In the presence of the vulnerability, the code below will
+ * cause the device to crash, because we're scribbling all
+ * over kernel memory
+ */
+
+ int i;
+ for (i = 0; i < length; i++) {
+ addr[i] = 'A';
+ }
+ usleep(100000);
+
+done1:
+ munmap(addr, length);
+done2:
+ close(fd);
+ return true;
+}
+
+jboolean android_security_cts_CharDeviceTest_doExynosReadTest(JNIEnv* env, jobject thiz)
+{
+ const char *MAGIC_STRING = "KHAAAAN!!! EXYNOS!!!";
+
+ jboolean ret = true;
+ int page_size = sysconf(_SC_PAGE_SIZE);
+ int length = page_size * page_size;
+ int fd = open("/dev/exynos-mem", O_RDONLY);
+ if (fd < 0) {
+ return true;
+ }
+
+ char *addr = (char *)
+ mmap(NULL, length, PROT_READ, MAP_SHARED, fd, PHYS_OFFSET);
+
+ if (addr == MAP_FAILED) {
+ goto done2;
+ }
+
+ // Throw the magic string into the kernel ring buffer. Once
+ // there, we shouldn't be able to access it.
+ ALOGE("%s", MAGIC_STRING);
+
+ // Now see if we can scan kernel memory, looking for our magic
+ // string. If we find it, return false.
+ int i;
+ for (i = 0; i < (length - strlen(MAGIC_STRING)); i++) {
+ if (strncmp(&addr[i], MAGIC_STRING, strlen(MAGIC_STRING)) == 0) {
+ ret = false;
+ break;
+ }
+ }
+
+done1:
+ munmap(addr, length);
+done2:
+ close(fd);
+ return ret;
+}
+
+static JNINativeMethod gMethods[] = {
+ { "doExynosWriteTest", "()Z",
+ (void *) android_security_cts_CharDeviceTest_doExynosWriteTest },
+ { "doExynosReadTest", "()Z",
+ (void *) android_security_cts_CharDeviceTest_doExynosReadTest },
+};
+
+int register_android_security_cts_CharDeviceTest(JNIEnv* env)
+{
+ jclass clazz = env->FindClass("android/security/cts/CharDeviceTest");
+ return env->RegisterNatives(clazz, gMethods,
+ sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/security/src/android/security/cts/CharDeviceTest.java b/tests/tests/security/src/android/security/cts/CharDeviceTest.java
new file mode 100644
index 0000000..51975b9
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CharDeviceTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.security.cts;
+
+import junit.framework.TestCase;
+
+public class CharDeviceTest extends TestCase {
+
+ static {
+ System.loadLibrary("ctssecurity_jni");
+ }
+
+ /**
+ * Detect Exynos 4xxx rooting vuln. CVE-2012-6422.
+ *
+ * Reference: http://forum.xda-developers.com/showthread.php?t=2048511
+ */
+ public void testExynosRootingVuln() throws Exception {
+ assertTrue(doExynosWriteTest());
+ }
+
+ /**
+ * Detect Exynos 4xxx kernel memory leak to userspace. CVE-2012-6422.
+ *
+ * Reference: http://forum.xda-developers.com/showthread.php?t=2048511
+ */
+ public void testExynosKernelMemoryRead() throws Exception {
+ assertTrue(doExynosReadTest());
+ }
+
+ /**
+ * @return true iff the device does not have the exynos rooting
+ * vulnerability. If the device has the rooting vulnerability,
+ * this method will cause the device to crash and this function
+ * will never return.
+ */
+ private static native boolean doExynosWriteTest();
+
+ /**
+ * @return true iff the device does not provide read-access to kernel memory
+ */
+ private static native boolean doExynosReadTest();
+}
diff --git a/tests/tests/view/src/android/view/cts/NumberPickerTest.java b/tests/tests/view/src/android/view/cts/NumberPickerTest.java
new file mode 100644
index 0000000..2e2733e
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/NumberPickerTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.view.cts;
+
+import android.test.AndroidTestCase;
+import android.widget.NumberPicker;
+
+public class NumberPickerTest extends AndroidTestCase {
+
+ public void testSetDisplayedValues1() throws Exception {
+ NumberPicker numberPicker = new NumberPicker(getContext());
+ numberPicker.setMinValue(10);
+ numberPicker.setMaxValue(12);
+ numberPicker.setDisplayedValues(new String[]{"One", "Two", "Three"});
+ }
+
+ public void testSetDisplayedValues2() throws Exception {
+ NumberPicker numberPicker = new NumberPicker(getContext());
+ numberPicker.setMinValue(10);
+ numberPicker.setMaxValue(14);
+ try {
+ numberPicker.setDisplayedValues(new String[]{"One", "Two", "Three"});
+ fail("The size of the displayed values array must be equal to the selectable numbers!");
+ } catch (Exception e) {
+ /* expected */
+ }
+ }
+}
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupTest.java b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
index 1fc9a88..b46c031 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
@@ -1661,6 +1661,63 @@
assertFalse(vg.isGetChildStaticTransformationCalled);
}
+ static public int resetRtlPropertiesCount;
+ static public int resetResolvedLayoutDirectionCount;
+ static public int resetResolvedTextDirectionCount;
+ static public int resetResolvedTextAlignmentCount;
+ static public int resetResolvedPaddingCount;
+ static public int resetResolvedDrawablesCount;
+
+
+ private static void clearRtlCounters() {
+ resetRtlPropertiesCount = 0;
+ resetResolvedLayoutDirectionCount = 0;
+ resetResolvedTextDirectionCount = 0;
+ resetResolvedTextAlignmentCount = 0;
+ resetResolvedPaddingCount = 0;
+ resetResolvedDrawablesCount = 0;
+ }
+
+ public void testResetRtlProperties() {
+ clearRtlCounters();
+
+ MockViewGroup vg = new MockViewGroup(mContext);
+ MockView2 v1 = new MockView2(mContext);
+ MockView2 v2 = new MockView2(mContext);
+
+ MockViewGroup v3 = new MockViewGroup(mContext);
+ MockView2 v4 = new MockView2(mContext);
+
+ v3.addView(v4);
+ assertEquals(1, resetRtlPropertiesCount);
+ assertEquals(1, resetResolvedLayoutDirectionCount);
+ assertEquals(1, resetResolvedTextDirectionCount);
+ assertEquals(1, resetResolvedTextAlignmentCount);
+ assertEquals(1, resetResolvedPaddingCount);
+ assertEquals(1, resetResolvedDrawablesCount);
+
+ clearRtlCounters();
+ vg.addView(v1);
+ vg.addView(v2);
+ vg.addView(v3);
+
+ assertEquals(3, resetRtlPropertiesCount); // for v1 / v2 / v3 only
+ assertEquals(4, resetResolvedLayoutDirectionCount); // for v1 / v2 / v3 / v4
+ assertEquals(4, resetResolvedTextDirectionCount);
+ assertEquals(3, resetResolvedTextAlignmentCount); // for v1 / v2 / v3 only
+ assertEquals(4, resetResolvedPaddingCount);
+ assertEquals(4, resetResolvedDrawablesCount);
+
+ clearRtlCounters();
+ vg.resetRtlProperties();
+ assertEquals(1, resetRtlPropertiesCount); // for vg only
+ assertEquals(5, resetResolvedLayoutDirectionCount); // for all
+ assertEquals(5, resetResolvedTextDirectionCount);
+ assertEquals(1, resetResolvedTextAlignmentCount); // for vg only as TextAlignment is not inherited (default is Gravity)
+ assertEquals(5, resetResolvedPaddingCount);
+ assertEquals(5, resetResolvedDrawablesCount);
+ }
+
static class MockTextView extends TextView {
public boolean isClearFocusCalled;
@@ -2071,6 +2128,93 @@
public void setStaticTransformationsEnabled(boolean enabled) {
super.setStaticTransformationsEnabled(enabled);
}
+
+ @Override
+ public void resetRtlProperties() {
+ super.resetRtlProperties();
+ resetRtlPropertiesCount++;
+ }
+
+ @Override
+ public void resetResolvedLayoutDirection() {
+ super.resetResolvedLayoutDirection();
+ resetResolvedLayoutDirectionCount++;
+ }
+
+ @Override
+ public void resetResolvedTextDirection() {
+ super.resetResolvedTextDirection();
+ resetResolvedTextDirectionCount++;
+ }
+
+ @Override
+ public void resetResolvedTextAlignment() {
+ super.resetResolvedTextAlignment();
+ resetResolvedTextAlignmentCount++;
+ }
+
+ @Override
+ public void resetResolvedPadding() {
+ super.resetResolvedPadding();
+ resetResolvedPaddingCount++;
+ }
+
+ @Override
+ protected void resetResolvedDrawables() {
+ super.resetResolvedDrawables();
+ resetResolvedDrawablesCount++;
+ }
+ }
+
+ static class MockView2 extends View {
+
+ public MockView2(Context context) {
+ super(context);
+ }
+
+ public MockView2(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public MockView2(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public void resetRtlProperties() {
+ super.resetRtlProperties();
+ resetRtlPropertiesCount++;
+ }
+
+ @Override
+ public void resetResolvedLayoutDirection() {
+ super.resetResolvedLayoutDirection();
+ resetResolvedLayoutDirectionCount++;
+ }
+
+ @Override
+ public void resetResolvedTextDirection() {
+ super.resetResolvedTextDirection();
+ resetResolvedTextDirectionCount++;
+ }
+
+ @Override
+ public void resetResolvedTextAlignment() {
+ super.resetResolvedTextAlignment();
+ resetResolvedTextAlignmentCount++;
+ }
+
+ @Override
+ public void resetResolvedPadding() {
+ super.resetResolvedPadding();
+ resetResolvedPaddingCount++;
+ }
+
+ @Override
+ protected void resetResolvedDrawables() {
+ super.resetResolvedDrawables();
+ resetResolvedDrawablesCount++;
+ }
}
public void setResult(int resultCode) {
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 9080320..533e8a8 100755
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -3151,7 +3151,12 @@
tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
+ // No reset when we remove the view
ll.removeView(tv);
+ assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
+
+ // Reset is done when we add the view
+ ll.addView(tv);
assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
}
@@ -3274,8 +3279,13 @@
tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
+ // No reset when we remove the view
ll.removeView(tv);
- // default text alignment is GRAVITY
+ assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
+
+ // Reset is done when we add the view
+ // Default text alignment is GRAVITY
+ ll.addView(tv);
assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
}
diff --git a/tests/uiautomator/Android.mk b/tests/uiautomator/Android.mk
index b5bfae3..68b1dc2 100644
--- a/tests/uiautomator/Android.mk
+++ b/tests/uiautomator/Android.mk
@@ -22,7 +22,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE := CtsUiAutomatorTests
-LOCAL_JAVA_LIBRARIES := uiautomator_sdk_v16
+LOCAL_JAVA_LIBRARIES := uiautomator_sdk_v17
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_CTS_TEST_APK := CtsUiAutomatorApp
LOCAL_CTS_TEST_APP_PACKAGE := com.android.cts.uiautomator
diff --git a/tests/uiautomator/src/com/android/cts/uiautomatortest/CtsUiAutomatorTest.java b/tests/uiautomator/src/com/android/cts/uiautomatortest/CtsUiAutomatorTest.java
index 2161820..5de9805 100644
--- a/tests/uiautomator/src/com/android/cts/uiautomatortest/CtsUiAutomatorTest.java
+++ b/tests/uiautomator/src/com/android/cts/uiautomatortest/CtsUiAutomatorTest.java
@@ -15,17 +15,832 @@
*/
package com.android.cts.uiautomatortest;
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.uiautomator.core.UiCollection;
+import com.android.uiautomator.core.UiDevice;
+import com.android.uiautomator.core.UiObject;
+import com.android.uiautomator.core.UiObjectNotFoundException;
+import com.android.uiautomator.core.UiScrollable;
+import com.android.uiautomator.core.UiSelector;
+import com.android.uiautomator.core.UiWatcher;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+
/**
* Sanity test uiautomator functionality on target device.
*/
public class CtsUiAutomatorTest extends UiAutomatorTestCase {
+ private static final String LOG_TAG = CtsUiAutomatorTest.class.getSimpleName();
+ private static final String[] LIST_SCROLL_TESTS = new String[] {
+ "Test 17", "Test 11", "Test 20"
+ };
+ private static final String LAUNCH_APP = "am start -a android.intent.action.MAIN"
+ + " -n com.android.cts.uiautomator/.MainActivity -W";
+ private static final String PKG_NAME = "com.android.cts.uiautomator";
+
+ // Maximum wait for key object to become visible
+ private static final int WAIT_EXIST_TIMEOUT = 5 * 1000;
+
+ private static final String SCREEN_SHOT_FILE_PATH_NAME = "/data/local/tmp/ctsScreenShot";
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ // Make sure the test app is always running
+ if (!new UiObject(new UiSelector().packageName(PKG_NAME)).exists())
+ runShellCommand(LAUNCH_APP);
+ }
/**
- * Simple test case that launches the test app, and verifies initial UI is present.
+ * Helper to execute a command on the shell
+ *
+ * @throws IOException
+ * @throws InterruptedException
*/
- public void testLaunchAppVerifyUi() {
- // TODO: implement this
+ private void runShellCommand(String command) throws IOException, InterruptedException {
+ Process p = null;
+ BufferedReader resultReader = null;
+ try {
+ p = Runtime.getRuntime().exec(command);
+ int status = p.waitFor();
+ if (status != 0) {
+ throw new RuntimeException(String.format("Run shell command: %s, status: %s",
+ command, status));
+ }
+ } finally {
+ if (resultReader != null) {
+ resultReader.close();
+ }
+ if (p != null) {
+ p.destroy();
+ }
+ }
+ }
+
+ /*
+ * Items in the listScrollTests array should be spread out such that a
+ * scroll is required to reach each item at each of the far ends.
+ */
+ public void testListScrollAndSelect() throws UiObjectNotFoundException {
+ UiScrollable listView = new UiScrollable(
+ new UiSelector().className(android.widget.ListView.class.getName()));
+
+ // on single fragment display
+ if (!listView.exists())
+ UiDevice.getInstance().pressBack();
+
+ for (String test : LIST_SCROLL_TESTS) {
+ openTest(test);
+ verifyTestDetailsExists(test);
+ }
+ }
+
+ /**
+ * Test erasing of multi word text in edit field and input of new text. Test
+ * verifying input text using a complex UiSelector
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testTextEraseAndInput() throws UiObjectNotFoundException {
+ String testText = "Android Ui Automator Input Text";
+ openTest("Test 1");
+
+ UiObject editText = new UiObject(new UiSelector().className(android.widget.EditText.class
+ .getName()));
+ editText.setText(testText);
+
+ UiObject submitButton = new UiObject(new UiSelector()
+ .className(android.widget.Button.class.getName()).clickable(true)
+ .textStartsWith("Submit"));
+ submitButton.click();
+
+ UiObject result = new UiObject(new UiSelector().className(
+ android.widget.LinearLayout.class.getName()).childSelector(
+ (new UiSelector().className(android.widget.ScrollView.class.getName())
+ .childSelector(new UiSelector().className(android.widget.TextView.class
+ .getName())))));
+
+ if (!testText.equals(result.getText())) {
+ throw new UiObjectNotFoundException("Test text: " + testText);
+ }
+
+ getObjectByText("OK").click();
+ }
+
+ /**
+ * Select each of the buttons by using only the content description property
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectByContentDescription() throws UiObjectNotFoundException {
+ openTest("Test 2");
+ getObjectByDescription("Button 1").click();
+ verifyDialogActionResults("Button 1");
+ getObjectByDescription("Button 2").click();
+ verifyDialogActionResults("Button 2");
+ getObjectByDescription("Button 3").click();
+ verifyDialogActionResults("Button 3");
+ }
+
+ /**
+ * Select each of the buttons by using only the text property
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectByText() throws UiObjectNotFoundException {
+ openTest("Test 2");
+ getObjectByText("Button 1").click();
+ verifyDialogActionResults("Button 1");
+ getObjectByText("Button 2").click();
+ verifyDialogActionResults("Button 2");
+ getObjectByText("Button 3").click();
+ verifyDialogActionResults("Button 3");
+ }
+
+ /**
+ * Select each of the buttons by using only the index property
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectByIndex() throws UiObjectNotFoundException {
+ openTest("Test 2");
+ getObjectByIndex(android.widget.Button.class.getName(), 0).click();
+ verifyDialogActionResults("Button 1");
+ getObjectByIndex(android.widget.Button.class.getName(), 1).click();
+ verifyDialogActionResults("Button 2");
+ getObjectByIndex(android.widget.Button.class.getName(), 2).click();
+ verifyDialogActionResults("Button 3");
+ }
+
+ /**
+ * Select each of the buttons by using only the instance number
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectByInstance() throws UiObjectNotFoundException {
+ openTest("Test 2");
+ getObjectByInstance(android.widget.Button.class.getName(), 0).click();
+ verifyDialogActionResults("Button 1");
+ getObjectByInstance(android.widget.Button.class.getName(), 1).click();
+ verifyDialogActionResults("Button 2");
+ getObjectByInstance(android.widget.Button.class.getName(), 2).click();
+ verifyDialogActionResults("Button 3");
+ }
+
+ /**
+ * Test if a the content changed due to an action can be verified
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectAfterContentChanged() throws UiObjectNotFoundException {
+ openTest("Test 2");
+ getObjectByText("Before").click();
+ getObjectByText("After").click();
+ }
+
+ /**
+ * Test opening the options menu using the soft buttons
+ *
+ * @throws UiObjectNotFoundException
+ * @throws InterruptedException
+ * @throws IOException
+ */
+ public void testDeviceSoftKeys() throws UiObjectNotFoundException, IOException,
+ InterruptedException {
+ openTest("Test 2");
+ UiDevice device = UiDevice.getInstance();
+ device.pressMenu();
+ getObjectByText("Finish").click();
+ verifyDialogActionResults("Finish");
+
+ // Back button
+ openTest("Test 1");
+ UiObject editText = new UiObject(new UiSelector().className(android.widget.EditText.class
+ .getName()));
+ editText.setText("Android Geppetto Test Application");
+
+ UiObject submitButton = new UiObject(new UiSelector()
+ .className(android.widget.Button.class.getName()).clickable(true)
+ .textStartsWith("Submit"));
+ submitButton.click();
+
+ // Text from the popup dialog
+ UiObject result = new UiObject(new UiSelector().textContains("geppetto"));
+
+ // Back button test to dismiss the dialog
+ assertTrue("Wait for exist must return true", result.waitForExists(2000));
+ device.pressBack();
+ result.waitUntilGone(1000);
+ assertFalse("Wait for exist must return false after press back", result.exists());
+
+ // Home button test
+ openTest("Test 5");
+ String pkgName = device.getCurrentPackageName();
+ assertTrue("CTS test app must be running", pkgName.equals(PKG_NAME));
+ device.pressHome();
+ boolean gone = new UiObject(new UiSelector().packageName(PKG_NAME)).waitUntilGone(5000);
+ assertTrue("CTS test app still visble after pressing home", gone);
+ }
+
+ /**
+ * This view is in constant update generating window content changed events.
+ * The test will read the time displayed and exhaust each wait for idle
+ * timeout until it read and sets the text back into the edit field and
+ * presses submit. A dialog box should pop up with the time it took since
+ * reading the value until pressing submit.
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testWaitForIdleTimeout() throws UiObjectNotFoundException {
+ openTest("Test 3");
+ UiObject clk = new UiObject(new UiSelector().descriptionStartsWith("Performance "));
+
+ // First default wait for idle timeout assumed to be 10 seconds
+ String txtTime = clk.getText();
+ UiObject edit = new UiObject(new UiSelector().className(android.widget.EditText.class
+ .getName()));
+
+ // Second default wait for idle timeout assumed to be 10 seconds.
+ // Total ~20.
+ edit.setText(txtTime);
+
+ // Third default wait for idle timeout assumed to be 10 seconds.
+ // Total ~30.
+ getObjectByText("Submit").click();
+
+ // The value read should have value between 30 and 60 seconds indicating
+ // that the internal default timeouts for wait-for-idle is in acceptable
+ // range.
+ UiObject readTime = new UiObject(new UiSelector().className(
+ android.widget.TextView.class.getName()).instance(1));
+ String timeDiff = readTime.getText();
+ Log.i(LOG_TAG, "Sync time: " + timeDiff);
+
+ getObjectByText("OK").click();
+
+ int totalDelay = Integer.parseInt(timeDiff);
+
+ // Cumulative waits in this test should add up to at minimum 30 seconds
+ assertFalse("Timeout for wait-for-idle is too short. Expecting minimum 10 seconds",
+ totalDelay < 30 * 1000);
+
+ // allow for tolerance in time measurements due to differences between
+ // device speeds
+ assertFalse("Timeout for wait-for-idle is too long. Expecting maximum 15 seconds",
+ totalDelay > 60 * 1000);
+ }
+
+ /**
+ * This view is in constant update generating window content changed events.
+ * This test uses the soft key presses and clicks while the background
+ * screen is constantly updating causing a constant busy state.
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testVerifyMenuClicks() throws UiObjectNotFoundException {
+ openTest("Test 3");
+ UiDevice.getInstance().pressMenu();
+ new UiObject(new UiSelector().text("Submit")).click();
+ verifyDialogActionResults("Submit");
+ UiDevice.getInstance().pressMenu();
+ new UiObject(new UiSelector().text("Exit")).click();
+ verifyDialogActionResults("Exit");
+ }
+
+ /**
+ * Verifies swipeRight, swipeLeft and raw swipe APIs perform as expected.
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSwipes() throws UiObjectNotFoundException {
+ openTest("Test 4");
+ UiObject textView = new UiObject(new UiSelector().textContains("["));
+
+ textView.swipeLeft(10);
+ assertTrue("UiObject swipe left", "[ 2 ]".equals(textView.getText()));
+
+ textView.swipeLeft(10);
+ assertTrue("UiObject swipe left", "[ 3 ]".equals(textView.getText()));
+
+ textView.swipeLeft(10);
+ assertTrue("UiObject swipe left", "[ 4 ]".equals(textView.getText()));
+
+ textView.swipeRight(10);
+ assertTrue("UiObject swipe right", "[ 3 ]".equals(textView.getText()));
+
+ textView.swipeRight(10);
+ assertTrue("UiObject swipe right", "[ 2 ]".equals(textView.getText()));
+
+ textView.swipeRight(10);
+ assertTrue("UiObject swipe right", "[ 1 ]".equals(textView.getText()));
+
+ Rect tb = textView.getBounds();
+ UiDevice.getInstance().swipe(tb.right - 20, tb.centerY(), tb.left + 20, tb.centerY(), 50);
+ assertTrue("UiDevice swipe", "[ 2 ]".equals(textView.getText()));
+ }
+
+ /**
+ * Creates a complex selector
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testComplexSelectors() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiSelector frameLayout = new UiSelector().className(android.widget.FrameLayout.class
+ .getName());
+ UiSelector gridLayout = new UiSelector().className(android.widget.GridLayout.class
+ .getName());
+ UiSelector toggleButton = new UiSelector().className(android.widget.ToggleButton.class
+ .getName());
+ UiObject button = new UiObject(frameLayout.childSelector(gridLayout).childSelector(
+ toggleButton));
+
+ assertTrue("Toggle button value should be OFF", "OFF".equals(button.getText()));
+ button.click();
+ assertTrue("Toggle button value should be ON", "ON".equals(button.getText()));
+ button.click();
+ assertTrue("Toggle button value should be OFF", "OFF".equals(button.getText()));
+ }
+
+ /**
+ * The view contains a WebView with static content. This test uses the text
+ * traversal feature of pressing down arrows to read the view's contents
+ *
+ * @throws UiObjectNotFoundException
+ */
+ /*// broken in MR1
+ public void testWebViewTextTraversal() throws UiObjectNotFoundException {
+ openTest("Test 6");
+ UiObject webView = new UiObject(new UiSelector().className(android.webkit.WebView.class
+ .getName()));
+ webView.clickTopLeft();
+ UiDevice device = UiDevice.getInstance();
+ device.clearLastTraversedText();
+
+ device.pressDPadDown();
+ String text = device.getLastTraversedText();
+ assertTrue("Read regular text", text.contains("This is test <b>6</b>"));
+
+ device.pressDPadDown();
+ text = device.getLastTraversedText();
+ assertTrue("Anchor text", text.contains("<a"));
+
+ device.pressDPadDown();
+ text = device.getLastTraversedText();
+ assertTrue("h5 text", text.contains("h5"));
+
+ device.pressDPadDown();
+ text = device.getLastTraversedText();
+ assertTrue("Anchor text", text.contains("<a"));
+
+ device.pressDPadDown();
+ text = device.getLastTraversedText();
+ assertTrue("h4 text", text.contains("h4"));
+ }*/
+
+ /**
+ * Test when an object does not exist, an exception is thrown
+ */
+ public void testExceptionObjectNotFound() {
+ UiSelector selector = new UiSelector().text("Nothing should be found");
+ UiSelector child = new UiSelector().className("Nothing");
+ UiObject obj = new UiObject(selector.childSelector(child));
+
+ assertFalse("Object is reported as existing", obj.exists());
+
+ try {
+ obj.click();
+ } catch (UiObjectNotFoundException e) {
+ return;
+ }
+ assertTrue("Exception not thrown for Object not found", false);
+ }
+
+ /**
+ * Verifies the UiWatcher registration and trigger function
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testUiWatcher() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiDevice device = UiDevice.getInstance();
+ device.registerWatcher("Artificial crash", new UiWatcher() {
+
+ @Override
+ public boolean checkForCondition() {
+ if (new UiObject(new UiSelector().packageName("android")).exists()) {
+ try {
+ // Expecting a localized OK button
+ new UiObject(new UiSelector().className(
+ android.widget.Button.class.getName()).enabled(true)).click();
+ } catch (UiObjectNotFoundException e) {
+ }
+ return true;
+ }
+ return false;
+ }
+ });
+
+ // Causes a runtime exception to be thrown
+ getObjectByText("Button").click();
+
+ // Fake doing something while the exception is being displayed
+ SystemClock.sleep(2000);
+ device.runWatchers();
+ assertTrue("UiWatcher not triggered", device.hasAnyWatcherTriggered());
+ }
+
+ /**
+ * Verifies the 'checked' property of both UiSelector and UiObject
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectorChecked() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiObject checkboxChecked = new UiObject(new UiSelector().className(
+ android.widget.CheckBox.class.getName()).checked(true));
+ UiObject checkboxNotChecked = new UiObject(new UiSelector().className(
+ android.widget.CheckBox.class.getName()).checked(false));
+
+ checkboxNotChecked.click();
+ assertTrue("Checkbox should be checked", checkboxChecked.isChecked());
+ checkboxChecked.click();
+ assertFalse("Checkbox should be unchecked", checkboxNotChecked.isChecked());
+ }
+
+ /**
+ * Verifies the 'Clickable' property of both the UiSelector and UiObject
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectorClickable() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiSelector clickableCheckbox = new UiSelector().clickable(true).className(
+ android.widget.CheckBox.class.getName());
+ UiSelector notClickableProgress = new UiSelector().clickable(false).className(
+ android.widget.ProgressBar.class.getName());
+
+ assertTrue("Selector clickable", new UiObject(clickableCheckbox).isClickable());
+ assertFalse("Selector not clickable", new UiObject(notClickableProgress).isClickable());
+ }
+
+ /**
+ * Verifies the 'focusable' property of both UiSelector and UiObject
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectorFocusable() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiSelector mainLayout = new UiSelector().description("Widgets Collection");
+ UiSelector focusableCheckbox = mainLayout.childSelector(new UiSelector().className(
+ android.widget.CheckBox.class.getName()).focusable(true));
+ UiSelector notFocusableSpinner = mainLayout.childSelector(new UiSelector().className(
+ android.widget.Spinner.class.getName()).focusable(false));
+
+ assertTrue("Selector focusable", new UiObject(focusableCheckbox).isFocusable());
+ assertFalse("Selector not focusable", new UiObject(notFocusableSpinner).isFocusable());
+ }
+
+ /**
+ * Verifies the 'DescriptionContains' property of UiSelector
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectorDescriptionContains() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiSelector progressDescriptionContains = new UiSelector().descriptionContains("%");
+ assertTrue("Selector descriptionContains", "Progress is 50 %".equals(new UiObject(
+ progressDescriptionContains).getContentDescription()));
+ }
+
+ /**
+ * Verifies the 'DescriptionStarts' property of UiSelector
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectorDescriptionStarts() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiSelector progressDescriptionStart = new UiSelector().descriptionStartsWith("progress");
+ assertTrue("Selector descriptionStart", "Progress is 50 %".equals(new UiObject(
+ progressDescriptionStart).getContentDescription()));
+ }
+
+ /**
+ * Verifies the 'Enabled' property of both UiSelector and UiObject
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testSelectorEnabled() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiSelector mainLayout = new UiSelector().description("Widgets Collection");
+ UiSelector buttonDisabled = mainLayout.childSelector(new UiSelector().className(
+ android.widget.Button.class.getName()).enabled(false));
+ UiSelector buttonEnabled = mainLayout.childSelector(new UiSelector().className(
+ android.widget.Button.class.getName()).enabled(true));
+
+ assertFalse("Selector enabled false", new UiObject(buttonDisabled).isEnabled());
+ assertTrue("Selector enabled true", new UiObject(buttonEnabled).isEnabled());
+ }
+
+ /**
+ * Verifies the UiCollection object child counting by object pattern
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testCollectionCount() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiCollection collection = new UiCollection(
+ new UiSelector().description("Widgets Collection"));
+ assertTrue("Collection layout not found", collection.waitForExists(WAIT_EXIST_TIMEOUT));
+
+ assertTrue("Collection count",
+ collection.getChildCount(new UiSelector().clickable(true)) == 6);
+ }
+
+ /**
+ * Verifies the UiCollection can find an object by text and returning by
+ * pattern
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testCollectionGetChildByText() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiCollection collection = new UiCollection(
+ new UiSelector().description("Widgets Collection"));
+ assertTrue("Collection layout not found", collection.waitForExists(WAIT_EXIST_TIMEOUT));
+
+ UiObject item = collection.getChildByText(
+ new UiSelector().className(android.widget.Button.class.getName()), "Button");
+
+ assertTrue("Collection get child by text", "Button".equals(item.getText()));
+ }
+
+ /**
+ * Verifies the UiCollection can find an object by instance and returning by
+ * pattern
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testCollectionGetChildByInstance() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiCollection collection = new UiCollection(
+ new UiSelector().description("Widgets Collection"));
+ assertTrue("Collection layout not found", collection.waitForExists(WAIT_EXIST_TIMEOUT));
+
+ // find the second button
+ UiObject item = collection.getChildByInstance(
+ new UiSelector().className(android.widget.Button.class.getName()), 1);
+
+ assertTrue("Collection get child by instance", "Button".equals(item.getText()));
+ }
+
+ /**
+ * Verifies the UiCollection can find an object by description and returning
+ * by pattern
+ *
+ * @throws UiObjectNotFoundException
+ */
+ public void testCollectionGetChildByDescription() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiCollection collection = new UiCollection(
+ new UiSelector().description("Widgets Collection"));
+ assertTrue("Collection layout not found", collection.waitForExists(WAIT_EXIST_TIMEOUT));
+
+ UiObject item = collection.getChildByDescription(
+ new UiSelector().className(android.widget.Button.class.getName()),
+ "Description for Button");
+
+ assertTrue("Collection get child by description", "Button".equals(item.getText()));
+ }
+
+ /**
+ * Test Orientation APIs by causing rotations and verifying current state
+ *
+ * @throws RemoteException
+ * @throws UiObjectNotFoundException
+ * @since API Level 17
+ */
+ public void testRotation() throws RemoteException, UiObjectNotFoundException {
+ openTest("Test 5");
+ UiDevice device = UiDevice.getInstance();
+
+ device.setOrientationLeft();
+ device.waitForIdle(); // isNaturalOrientation is not waiting for idle
+ SystemClock.sleep(1000);
+ assertFalse("Device orientation should not be natural", device.isNaturalOrientation());
+
+ device.setOrientationNatural();
+ device.waitForIdle(); // isNaturalOrientation is not waiting for idle
+ SystemClock.sleep(1000);
+ assertTrue("Device orientation should be natural", device.isNaturalOrientation());
+
+ device.setOrientationRight();
+ device.waitForIdle(); // isNaturalOrientation is not waiting for idle
+ SystemClock.sleep(1000);
+ assertFalse("Device orientation should not be natural", device.isNaturalOrientation());
+
+ device.setOrientationNatural();
+ }
+
+ /**
+ * Reads the current device's product name. Since it is not possible to predetermine the
+ * would be value, the check verifies that the value is not null and not empty.
+ *
+ * @since API Level 17
+ */
+ public void testGetProductName() {
+ String name = UiDevice.getInstance().getProductName();
+ assertFalse("Product name check returned empty string", name.isEmpty());
+ }
+
+ /**
+ * Select each of the buttons by using only regex text
+ *
+ * @throws UiObjectNotFoundException
+ * @since API Level 17
+ */
+ public void testSelectByTextMatch() throws UiObjectNotFoundException {
+ openTest("Test 2");
+ getObjectByTextMatch(".*n\\s1$").click();
+ verifyDialogActionResults("Button 1");
+ getObjectByTextMatch(".*n\\s2$").click();
+ verifyDialogActionResults("Button 2");
+ getObjectByTextMatch(".*n\\s3$").click();
+ verifyDialogActionResults("Button 3");
+ }
+
+ /**
+ * Select each of the buttons by using only regex content-description
+ *
+ * @throws UiObjectNotFoundException
+ * @since API Level 17
+ */
+ public void testSelectByDescriptionMatch() throws UiObjectNotFoundException {
+ openTest("Test 2");
+ getObjectByDescriptionMatch(".*n\\s1$").click();
+ verifyDialogActionResults("Button 1");
+ getObjectByDescriptionMatch(".*n\\s2$").click();
+ verifyDialogActionResults("Button 2");
+ getObjectByDescriptionMatch(".*n\\s3$").click();
+ verifyDialogActionResults("Button 3");
+ }
+
+ /**
+ * Select each of the buttons by using only regex class name
+ *
+ * @throws UiObjectNotFoundException
+ * @since API Level 17
+ */
+ public void testSelectByClassMatch() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiObject tgl = getObjectByClassMatch(".*ToggleButton$", 0);
+ String tglValue = tgl.getText();
+ tgl.click();
+
+ assertFalse("Matching class by Regex failed", tglValue.equals(tgl.getText()));
+ }
+
+ /**
+ * Select each of the buttons by using only class type
+ *
+ * @throws UiObjectNotFoundException
+ * @since API Level 17
+ */
+ public void testSelectByClassType() throws UiObjectNotFoundException {
+ openTest("Test 5");
+ UiObject tgl = getObjectByClass(android.widget.ToggleButton.class, 0);
+ String tglValue = tgl.getText();
+ tgl.click();
+
+ assertFalse("Matching class by class type failed", tglValue.equals(tgl.getText()));
+ }
+
+ /**
+ * Test the coordinates of 3 buttons side by side verifying vertical and
+ * horizontal coordinates.
+ *
+ * @throws UiObjectNotFoundException
+ * @since API Level 17
+ */
+ public void testGetVisibleBounds() throws UiObjectNotFoundException {
+ openTest("Test 2");
+ Rect rect1 = getObjectByText("Button 1").getVisibleBounds();
+ Rect rect2 = getObjectByText("Button 2").getVisibleBounds();
+ Rect rect3 = getObjectByText("Button 3").getVisibleBounds();
+
+ assertTrue("X coordinate check failed",
+ rect1.left < rect2.left && rect2.right < rect3.right);
+ assertTrue("Y coordinate check failed",
+ rect1.top == rect2.top && rect2.bottom == rect3.bottom);
+ }
+
+ /**
+ * Tests the LongClick functionality in the API
+ *
+ * @throws UiObjectNotFoundException
+ * @since API Level 17
+ */
+ public void testSelectorLongClickable() throws UiObjectNotFoundException {
+ openTest("Test 2");
+ getObjectByText("Button 1").longClick();
+ verifyDialogActionResults("Longclick Button 1");
+ }
+
+ /**
+ * Test the UiSelector's long-clickable property
+ *
+ * @throws UiObjectNotFoundException
+ * @since API Level 17
+ */
+ public void testSelectorLongClickableProperty() throws UiObjectNotFoundException {
+ UiObject button3 = new UiObject(new UiSelector().className(
+ android.widget.Button.class).longClickable(true).instance(2));
+ button3.longClick();
+ verifyDialogActionResults("Longclick Button 3");
+ }
+
+ /**
+ * Takes a screen shot of the current display and checks if the file is
+ * created and is not zero size.
+ *
+ * @since API Level 17
+ */
+ public void testTakeScreenShots() {
+ File storePath = new File(SCREEN_SHOT_FILE_PATH_NAME);
+ getUiDevice().takeScreenshot(storePath);
+
+ assertTrue("Screenshot file not detected in store", storePath.exists());
+ assertTrue("Zero size for screenshot file", storePath.length() > 0);
+ }
+
+ /**
+ * Private helper to open test views. Also covers UiScrollable tests
+ *
+ * @param name
+ * @throws UiObjectNotFoundException
+ */
+ private void openTest(String name) throws UiObjectNotFoundException {
+ UiScrollable listView = new UiScrollable(
+ new UiSelector().className(android.widget.ListView.class.getName()));
+
+ // on single fragment display
+ if (!listView.exists())
+ UiDevice.getInstance().pressBack();
+
+ UiObject testItem = listView.getChildByText(
+ new UiSelector().className(android.widget.TextView.class.getName()), name);
+
+ testItem.click();
+ }
+
+ private void verifyTestDetailsExists(String name) throws UiObjectNotFoundException {
+ // verify that we're at the right test
+ new UiObject(new UiSelector().description("Details").text(name)).getText();
+ }
+
+ private UiObject getObjectByText(String txt) {
+ return new UiObject(new UiSelector().text(txt));
+ }
+
+ private UiObject getObjectByTextMatch(String regex) {
+ return new UiObject(new UiSelector().textMatches(regex));
+ }
+
+ private UiObject getObjectByDescriptionMatch(String regex) {
+ return new UiObject(new UiSelector().descriptionMatches(regex));
+ }
+
+ private UiObject getObjectByDescription(String txt) {
+ return new UiObject(new UiSelector().description(txt));
+ }
+
+ private UiObject getObjectByClassMatch(String regex, int instance) {
+ return new UiObject(new UiSelector().classNameMatches(regex).instance(instance));
+ }
+
+ private <T> UiObject getObjectByClass(Class<T> type, int instance) {
+ return new UiObject(new UiSelector().className(type).instance(instance));
+ }
+
+ private UiObject getObjectByIndex(String className, int index) {
+ return new UiObject(new UiSelector().className(className).index(index));
+ }
+
+ private UiObject getObjectByInstance(String className, int instance) {
+ return new UiObject(new UiSelector().className(className).instance(instance));
+ }
+
+ private void verifyDialogActionResults(String txt) throws UiObjectNotFoundException {
+ if (!getObjectByText("Action results").exists() || !getObjectByText(txt).exists()) {
+ throw new UiObjectNotFoundException(txt);
+ }
+ getObjectByText("OK").click();
}
}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk b/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
index 72eb681..e30816a 100644
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
@@ -1,3 +1,4 @@
+#
# Copyright (C) 2012 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -11,6 +12,7 @@
# 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)
@@ -24,7 +26,9 @@
LOCAL_SDK_VERSION := current
LOCAL_PACKAGE_NAME := CtsUiAutomatorApp
+LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4
LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
+
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/AndroidManifest.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/AndroidManifest.xml
index 8ab2acf..9b3d8b3 100644
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/AndroidManifest.xml
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/AndroidManifest.xml
@@ -1,34 +1,49 @@
<?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
+<!--
+ * 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.
+ -->
- 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.uiautomator" >
+ package="com.android.cts.uiautomator"
+ android:versionCode="1"
+ android:versionName="1.0" >
+ <uses-sdk
+ android:minSdkVersion="14"
+ android:targetSdkVersion="15" />
+ <uses-permission android:name="android.permission.INTERNET"/>
<application
- android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
- android:name="com.android.cts.uiautomator.MainActivity"
- android:label="@string/app_name" >
+ android:name=".MainActivity"
+ android:label="@string/title_test_list" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
-
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- </application>
+ <activity
+ android:name=".SinglePaneDetailActivity"
+ android:label="@string/title_test_detail" >
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value="FragmentActivity" />
+ </activity>
+ </application>
</manifest>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_action_search.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_action_search.png
new file mode 100644
index 0000000..67de12d
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_action_search.png
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_launcher.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..947dbfc
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-ldpi/ic_launcher.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000..e075065
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_action_search.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_action_search.png
new file mode 100644
index 0000000..134d549
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_action_search.png
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_launcher.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f91af33
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_action_search.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_action_search.png
new file mode 100644
index 0000000..d699c6b
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_action_search.png
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_launcher.png b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..542a9cb
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/activity_main.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/activity_main.xml
index e97c5f9..f0e3bc9 100644
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/activity_main.xml
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/activity_main.xml
@@ -1,3 +1,20 @@
+<?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.
+ -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/list_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/list_activity.xml
new file mode 100644
index 0000000..25bca5d
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/list_activity.xml
@@ -0,0 +1,26 @@
+<?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.
+ -->
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:name="com.android.cts.uiautomator.TestListFragment"
+ android:id="@+id/item_list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ tools:context=".MainActivity" />
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/simple_list_item_selected.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/simple_list_item_selected.xml
new file mode 100644
index 0000000..978ceee
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/simple_list_item_selected.xml
@@ -0,0 +1,28 @@
+<?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.
+ -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
+ android:gravity="center_vertical"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ android:background="?android:attr/activatedBackgroundIndicator"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+/>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/singlepane_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/singlepane_activity.xml
new file mode 100644
index 0000000..78b2545
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/singlepane_activity.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.
+ -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/test_results_detail_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".TestResultsDetailActivity" />
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test1_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test1_detail_fragment.xml
new file mode 100644
index 0000000..c9b2a05
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test1_detail_fragment.xml
@@ -0,0 +1,61 @@
+<?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:id="@+id/test_1_detail_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/item1_test_description"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dp"
+ android:text="@string/test1_description" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+
+ <EditText
+ android:id="@+id/test1TextField"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="5dp"
+ android:layout_weight="2"
+ android:inputType="textNoSuggestions"
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:width="200dip" >
+
+ <requestFocus />
+ </EditText>
+
+ <Button
+ android:id="@+id/test1SubmitButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="5dip"
+ android:layout_marginRight="5dip"
+ android:minWidth="64dip"
+ android:text="@string/buttonSubmit" />
+
+ </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test2_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test2_detail_fragment.xml
new file mode 100644
index 0000000..1bf60b8
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test2_detail_fragment.xml
@@ -0,0 +1,78 @@
+<?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:id="@+id/test_2_detail_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dp"
+ android:text="@string/test2_description" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal" >
+
+ <Button
+ android:id="@+id/test2button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="@string/button1"
+ android:text="@string/button1" />
+
+ <Button
+ android:id="@+id/test2button2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="@string/button2"
+ android:text="@string/button2" />
+
+ <Button
+ android:id="@+id/test2button3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="@string/button3"
+ android:text="@string/button3" />
+ </LinearLayout>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dp"
+ android:text="@string/test2_description_2" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal" >
+
+ <Button
+ android:id="@+id/test2dynaButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="@string/buttonBefore"
+ android:text="@string/buttonBefore" />
+
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test3_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test3_detail_fragment.xml
new file mode 100644
index 0000000..de7ecb6
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test3_detail_fragment.xml
@@ -0,0 +1,76 @@
+<?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:id="@+id/test_3_detail_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/item3_test_description"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dp"
+ android:text="@string/test3_description" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/test3ClockTextView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginBottom="10dip"
+ android:layout_marginTop="10dip"
+ android:contentDescription="@string/test3ClockDescription"
+ android:padding="10dp"
+ android:text="@string/test3InitialClock" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+
+ <EditText
+ android:id="@+id/test3TextField"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="5dp"
+ android:layout_weight="2"
+ android:inputType="numberDecimal"
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip"
+ android:width="200dip" >
+ <requestFocus />
+ </EditText>
+
+ <Button
+ android:id="@+id/test3SubmitButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="5dip"
+ android:layout_marginRight="5dip"
+ android:minWidth="64dip"
+ android:text="@string/buttonSubmit" />
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test4_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test4_detail_fragment.xml
new file mode 100644
index 0000000..dbf88ee
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test4_detail_fragment.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.
+ -->
+ <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/test_4_detail_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".Test4DetailActivity" />
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test5_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test5_detail_fragment.xml
new file mode 100644
index 0000000..e34f271
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test5_detail_fragment.xml
@@ -0,0 +1,109 @@
+<?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:contentDescription="@string/test_5_Widgets_collection"
+ android:orientation="vertical" >
+
+ <CheckBox
+ android:id="@+id/test_5_checkBox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/test5_CheckBox" />
+
+ <Spinner
+ android:id="@+id/test_5_spinner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ProgressBar
+ android:id="@+id/test_5_progressBar"
+ style="?android:attr/progressBarStyleLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <GridLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:columnCount="3" >
+
+ <ImageButton
+ android:id="@+id/test_5_imageButton"
+ android:layout_column="0"
+ android:layout_gravity="left"
+ android:layout_row="0"
+ android:src="@drawable/ic_launcher" />
+
+ <RatingBar
+ android:id="@+id/test_5_ratingBar"
+ android:layout_column="1"
+ android:layout_columnSpan="2"
+ android:layout_gravity="left|bottom"
+ android:layout_row="0" />
+
+ <Button
+ android:id="@+id/test_5_button2"
+ style="?android:attr/buttonStyleSmall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="left|bottom"
+ android:enabled="false"
+ android:layout_row="0"
+ android:text="@string/test5_Button_Disabled" />
+
+ <Space
+ android:layout_width="21dp"
+ android:layout_height="1dp"
+ android:layout_column="1"
+ android:layout_row="0" />
+
+ <Space
+ android:layout_width="1dp"
+ android:layout_height="21dp"
+ android:layout_column="0"
+ android:layout_row="0" />
+
+ <Space
+ android:layout_width="221dp"
+ android:layout_height="15dp"
+ android:layout_column="2"
+ android:layout_row="1" />
+
+ <ToggleButton
+ android:id="@+id/test_5_toggleButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_column="2"
+ android:text="@string/test5_ToggleButton" />
+ </GridLayout>
+
+ <SeekBar
+ android:id="@+id/test_5_seekBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <Button
+ android:id="@+id/test_5_button1"
+ style="?android:attr/buttonStyleSmall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="@string/test5_Button_Description"
+ android:text="@string/test5_Button" />
+
+</LinearLayout>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test6_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test6_detail_fragment.xml
new file mode 100644
index 0000000..01a9fdc
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test6_detail_fragment.xml
@@ -0,0 +1,28 @@
+<?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" >
+
+ <WebView
+ android:id="@+id/test6WebView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test_results_detail_fragment.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test_results_detail_fragment.xml
new file mode 100644
index 0000000..28ed6dd
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/test_results_detail_fragment.xml
@@ -0,0 +1,43 @@
+<?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:id="@+id/test_results_detail_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/textView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dp"
+ android:text="@string/now_displaying_results_for" />
+
+ <TextView
+ android:id="@+id/testResultsTextView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:contentDescription="@string/title_test_detail"
+ android:paddingLeft="2dp"
+ android:paddingTop="5dp"
+ android:textColor="#00aa00"
+ android:textSize="@dimen/padding_large"
+ android:textStyle="bold" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/twopane_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/twopane_activity.xml
new file mode 100644
index 0000000..3777db6
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/layout/twopane_activity.xml
@@ -0,0 +1,41 @@
+<?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"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:divider="?android:attr/dividerHorizontal"
+ android:showDividers="middle"
+ tools:context=".TestListActivity">
+
+ <fragment
+ android:id="@+id/item_list"
+ android:name="com.android.cts.uiautomator.TestListFragment"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+
+ <FrameLayout android:id="@+id/test_detail_container"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="3" />
+
+</LinearLayout>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/activity_main.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/activity_main.xml
index 77f358b..73c4db8 100644
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/activity_main.xml
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/activity_main.xml
@@ -1,3 +1,20 @@
+<?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.
+ -->
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test1_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test1_detail_activity.xml
new file mode 100644
index 0000000..fe1fe20
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test1_detail_activity.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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_settings"
+ android:title="@string/menu_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never" />
+</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test2_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test2_detail_activity.xml
new file mode 100644
index 0000000..405d4c8
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test2_detail_activity.xml
@@ -0,0 +1,32 @@
+<?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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_text1"
+ android:title="Submit" />
+ <item android:id="@+id/menu_text2"
+ android:icon="@drawable/ic_launcher"
+ android:title="Done" />
+ <item android:id="@+id/menu_text3"
+ android:title="OK" />
+ <item android:id="@+id/menu_text4"
+ android:title="Finish" />
+ <item android:id="@+id/menu_text5"
+ android:title="Complete" />
+ <item android:id="@+id/menu_text6"
+ android:title="Exit" />
+</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test3_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test3_detail_activity.xml
new file mode 100644
index 0000000..fe1fe20
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test3_detail_activity.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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_settings"
+ android:title="@string/menu_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never" />
+</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test4_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test4_detail_activity.xml
new file mode 100644
index 0000000..fe1fe20
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test4_detail_activity.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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_settings"
+ android:title="@string/menu_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never" />
+</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test5_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test5_detail_activity.xml
new file mode 100644
index 0000000..fe1fe20
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test5_detail_activity.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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_settings"
+ android:title="@string/menu_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never" />
+</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test6_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test6_detail_activity.xml
new file mode 100644
index 0000000..fe1fe20
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test6_detail_activity.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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_settings"
+ android:title="@string/menu_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never" />
+</menu>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test_results_detail_activity.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test_results_detail_activity.xml
new file mode 100644
index 0000000..febffa2
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/menu/test_results_detail_activity.xml
@@ -0,0 +1,24 @@
+<?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.
+ -->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_settings"
+ android:title="@string/menu_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never" />
+</menu>
+
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/dimens.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/dimens.xml
new file mode 100644
index 0000000..788578a
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/dimens.xml
@@ -0,0 +1,24 @@
+<?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>
+
+ <dimen name="padding_small">8dp</dimen>
+ <dimen name="padding_medium">16dp</dimen>
+ <dimen name="padding_large">16dp</dimen>
+
+</resources>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/refs.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/refs.xml
new file mode 100644
index 0000000..ac82847
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-large/refs.xml
@@ -0,0 +1,20 @@
+<?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>
+ <item type="layout" name="list_activity">@layout/twopane_activity</item>
+</resources>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-sw600dp/refs.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-sw600dp/refs.xml
new file mode 100644
index 0000000..ac82847
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-sw600dp/refs.xml
@@ -0,0 +1,20 @@
+<?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>
+ <item type="layout" name="list_activity">@layout/twopane_activity</item>
+</resources>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v11/styles.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v11/styles.xml
new file mode 100644
index 0000000..504d3e3
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v11/styles.xml
@@ -0,0 +1,22 @@
+<?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>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light" />
+
+</resources>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v14/styles.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v14/styles.xml
new file mode 100644
index 0000000..1232912
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values-v14/styles.xml
@@ -0,0 +1,22 @@
+<?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>
+
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar" />
+
+</resources>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/dimens.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/dimens.xml
new file mode 100644
index 0000000..d607bb7
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/dimens.xml
@@ -0,0 +1,24 @@
+<?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>
+
+ <dimen name="padding_small">8dp</dimen>
+ <dimen name="padding_medium">8dp</dimen>
+ <dimen name="padding_large">16dp</dimen>
+
+</resources>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/strings.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/strings.xml
index 5846d0c..78b829f 100644
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/strings.xml
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/strings.xml
@@ -1,8 +1,62 @@
<?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">CtsUiAutomatorApp</string>
- <string name="hello_world">Hello world!</string>
+ <string name="app_name">UiAutomator Test App</string>
+ <string name="test1_description">This helps verify entering text into a pre-populated field. The pop-up dialog will echo the text entered after clicking submit. The initial value in the field must first be deleted.</string>
<string name="menu_settings">Settings</string>
+ <string name="title_activity_item1_detail">Item1DetailActivity</string>
+ <string name="buttonSubmit">Submit</string>
+ <string name="item1_dialog_title">Text submitted</string>
+ <string name="OK">OK</string>
+ <string name="title_test_list">UiAutomator Tests</string>
+ <string name="title_test_detail">Details</string>
+ <string name="hello_world">Hello world!</string>
+ <string name="title_activity_test2_detail">Test2DetailActivity</string>
+ <string name="test2_description">This helps test selection of button using Instance, Text and Content Description. Once clicked, a dialog pops up to verify the properties of button clicked.</string>
+ <string name="test2_description_2">This tests a Button text changing dynamically after a click. The test should attempt to find the button after it has changed using its new text.</string>
+ <string name="test3_description">The tests should read the clock, then write the clock back into the EditText then press submit. A dialog will display the time it took from reading the clock until submit is press. This can be used to get an idea of performance differences.</string>
+ <string name="button1">Button 1</string>
+ <string name="button1long">Longclick Button 1</string>
+ <string name="button2">Button 2</string>
+ <string name="button2long">Longclick Button 2</string>
+ <string name="button3">Button 3</string>
+ <string name="button3long">Longclick Button 3</string>
+ <string name="buttonBefore">Before</string>
+ <string name="buttonAfter">After</string>
+ <string name="dialog_title_result">Action results</string>
+ <string name="now_displaying_results_for">Verifying scroll into view and list item selection. Now displaying results for:</string>
+ <string name="title_activity_test3_detail">Performance test</string>
+ <string name="test3ClockDescription">Performance clock</string>
+ <string name="test3InitialClock">0000000000</string>
+ <string name="test3_dialog_title">Time difference in ms</string>
+ <string name="test5_CheckBox">CheckBox</string>
+ <string name="test5_ToggleButton">ToggleButton</string>
+ <string name="test5_Button">Button</string>
+ <string name="test5_Button_Description">Description for Button</string>
+ <string name="test5_Button_Disabled">Button D</string>
+ <string name="title_section4">Section 4</string>
+ <string name="title_section3">Section 3</string>
+ <string name="title_section2">Section 2</string>
+ <string name="title_section1">Section 1</string>
+ <string name="title_activity_test4_detail">Test4DetailActivity</string>
+ <string name="title_activity_test5_detail">Test5DetailActivity</string>
+ <string name="title_activity_test6_detail">Test6DetailActivity</string>
+ <string name="test_5_Widgets_collection">Widgets Collection</string>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/styles.xml b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/styles.xml
index 4a10ca4..119c259 100644
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/styles.xml
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/res/values/styles.xml
@@ -1,20 +1,22 @@
+<?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>
- <!--
- Base application theme, dependent on API level. This theme is replaced
- by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
- -->
- <style name="AppBaseTheme" parent="android:Theme.Light">
- <!--
- Theme customizations available in newer API levels can go in
- res/values-vXX/styles.xml, while customizations related to
- backward-compatibility can go here.
- -->
- </style>
-
- <!-- Application theme. -->
- <style name="AppTheme" parent="AppBaseTheme">
- <!-- All customizations that are NOT specific to a particular API-level can go here. -->
- </style>
+ <style name="AppTheme" parent="android:Theme.Light" />
</resources>
\ No newline at end of file
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/MainActivity.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/MainActivity.java
index ee455b8..8d4f144 100644
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/MainActivity.java
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/MainActivity.java
@@ -1,22 +1,60 @@
+/*
+ * 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.uiautomator;
+import android.content.Intent;
import android.os.Bundle;
-import android.app.Activity;
-import android.view.Menu;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.view.WindowManager;
-public class MainActivity extends Activity {
+public class MainActivity extends FragmentActivity implements TestListFragment.Callbacks {
+
+ private boolean mTwoPane;
+ public static final String LOG_TAG = "UiAutomatorApp";
@Override
- protected void onCreate(Bundle savedInstanceState) {
+ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
+
+ // If the device is locked, this attempts to dismiss the KeyGuard
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
+ WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
+ WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+ setContentView(R.layout.list_activity);
+
+ if (findViewById(R.id.test_detail_container) != null) {
+ mTwoPane = true;
+ ((TestListFragment) getSupportFragmentManager().findFragmentById(R.id.item_list))
+ .setActivateOnItemClick(true);
+ }
}
@Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.activity_main, menu);
- return true;
+ public void onItemSelected(String id) {
+ if (mTwoPane) {
+ Fragment fragment = TestItems.getFragment(id);
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.test_detail_container, fragment).commit();
+ } else {
+ Intent detailIntent = new Intent(this, SinglePaneDetailActivity.class);
+ detailIntent.putExtra("item_id", id);
+ startActivity(detailIntent);
+ }
}
-
}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/SinglePaneDetailActivity.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/SinglePaneDetailActivity.java
new file mode 100644
index 0000000..1c0ff8c
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/SinglePaneDetailActivity.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 com.android.cts.uiautomator;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.NavUtils;
+import android.view.Menu;
+import android.view.MenuItem;
+
+public class SinglePaneDetailActivity extends FragmentActivity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.singlepane_activity);
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+
+ if (savedInstanceState == null) {
+ Fragment fragment = TestItems.getFragment(getIntent().getStringExtra("item_id"));
+ getSupportFragmentManager().beginTransaction()
+ .add(R.id.test_results_detail_container, fragment).commit();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.test_results_detail_activity, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ NavUtils.navigateUpFromSameTask(this);
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test1DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test1DetailFragment.java
new file mode 100644
index 0000000..e8eddba
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test1DetailFragment.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 com.android.cts.uiautomator;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+
+public class Test1DetailFragment extends Fragment {
+
+ public static final String ARG_ITEM_ID = "item_id";
+ private Button mSubmitButton;
+ private EditText mEditText;
+ TestItems.TestItem mItem;
+
+ public Test1DetailFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments().containsKey(ARG_ITEM_ID)) {
+ mItem = TestItems.getTest(getArguments().getString(ARG_ITEM_ID));
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+ View rootView = inflater.inflate(R.layout.test1_detail_fragment, container, false);
+ if (mItem != null) {
+ ((EditText) rootView.findViewById(R.id.test1TextField)).setText(mItem.mName);
+
+ mSubmitButton = (Button) rootView.findViewById(R.id.test1SubmitButton);
+ mEditText = (EditText) rootView.findViewById(R.id.test1TextField);
+ mEditText.setText("");
+ mSubmitButton.setOnClickListener(new Button.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final String savedInput = mEditText.getText().toString();
+ // clear so we won't be confused by the input text in
+ // validation
+ mEditText.setText("");
+ // close soft keyboard
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
+ Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
+ // display the submitted text
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.item1_dialog_title);
+ builder.setPositiveButton(R.string.OK, null);
+ builder.setMessage(savedInput);
+ AlertDialog diag = builder.create();
+ diag.show();
+ }
+ });
+ }
+ return rootView;
+ }
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test2DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test2DetailFragment.java
new file mode 100644
index 0000000..4eade4b
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test2DetailFragment.java
@@ -0,0 +1,175 @@
+/*
+ * 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.uiautomator;
+
+import android.app.AlertDialog;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+public class Test2DetailFragment extends Fragment {
+ public static final String ARG_ITEM_ID = "item_id";
+ private Button mButton1, mButton2, mButton3, mDynaButton;
+ private boolean mDynaButtonAfter = false;
+
+ public Test2DetailFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ inflater.inflate(R.menu.test2_detail_activity, menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.dialog_title_result);
+ builder.setMessage(item.getTitle());
+ builder.setPositiveButton(R.string.OK, null);
+ AlertDialog diag = builder.create();
+ diag.show();
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+ View rootView = inflater.inflate(R.layout.test2_detail_fragment, container, false);
+
+ mButton1 = (Button) rootView.findViewById(R.id.test2button1);
+ mButton2 = (Button) rootView.findViewById(R.id.test2button2);
+ mButton3 = (Button) rootView.findViewById(R.id.test2button3);
+ mDynaButton = (Button) rootView.findViewById(R.id.test2dynaButton);
+
+ mButton1.setOnClickListener(new Button.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.dialog_title_result);
+ builder.setPositiveButton(R.string.OK, null);
+ builder.setMessage(R.string.button1);
+ AlertDialog diag = builder.create();
+ diag.show();
+ }
+ });
+
+ mButton1.setOnLongClickListener(new Button.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.dialog_title_result);
+ builder.setPositiveButton(R.string.OK, null);
+ builder.setMessage(R.string.button1long);
+ AlertDialog diag = builder.create();
+ diag.show();
+ return true;
+ }
+ });
+
+ mButton2.setOnClickListener(new Button.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.dialog_title_result);
+ builder.setPositiveButton(R.string.OK, null);
+ builder.setMessage(R.string.button2);
+ AlertDialog diag = builder.create();
+ diag.show();
+ }
+ });
+
+ mButton2.setOnLongClickListener(new Button.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.dialog_title_result);
+ builder.setPositiveButton(R.string.OK, null);
+ builder.setMessage(R.string.button2long);
+ AlertDialog diag = builder.create();
+ diag.show();
+ return true;
+ }
+ });
+
+ mButton3.setOnClickListener(new Button.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.dialog_title_result);
+ builder.setPositiveButton(R.string.OK, null);
+ builder.setMessage(R.string.button3);
+ AlertDialog diag = builder.create();
+ diag.show();
+ }
+ });
+
+ mButton3.setOnLongClickListener(new Button.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.dialog_title_result);
+ builder.setPositiveButton(R.string.OK, null);
+ builder.setMessage(R.string.button3long);
+ AlertDialog diag = builder.create();
+ diag.show();
+ return true;
+ }
+ });
+
+ mDynaButton.setOnClickListener(new Button.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (getActivity().getString(R.string.buttonBefore).equals(mDynaButton.getText())) {
+ mDynaButton.setText(R.string.buttonAfter);
+ mDynaButton
+ .setContentDescription(getActivity().getString(R.string.buttonAfter));
+ mDynaButtonAfter = true;
+ } else {
+ mDynaButton.setText(R.string.buttonBefore);
+ mDynaButton.setContentDescription(getActivity()
+ .getString(R.string.buttonBefore));
+ mDynaButtonAfter = false;
+ }
+ }
+ });
+
+ if (savedState != null && savedState.getBoolean("DynaButtonAfter")) {
+ mDynaButton.setText(R.string.buttonAfter);
+ mDynaButton.setContentDescription(getActivity().getString(R.string.buttonAfter));
+ mDynaButtonAfter = true;
+ }
+ return rootView;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle savedInstanceState) {
+ super.onSaveInstanceState(savedInstanceState);
+ // Save UI state changes to the savedInstanceState.
+ savedInstanceState.putBoolean("DynaButtonAfter", mDynaButtonAfter);
+ }
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test3DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test3DetailFragment.java
new file mode 100644
index 0000000..e0be0cf
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test3DetailFragment.java
@@ -0,0 +1,134 @@
+/*
+ * 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.uiautomator;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+public class Test3DetailFragment extends Fragment {
+
+ public static final String ARG_ITEM_ID = "item_id";
+ private TextView mTextClock;
+ private Button mSubmitButton;
+ private EditText mEditText;
+ private long mCurrentTime;
+ private final Object sync = new Object();
+ private boolean mRunCounter = true;
+
+ public Test3DetailFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ inflater.inflate(R.menu.test2_detail_activity, menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.dialog_title_result);
+ builder.setMessage(item.getTitle());
+ builder.setPositiveButton(R.string.OK, null);
+ AlertDialog diag = builder.create();
+ diag.show();
+ return super.onOptionsItemSelected(item);
+ }
+
+ private final Handler mHandler = new Handler();
+
+ final Runnable mClockRunnable = new Runnable() {
+ @Override
+ public void run() {
+ // call the activity method that updates the UI
+ updateClockOnUi();
+ }
+ };
+
+ private void updateClockOnUi() {
+ synchronized (sync) {
+ mTextClock.setText("" + mCurrentTime);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+ View rootView = inflater.inflate(R.layout.test3_detail_fragment, container, false);
+ mTextClock = (TextView) rootView.findViewById(R.id.test3ClockTextView);
+ mSubmitButton = (Button) rootView.findViewById(R.id.test3SubmitButton);
+ mEditText = (EditText) rootView.findViewById(R.id.test3TextField);
+ mSubmitButton.setOnClickListener(new Button.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // close soft keyboard
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
+ Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
+
+ // display the submitted text
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.test3_dialog_title);
+ builder.setPositiveButton(R.string.OK, null);
+ CharSequence inputText = mEditText.getText();
+ if (inputText != null && !inputText.toString().isEmpty()) {
+ long inputTime = Long.parseLong(inputText.toString());
+ builder.setMessage("" + (mCurrentTime - inputTime));
+ } else {
+ builder.setMessage("<NO DATA>");
+ }
+ AlertDialog diag = builder.create();
+ diag.show();
+ mEditText.setText("");
+ mRunCounter = false;
+ }
+ });
+
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ while (mRunCounter) {
+ synchronized (sync) {
+ mCurrentTime = SystemClock.elapsedRealtime();
+ }
+ mHandler.post(mClockRunnable);
+ SystemClock.sleep(100);
+ }
+ }
+ }).start();
+
+ return rootView;
+ }
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test4DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test4DetailFragment.java
new file mode 100644
index 0000000..0c914dc
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test4DetailFragment.java
@@ -0,0 +1,178 @@
+/*
+ * 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.uiautomator;
+
+import android.app.ActionBar;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class Test4DetailFragment extends Fragment implements ActionBar.TabListener {
+ public static final String ARG_ITEM_ID = "item_id";
+
+ /**
+ * The {@link android.support.v4.view.PagerAdapter} that will provide
+ * fragments for each of the sections. We use a
+ * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
+ * will keep every loaded fragment in memory. If this becomes too memory
+ * intensive, it may be best to switch to a
+ * {@link android.support.v4.app.FragmentStatePagerAdapter}.
+ */
+ SectionsPagerAdapter mSectionsPagerAdapter;
+
+ /**
+ * The {@link ViewPager} that will host the section contents.
+ */
+ ViewPager mViewPager;
+
+ public Test4DetailFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onDestroyView() {
+ getActivity().getActionBar().removeAllTabs();
+ super.onDestroyView();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+
+ View rootView = inflater.inflate(R.layout.test4_detail_fragment, container, false);
+
+ // Set up the action bar.
+ final ActionBar actionBar = getActivity().getActionBar();
+ if (actionBar.getTabCount() > 0) {
+ return rootView;
+ }
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+
+ // Create the adapter that will return a fragment for each of the three
+ // primary sections of the app.
+ mSectionsPagerAdapter = new SectionsPagerAdapter(getActivity().getSupportFragmentManager());
+
+ // Set up the ViewPager with the sections adapter.
+ mViewPager = (ViewPager) rootView.findViewById(R.id.test_4_detail_container);
+ mViewPager.setAdapter(mSectionsPagerAdapter);
+
+ // When swiping between different sections, select the corresponding
+ // tab. We can also use ActionBar.Tab#select() to do this if we have a
+ // reference to the Tab.
+ mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
+ @Override
+ public void onPageSelected(int position) {
+ actionBar.setSelectedNavigationItem(position);
+ }
+ });
+
+ // For each of the sections in the app, add a tab to the action bar.
+ for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
+ // Create a tab with text corresponding to the page title defined by
+ // the adapter. Also specify this Activity object, which implements
+ // the TabListener interface, as the listener for when this tab is
+ // selected.
+ actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(i))
+ .setTabListener(this));
+ }
+ return rootView;
+ }
+
+ @Override
+ public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ }
+
+ @Override
+ public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ }
+
+ @Override
+ public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ }
+
+ /**
+ * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
+ * one of the primary sections of the app.
+ */
+ public class SectionsPagerAdapter extends FragmentPagerAdapter {
+
+ public SectionsPagerAdapter(FragmentManager fm) {
+ super(fm);
+ }
+
+ @Override
+ public Fragment getItem(int i) {
+ Fragment fragment = new DummySectionFragment();
+ Bundle args = new Bundle();
+ args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public int getCount() {
+ return 4;
+ }
+
+ @Override
+ public CharSequence getPageTitle(int position) {
+ switch (position) {
+ case 0:
+ return getString(R.string.title_section1).toUpperCase();
+ case 1:
+ return getString(R.string.title_section2).toUpperCase();
+ case 2:
+ return getString(R.string.title_section3).toUpperCase();
+ case 3:
+ return getString(R.string.title_section4).toUpperCase();
+ }
+ return null;
+ }
+ }
+
+ /**
+ * A dummy fragment representing a section of the app, but that simply
+ * displays dummy text.
+ */
+ public static class DummySectionFragment extends Fragment {
+ public DummySectionFragment() {
+ }
+
+ public static final String ARG_SECTION_NUMBER = "section_number";
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ TextView textView = new TextView(getActivity());
+ textView.setGravity(Gravity.CENTER);
+ Bundle args = getArguments();
+ textView.setText("[ " + Integer.toString(args.getInt(ARG_SECTION_NUMBER)) + " ]");
+ return textView;
+ }
+ }
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test5DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test5DetailFragment.java
new file mode 100644
index 0000000..0f88d3c
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test5DetailFragment.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 com.android.cts.uiautomator;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.ImageButton;
+import android.widget.SeekBar;
+import android.widget.Spinner;
+
+public class Test5DetailFragment extends Fragment {
+
+ public static final String ARG_ITEM_ID = "item_id";
+
+ public Test5DetailFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+ View rootView = inflater.inflate(R.layout.test5_detail_fragment, container, false);
+
+ // Set the content description for the following
+ Spinner spinner = (Spinner) rootView.findViewById(R.id.test_5_spinner);
+ spinner.setContentDescription("Spinner");
+ ImageButton imageButton = (ImageButton) rootView.findViewById(R.id.test_5_imageButton);
+ imageButton.setContentDescription("Image button");
+
+ // Each time this view is displayed, reset the following states
+ SeekBar seekBar = (SeekBar) rootView.findViewById(R.id.test_5_seekBar);
+ seekBar.setProgress(50);
+ seekBar.setContentDescription("Progress is 50 %");
+ CheckBox checkbox = (CheckBox) rootView.findViewById(R.id.test_5_checkBox);
+ checkbox.setChecked(false);
+
+ // Register click event handlers for the following
+ Button button = (Button) rootView.findViewById(R.id.test_5_button1);
+ button.setOnClickListener(new Button.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // we want an artificial crash
+ throw new RuntimeException("Artificial crash to test UiWatcher");
+ }
+ });
+
+ return rootView;
+ }
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test6DetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test6DetailFragment.java
new file mode 100644
index 0000000..90bcfcf
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/Test6DetailFragment.java
@@ -0,0 +1,50 @@
+/*
+ * 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.uiautomator;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebView;
+
+public class Test6DetailFragment extends Fragment {
+ public static final String ARG_ITEM_ID = "item_id";
+ private final static String PAGE = "<html><body>"
+ + "This is test <b>6</b> for WebView text traversal test."
+ + "<p/><a href=\"http://google.com\">This is a link to google</a><br/>"
+ + "<h5>This is h5 text</h5>"
+ + "<a href=\"http://yahoo.com\">This is a link to yahoo</a>"
+ + "<p/><h4>This is h4 text</h4>" + "</body></html>";
+
+ public Test6DetailFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+ View rootView = inflater.inflate(R.layout.test6_detail_fragment, container, false);
+ WebView wv = (WebView) rootView.findViewById(R.id.test6WebView);
+ wv.loadData(PAGE, "text/html", null);
+ return rootView;
+ }
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestGenericDetailFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestGenericDetailFragment.java
new file mode 100644
index 0000000..ab36d04
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestGenericDetailFragment.java
@@ -0,0 +1,49 @@
+/*
+ * 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.uiautomator;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class TestGenericDetailFragment extends Fragment {
+ public static final String ARG_ITEM_ID = "item_id";
+ TestItems.TestItem mItem;
+
+ public TestGenericDetailFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments().containsKey(ARG_ITEM_ID)) {
+ mItem = TestItems.getTest(getArguments().getString(ARG_ITEM_ID));
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
+ View rootView = inflater.inflate(R.layout.test_results_detail_fragment, container, false);
+ if (mItem != null) {
+ ((TextView) rootView.findViewById(R.id.testResultsTextView)).setText(mItem.mName);
+ }
+ return rootView;
+ }
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestItems.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestItems.java
new file mode 100644
index 0000000..358516e
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestItems.java
@@ -0,0 +1,117 @@
+/*
+ * 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.uiautomator;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class TestItems {
+ private static String LOG_TAG = TestItems.class.getSimpleName();
+ private static List<TestItem> ITEMS = new ArrayList<TestItem>();
+ private static Map<String, TestItem> ITEM_MAP = new HashMap<String, TestItem>();
+
+ public static class TestItem {
+ public String mId;
+ public String mName;
+ private final Class<Fragment> mClassFragment;
+ public String mTestDescription;
+
+ @SuppressWarnings("unchecked")
+ public TestItem(String id, String name, Class<?> clsf) {
+ mId = id;
+ mName = name;
+ mClassFragment = (Class<Fragment>) clsf;
+ }
+
+ @Override
+ public String toString() {
+ return mName;
+ }
+ }
+
+ static {
+ addTestItem(new TestItem("1", "Test 1", Test1DetailFragment.class));
+ addTestItem(new TestItem("2", "Test 2", Test2DetailFragment.class));
+ addTestItem(new TestItem("3", "Test 3", Test3DetailFragment.class));
+ addTestItem(new TestItem("4", "Test 4", Test4DetailFragment.class));
+ addTestItem(new TestItem("5", "Test 5", Test5DetailFragment.class));
+ addTestItem(new TestItem("6", "Test 6", Test6DetailFragment.class));
+ addTestItem(new TestItem("7", "Test 7", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("8", "Test 8", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("9", "Test 9", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("10", "Test 10", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("11", "Test 11", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("12", "Test 12", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("13", "Test 13", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("14", "Test 14", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("15", "Test 15", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("16", "Test 16", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("17", "Test 17", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("18", "Test 18", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("19", "Test 19", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("20", "Test 20", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("21", "Test 21", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("22", "Test 22", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("23", "Test 23", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("24", "Test 24", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("25", "Test 25", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("26", "Test 26", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("27", "Test 27", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("28", "Test 28", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("29", "Test 29", TestGenericDetailFragment.class));
+ addTestItem(new TestItem("30", "Test 30", TestGenericDetailFragment.class));
+ }
+
+ private static void addTestItem(TestItem item) {
+ ITEMS.add(item);
+ ITEM_MAP.put(item.mId, item);
+ }
+
+ public static List<TestItem> getTests() {
+ return ITEMS;
+ }
+
+ public static TestItem getTest(String id) {
+ return ITEM_MAP.get(id);
+ }
+
+ public static TestItem getTest(int pos) {
+ return ITEMS.get(pos);
+ }
+
+ public static Fragment getFragment(String id) {
+ try {
+ Fragment fragment = getTest(id).mClassFragment.newInstance();
+ Bundle arguments = new Bundle();
+ arguments.putString("item_id", id);
+ fragment.setArguments(arguments);
+ return fragment;
+ } catch (InstantiationException e) {
+ Log.e(LOG_TAG, "Exception", e);
+ return null;
+ } catch (IllegalAccessException e) {
+ Log.e(LOG_TAG, "Exception", e);
+ return null;
+ }
+ }
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestListFragment.java b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestListFragment.java
new file mode 100644
index 0000000..46f0f73
--- /dev/null
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/src/com/android/cts/uiautomator/TestListFragment.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 com.android.cts.uiautomator;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+public class TestListFragment extends ListFragment {
+
+ private static final String STATE_ACTIVATED_POSITION = "activated_position";
+
+ private Callbacks mCallbacks = sDummyCallbacks;
+ private int mActivatedPosition = ListView.INVALID_POSITION;
+
+ public interface Callbacks {
+
+ public void onItemSelected(String id);
+ }
+
+ private static Callbacks sDummyCallbacks = new Callbacks() {
+ @Override
+ public void onItemSelected(String id) {
+ }
+ };
+
+ public TestListFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setListAdapter(new ArrayAdapter<TestItems.TestItem>(getActivity(),
+ R.layout.simple_list_item_selected, R.id.label, TestItems.getTests()));
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedState) {
+ super.onViewCreated(view, savedState);
+ if (savedState != null && savedState.containsKey(STATE_ACTIVATED_POSITION)) {
+ setActivatedPosition(savedState.getInt(STATE_ACTIVATED_POSITION));
+ }
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ if (!(activity instanceof Callbacks)) {
+ throw new IllegalStateException("Activity must implement fragment's callbacks.");
+ }
+
+ mCallbacks = (Callbacks) activity;
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mCallbacks = sDummyCallbacks;
+ }
+
+ @Override
+ public void onListItemClick(ListView listView, View view, int position, long id) {
+ super.onListItemClick(listView, view, position, id);
+ mCallbacks.onItemSelected(TestItems.getTest(position).mId);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ if (mActivatedPosition != ListView.INVALID_POSITION) {
+ outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
+ }
+ }
+
+ public void setActivateOnItemClick(boolean activateOnItemClick) {
+ getListView().setChoiceMode(
+ activateOnItemClick ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE);
+ }
+
+ public void setActivatedPosition(int position) {
+ if (position == ListView.INVALID_POSITION) {
+ getListView().setItemChecked(mActivatedPosition, false);
+ } else {
+ getListView().setItemChecked(position, true);
+ }
+
+ mActivatedPosition = position;
+ }
+}
diff --git a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
index 25a4ec1..ba87156 100644
--- a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
+++ b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
@@ -72,7 +72,6 @@
// PTS adds PtsAndroidTestCase
sourcePath.add("./cts/suite/pts/deviceTests/ptsutil/src");
sourcePath.add("./cts/libs/util/src");
- sourcePath.add("./frameworks/testing/uiautomator/library/src");
sourcePath.add(sourceDir.toString());
return join(sourcePath, ":");
}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
index c5b253a..ce4fdd7 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
@@ -49,8 +49,6 @@
String instrumentation = null;
String testType = null;
String jarPath = null;
- String appNameSpace = null;
- String targetNameSpace = null;
for (int i = 0; i < args.length; i++) {
if ("-p".equals(args[i])) {
@@ -70,17 +68,15 @@
"Missing value for expectation store")));
} else if ("-o".equals(args[i])) {
outputPath = getArg(args, ++i, "Missing value for output file");
- } else if ("-a".equals(args[i])) {
- appNameSpace = getArg(args, ++i, "Missing value for app name space");
- } else if ("-r".equals(args[i])) {
- targetNameSpace = getArg(args, ++i, "Missing value for target name space");
} else {
System.err.println("Unsupported flag: " + args[i]);
usage(args);
}
}
+ String appNameSpace = null;
String runner = null;
+ String targetNameSpace = null;
if (manifestFile != null) {
Document manifest = DocumentBuilderFactory.newInstance().newDocumentBuilder()
diff --git a/tools/tradefed-host/.classpath b/tools/tradefed-host/.classpath
index 09dd0ce..275ecf9 100644
--- a/tools/tradefed-host/.classpath
+++ b/tools/tradefed-host/.classpath
@@ -3,10 +3,10 @@
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="res"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/tradefederation"/>
<classpathentry exported="true" kind="var" path="CTS_SRC_ROOT/out/host/common/obj/JAVA_LIBRARIES/ctsdeviceinfolib_intermediates/javalib.jar"/>
<classpathentry exported="true" kind="var" path="CTS_SRC_ROOT/out/host/common/obj/JAVA_LIBRARIES/hosttestlib_intermediates/javalib.jar"/>
- <classpathentry kind="var" path="CTS_SRC_ROOT/prebuilt/common/ddmlib/ddmlib-prebuilt.jar" sourcepath="/SDK_SRC_ROOT"/>
- <classpathentry kind="var" path="CTS_SRC_ROOT/prebuilt/common/tradefed/tradefed-prebuilt.jar" sourcepath="/TRADEFED_ROOT/tools/tradefederation/src"/>
- <classpathentry kind="var" path="CTS_SRC_ROOT/out/host/common/obj/JAVA_LIBRARIES/junit_intermediates/javalib.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/tools/tradefed-host/.gitignore b/tools/tradefed-host/.gitignore
deleted file mode 100644
index ba077a4..0000000
--- a/tools/tradefed-host/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-bin
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/SettingsToggler.java b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/SettingsToggler.java
index 597d866..69d4c8a 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/SettingsToggler.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/SettingsToggler.java
@@ -51,7 +51,7 @@
"content update"
+ " --uri content://settings/secure"
+ " --bind value:s:" + value
- + " --where \"name=\\'" + name + "\\'\"");
+ + " --where \"name='" + name + "'\"");
}
public static void updateSecureInt(ITestDevice device, String name, int value)
@@ -60,7 +60,7 @@
"content update"
+ " --uri content://settings/secure"
+ " --bind value:i:" + value
- + " --where \"name=\\'" + name + "\\'\"");
+ + " --where \"name='" + name + "'\"");
}
private static void deleteSecure(ITestDevice device, String name)
@@ -68,6 +68,6 @@
device.executeShellCommand(
"content delete"
+ " --uri content://settings/secure"
- + " --where \"name=\\'" + name + "\\'\"");
+ + " --where \"name='" + name + "'\"");
}
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index db11bce..19ee3b7 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -400,7 +400,8 @@
// reboot it before running it.
// Also reboot after package which is know to leave pop-up behind
final List<String> rebootAfterList = Arrays.asList(
- "CtsMediaTestCases");
+ "CtsMediaTestCases",
+ "CtsAccessibilityTestCases");
final List<String> rebootBeforeList = Arrays.asList(
"CtsAnimationTestCases",
"CtsGraphicsTestCases",
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index 78a72ba..ffbb930 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -16,7 +16,6 @@
package com.android.cts.tradefed.testtype;
-import com.android.ddmlib.Log.LogLevel;
import com.android.ddmlib.testrunner.TestIdentifier;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.IRemoteTest;
@@ -49,7 +48,6 @@
"com.android.cts.tradefed.testtype.AccessibilityTestRunner";
public static final String ACCESSIBILITYSERVICE_TEST =
"com.android.cts.tradefed.testtype.AccessibilityServiceTestRunner";
- public static final String UIAUTOMATOR_TEST = "uiAutomator";
private static final String SIGNATURE_TEST_METHOD = "testSignature";
private static final String SIGNATURE_TEST_CLASS = "android.tests.sigtest.SimpleSignatureTest";
@@ -227,9 +225,6 @@
} else if (ACCESSIBILITYSERVICE_TEST.equals(mTestType)) {
AccessibilityServiceTestRunner test = new AccessibilityServiceTestRunner();
return setInstrumentationTest(test, testCaseDir);
- } else if (UIAUTOMATOR_TEST.equals(mTestType)) {
- UiAutomatorJarTest uiautomatorTest = new UiAutomatorJarTest();
- return setUiAutomatorTest(uiautomatorTest);
} else if (mIsSignatureTest) {
// TODO: hardcode the runner/class/method for now, since current package xml points to
// specialized instrumentation. Eventually this special case for signatureTest can be
@@ -290,28 +285,6 @@
}
/**
- * Populates given {@link UiAutomatorJarTest} with data from the package xml.
- *
- * @param uiautomatorTest
- * @return the populated {@link UiAutomatorJarTest} or <code>null</code>
- */
- private IRemoteTest setUiAutomatorTest(UiAutomatorJarTest uiautomatorTest) {
- uiautomatorTest.setInstallArtifacts(getJarPath());
- if (mClassName != null) {
- if (mMethodName != null) {
- CLog.logAndDisplay(LogLevel.WARN, "ui automator tests don't currently support" +
- "running individual methods");
- }
- uiautomatorTest.addClassName(mClassName);
- } else {
- uiautomatorTest.addClassNames(mTestClasses);
- }
- uiautomatorTest.setRunName(getUri());
- uiautomatorTest.setCaptureLogs(false);
- return uiautomatorTest;
- }
-
- /**
* Filter the tests to run based on list of excluded tests, class and method name.
*
* @return the filtered collection of tests
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/UiAutomatorJarTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/UiAutomatorJarTest.java
deleted file mode 100644
index 83cc6d6..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/UiAutomatorJarTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.tradefed.testtype;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.UiAutomatorTest;
-
-import java.io.FileNotFoundException;
-import java.util.Arrays;
-
-import junit.framework.Assert;
-
-/**
- * A {@link UiAutomatorTest} that will install a uiautomator jar before test
- * execution, and uninstall on execution completion.
- */
-public class UiAutomatorJarTest extends UiAutomatorTest implements IBuildReceiver {
-
- // TODO: expose this in parent
- private static final String SHELL_EXE_BASE = "/data/local/tmp/";
-
- /** the file names of the CTS jar to install */
- private String mTestJarFileName;
-
- private CtsBuildHelper mCtsBuild = null;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setBuild(IBuildInfo build) {
- mCtsBuild = CtsBuildHelper.createBuildHelper(build);
- }
-
- /**
- * Setter for CTS build files needed to perform the test.
- *
- * @param testJarName the file name of the jar containing the uiautomator tests
- */
- public void setInstallArtifacts(String testJarName) {
- mTestJarFileName = testJarName;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(final ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- Assert.assertNotNull("missing device", getDevice());
- Assert.assertNotNull("missing build", mCtsBuild);
- Assert.assertNotNull("missing jar to install", mTestJarFileName);
-
- installJar();
-
- super.run(listener);
-
- uninstallJar();
- }
-
- private void installJar() throws DeviceNotAvailableException {
- CLog.d("Installing %s on %s", mTestJarFileName, getDevice().getSerialNumber());
- String fullJarPath = String.format("%s%s", SHELL_EXE_BASE, mTestJarFileName);
- try {
- boolean result = getDevice().pushFile(mCtsBuild.getTestApp(mTestJarFileName),
- fullJarPath);
- Assert.assertTrue(String.format("Failed to push file to %s", fullJarPath), result);
- setTestJarPaths(Arrays.asList(fullJarPath));
- } catch (FileNotFoundException e) {
- Assert.fail(String.format("Could not find file %s", mTestJarFileName));
- }
- }
-
- private void uninstallJar() throws DeviceNotAvailableException {
- CLog.d("Uninstalling %s on %s", mTestJarFileName, getDevice().getSerialNumber());
- String fullJarPath = String.format("%s%s", SHELL_EXE_BASE, mTestJarFileName);
- getDevice().executeShellCommand(String.format("rm %s", fullJarPath));
- }
-}