am 259aedec: am a567a8cb: change log MSG level to error
* commit '259aedec4083a1c2d1d6335197522fab7f5dba0e':
change log MSG level to error
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 589f155..60a8cf2 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -18,6 +18,7 @@
CtsExternalStorageApp \
CtsInstrumentationAppDiffCert \
CtsPermissionDeclareApp \
+ CtsPermissionDeclareAppCompat \
CtsSharedUidInstall \
CtsSharedUidInstallDiffCert \
CtsSimpleAppInstall \
@@ -47,14 +48,11 @@
$(cts_support_packages) \
$(cts_external_packages)
-# Temporarily blacklisted packages
-# CtsWebkitSecurityTestCases \
-
# Test packages that require an associated test package XML.
cts_test_packages := \
CtsAccelerationTestCases \
- CtsAccessibilityServiceTestCases \
CtsAccountManagerTestCases \
+ CtsAccessibilityServiceTestCases \
CtsAccessibilityTestCases \
CtsAdminTestCases \
CtsAnimationTestCases \
@@ -97,6 +95,7 @@
CtsUtilTestCases \
CtsViewTestCases \
CtsWebkitTestCases \
+ CtsWebkitSecurityTestCases \
CtsWidgetTestCases
# All APKs that need to be scanned by the coverage utilities.
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 0898369..a8cb020 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.verifier"
android:versionCode="1"
- android:versionName="4.1_r2">
+ android:versionName="1337">
<!-- Using 10 for more complete NFC support... -->
<uses-sdk android:minSdkVersion="10"></uses-sdk>
@@ -306,6 +306,7 @@
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
+ <category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_camera" />
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 fd226a6..e3f58c3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationVerifier.java
@@ -58,6 +58,14 @@
long delta = timestamp - mLastActiveTimestamp;
mLastActiveTimestamp = timestamp;
+ if (location.getAccuracy() <= 0.0) {
+ fail(mProvider + " location has invalid accuracy: " + location.getAccuracy());
+ }
+ if (location.getElapsedRealtimeNano() <= 0) {
+ fail(mProvider + " location has invalid elapsed realtime: " +
+ location.getElapsedRealtimeNano());
+ }
+
if (mNumActiveUpdates != 1 && delta < mMinActiveInterval) {
fail(mProvider + " location updated too fast: " + delta + "ms < " +
mMinActiveInterval + "ms");
@@ -100,6 +108,14 @@
long delta = timestamp - mLastPassiveTimestamp;
mLastPassiveTimestamp = timestamp;
+ if (location.getAccuracy() <= 0.0) {
+ fail(mProvider + " location has invalid accuracy: " + location.getAccuracy());
+ }
+ if (location.getElapsedRealtimeNano() <= 0) {
+ fail(mProvider + " location has invalid elapsed realtime: " +
+ location.getElapsedRealtimeNano());
+ }
+
if (mNumPassiveUpdates != 1 && delta < mMinPassiveInterval) {
fail("passive " + mProvider + " location updated too fast: " + delta + "ms < " +
mMinPassiveInterval + "ms");
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/tech/MifareUltralightTagTester.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/tech/MifareUltralightTagTester.java
index 23f4762..038d276 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/tech/MifareUltralightTagTester.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/tech/MifareUltralightTagTester.java
@@ -29,7 +29,7 @@
*/
public class MifareUltralightTagTester implements TagTester {
- private static final int USER_PAGE_OFFSET = 4;
+ private static final int USER_PAGE_OFFSET = 5;
private static final int NUM_PAGES = 4;
@@ -77,4 +77,4 @@
}
};
}
-}
\ No newline at end of file
+}
diff --git a/build/test_package.mk b/build/test_package.mk
index e8d812b..071acee 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -19,6 +19,9 @@
# Replace "include $(BUILD_PACKAGE)" with "include $(BUILD_CTS_PACKAGE)"
#
+# Disable by default so "m cts" will work in emulator builds
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
cts_package_apk := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).apk
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
index 23d353e..5c28a4f 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
@@ -17,6 +17,7 @@
package com.android.cts.appsecurity;
import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
import com.android.ddmlib.testrunner.TestIdentifier;
@@ -84,6 +85,9 @@
// testPermissionDiffCert constants
private static final String DECLARE_PERMISSION_APK = "CtsPermissionDeclareApp.apk";
private static final String DECLARE_PERMISSION_PKG = "com.android.cts.permissiondeclareapp";
+ private static final String DECLARE_PERMISSION_COMPAT_APK = "CtsPermissionDeclareAppCompat.apk";
+ private static final String DECLARE_PERMISSION_COMPAT_PKG = "com.android.cts.permissiondeclareappcompat";
+
private static final String PERMISSION_DIFF_CERT_APK = "CtsUsePermissionDiffCert.apk";
private static final String PERMISSION_DIFF_CERT_PKG =
"com.android.cts.usespermissiondiffcertapp";
@@ -206,7 +210,8 @@
getDevice().uninstallPackage(WRITE_EXTERNAL_STORAGE_APP_PKG);
// stage test file on external storage
- getDevice().pushString("CAEK", "/sdcard/meow");
+ getDevice().pushString("CAEK",
+ getDevice().getMountPoint(IDevice.MNT_EXTERNAL_STORAGE) + "/meow");
// mark permission as not enforced
setPermissionEnforced(getDevice(), READ_EXTERNAL_STORAGE, false);
@@ -311,6 +316,7 @@
try {
// cleanup test app that might be installed from previous partial test run
getDevice().uninstallPackage(DECLARE_PERMISSION_PKG);
+ getDevice().uninstallPackage(DECLARE_PERMISSION_COMPAT_PKG);
getDevice().uninstallPackage(PERMISSION_DIFF_CERT_PKG);
String installResult = getDevice().installPackage(
@@ -318,6 +324,11 @@
assertNull(String.format("failed to install declare permission app. Reason: %s",
installResult), installResult);
+ installResult = getDevice().installPackage(
+ getTestAppFile(DECLARE_PERMISSION_COMPAT_APK), false);
+ assertNull(String.format("failed to install declare permission compat app. Reason: %s",
+ installResult), installResult);
+
// the app will install, but will get error at runtime
installResult = getDevice().installPackage(getTestAppFile(PERMISSION_DIFF_CERT_APK),
false);
@@ -329,6 +340,7 @@
}
finally {
getDevice().uninstallPackage(DECLARE_PERMISSION_PKG);
+ getDevice().uninstallPackage(DECLARE_PERMISSION_COMPAT_PKG);
getDevice().uninstallPackage(PERMISSION_DIFF_CERT_PKG);
}
}
diff --git a/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk b/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
index 6c31fd9..308992e 100644
--- a/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
@@ -27,4 +27,6 @@
# although not strictly necessary, sign this app with different cert than CtsAppWithData
LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk b/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
index ae14b7c..8bcb045 100644
--- a/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
@@ -26,4 +26,6 @@
LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
index 3c687f1..91d6ccf 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
@@ -22,4 +22,6 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsExternalStorageApp
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
index 67b2246..268ac73 100644
--- a/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
@@ -27,4 +27,6 @@
# sign this app with different cert than CtsTargetInstrumentationApp
LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
index 41ddb64..938b325 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
@@ -27,4 +27,6 @@
# sign this app with a different cert than CtsUsePermissionDiffCert
LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/AndroidManifest.xml
index 00c996c..ad7a640 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/AndroidManifest.xml
@@ -41,7 +41,8 @@
<provider android:name="PermissionContentProvider"
android:authorities="ctspermissionwithsignature"
android:readPermission="com.android.cts.permissionWithSignature"
- android:writePermission="com.android.cts.permissionWithSignature">
+ android:writePermission="com.android.cts.permissionWithSignature"
+ android:exported="true">
</provider>
<!-- Need a way for another app to try to access the permission, but will
@@ -49,7 +50,8 @@
<provider android:name="PermissionContentProviderGranting"
android:authorities="ctspermissionwithsignaturegranting"
android:readPermission="com.android.cts.permissionWithSignature"
- android:writePermission="com.android.cts.permissionWithSignature">
+ android:writePermission="com.android.cts.permissionWithSignature"
+ android:exported="true">
<grant-uri-permission android:pathPattern="/foo.*" />
<grant-uri-permission android:pathPattern="/yes.*" />
</provider>
@@ -68,12 +70,19 @@
<grant-uri-permission android:pathPattern="/yes.*" />
</provider>
+ <!-- An ambiguous content provider, where "exported" was not specified.
+ Nobody should get access to this. -->
+ <provider android:name="AmbiguousContentProvider"
+ android:authorities="ctsambiguousprovider">
+ </provider>
+
<!-- Target for tests about how path permissions interact with granting
URI permissions. -->
<provider android:name="PermissionContentProviderPath"
android:authorities="ctspermissionwithsignaturepath"
android:readPermission="com.android.cts.permissionNotUsedWithSignature"
- android:writePermission="com.android.cts.permissionNotUsedWithSignature">
+ android:writePermission="com.android.cts.permissionNotUsedWithSignature"
+ android:exported="true">
<path-permission
android:pathPrefix="/foo"
android:readPermission="com.android.cts.permissionWithSignature"
@@ -88,7 +97,8 @@
<!-- Target for tests that verify path permissions can restrict access
when no default top-level permission. -->
<provider android:name="PermissionContentProviderPathRestricting"
- android:authorities="ctspermissionwithsignaturepathrestricting">
+ android:authorities="ctspermissionwithsignaturepathrestricting"
+ android:exported="true">
<!-- Require signature permission to get into path. -->
<path-permission
android:pathPrefix="/foo"
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/AmbiguousContentProvider.java b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/AmbiguousContentProvider.java
new file mode 100644
index 0000000..3536979
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/AmbiguousContentProvider.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.permissiondeclareapp;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+/**
+ * Empty content provider, manifest did not declare exported=true nor exported=false.
+ */
+public class AmbiguousContentProvider extends ContentProvider {
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ // do nothing
+ return 0;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return "got/theMIME";
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public boolean onCreate() {
+ return false;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection,
+ String[] selectionArgs) {
+ return 0;
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk
new file mode 100644
index 0000000..acdc20f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 16
+
+LOCAL_PACKAGE_NAME := CtsPermissionDeclareAppCompat
+
+# sign this app with a different cert than CtsUsePermissionDiffCert
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/AndroidManifest.xml
new file mode 100644
index 0000000..5bbf93f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.permissiondeclareappcompat">
+
+ <application>
+ <!--
+ This provider doesn't specify an android:exported line. Because we specify
+ LOCAL_SDK_VERSION:=16 in Android.mk, we preserve the old behavior of defaulting
+ android:exported="true".
+ -->
+ <provider android:name="AmbiguousContentProvider"
+ android:authorities="ctsambiguousprovidercompat">
+ </provider>
+
+ </application>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/src/com/android/cts/permissiondeclareappcompat/AmbiguousContentProvider.java b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/src/com/android/cts/permissiondeclareappcompat/AmbiguousContentProvider.java
new file mode 100644
index 0000000..8665b70
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/src/com/android/cts/permissiondeclareappcompat/AmbiguousContentProvider.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.permissiondeclareappcompat;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+
+/**
+ * Empty content provider, all permissions are enforced in manifest
+ */
+public class AmbiguousContentProvider extends ContentProvider {
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ // do nothing
+ return 0;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return "got/theUnspecifiedMIME";
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public boolean onCreate() {
+ return false;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection,
+ String[] selectionArgs) {
+ return 0;
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk b/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
index f852c56..25ba1fe 100644
--- a/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
@@ -29,4 +29,6 @@
LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
index 3f0a6b6..a00b009 100644
--- a/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
@@ -27,4 +27,6 @@
# sign this app with a different cert than CtsSharedUidInstall
LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk b/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
index f7e0f27..3cd78cf 100644
--- a/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
@@ -27,4 +27,6 @@
# sign this app with a different cert than CtsSimpleAppInstallDiffCert
LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
index 06290be..5fbc910 100644
--- a/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
@@ -27,4 +27,6 @@
# sign this app with a different cert than CtsSimpleAppInstall
LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk b/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
index 532403c..cc87e29 100644
--- a/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
@@ -27,4 +27,6 @@
# sign this app with different cert than CtsInstrumentationAppDiffCert
LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
index 44ff270..acf9f6f 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
@@ -27,4 +27,6 @@
# sign this app with a different cert than CtsPermissionDeclareApp
LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
index 41cddf5..a6495a9 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
@@ -35,20 +35,23 @@
* Accesses app cts/tests/appsecurity-tests/test-apps/PermissionDeclareApp/...
*/
public class AccessPermissionWithDiffSigTest extends AndroidTestCase {
- static final ComponentName GRANT_URI_PERM_COMP
+ private static final ComponentName GRANT_URI_PERM_COMP
= new ComponentName("com.android.cts.permissiondeclareapp",
"com.android.cts.permissiondeclareapp.GrantUriPermission");
- static final Uri PERM_URI = Uri.parse("content://ctspermissionwithsignature");
- static final Uri PERM_URI_GRANTING = Uri.parse("content://ctspermissionwithsignaturegranting");
- static final Uri PERM_URI_PATH = Uri.parse("content://ctspermissionwithsignaturepath");
- static final Uri PERM_URI_PATH_RESTRICTING = Uri.parse(
+ private static final Uri PERM_URI = Uri.parse("content://ctspermissionwithsignature");
+ private static final Uri PERM_URI_GRANTING = Uri.parse("content://ctspermissionwithsignaturegranting");
+ private static final Uri PERM_URI_PATH = Uri.parse("content://ctspermissionwithsignaturepath");
+ private static final Uri PERM_URI_PATH_RESTRICTING = Uri.parse(
"content://ctspermissionwithsignaturepathrestricting");
- static final Uri PRIV_URI = Uri.parse("content://ctsprivateprovider");
- static final Uri PRIV_URI_GRANTING = Uri.parse("content://ctsprivateprovidergranting");
+ private static final Uri PRIV_URI = Uri.parse("content://ctsprivateprovider");
+ private static final Uri PRIV_URI_GRANTING = Uri.parse("content://ctsprivateprovidergranting");
+ private static final String EXPECTED_MIME_TYPE = "got/theMIME";
- static final String EXPECTED_MIME_TYPE = "got/theMIME";
-
- public void assertReadingContentUriNotAllowed(Uri uri, String msg) {
+ private static final Uri AMBIGUOUS_URI_COMPAT = Uri.parse("content://ctsambiguousprovidercompat");
+ private static final String EXPECTED_MIME_TYPE_AMBIGUOUS = "got/theUnspecifiedMIME";
+ private static final Uri AMBIGUOUS_URI = Uri.parse("content://ctsambiguousprovider");
+
+ private void assertReadingContentUriNotAllowed(Uri uri, String msg) {
try {
getContext().getContentResolver().query(uri, null, null, null, null);
fail("expected SecurityException reading " + uri + ": " + msg);
@@ -57,15 +60,15 @@
}
}
- public void assertReadingContentUriAllowed(Uri uri) {
+ private void assertReadingContentUriAllowed(Uri uri) {
try {
getContext().getContentResolver().query(uri, null, null, null, null);
} catch (SecurityException e) {
- fail("unexpected SecurityException reading " + uri);
+ fail("unexpected SecurityException reading " + uri + ": " + e.getMessage());
}
}
- public void assertReadingClipNotAllowed(ClipData clip, String msg) {
+ private void assertReadingClipNotAllowed(ClipData clip, String msg) {
for (int i=0; i<clip.getItemCount(); i++) {
ClipData.Item item = clip.getItemAt(i);
Uri uri = item.getUri();
@@ -85,7 +88,7 @@
}
}
- public void assertWritingContentUriNotAllowed(Uri uri, String msg) {
+ private void assertWritingContentUriNotAllowed(Uri uri, String msg) {
try {
getContext().getContentResolver().insert(uri, new ContentValues());
fail("expected SecurityException writing " + uri + ": " + msg);
@@ -94,15 +97,15 @@
}
}
- public void assertWritingContentUriAllowed(Uri uri) {
+ private void assertWritingContentUriAllowed(Uri uri) {
try {
getContext().getContentResolver().insert(uri, new ContentValues());
} catch (SecurityException e) {
- fail("unexpected SecurityException writing " + uri);
+ fail("unexpected SecurityException writing " + uri + ": " + e.getMessage());
}
}
- public void assertWritingClipNotAllowed(ClipData clip, String msg) {
+ private void assertWritingClipNotAllowed(ClipData clip, String msg) {
for (int i=0; i<clip.getItemCount(); i++) {
ClipData.Item item = clip.getItemAt(i);
Uri uri = item.getUri();
@@ -145,8 +148,35 @@
* since it is not exported from its app.
*/
public void testReadProviderWhenPrivate() {
- assertReadingContentUriNotAllowed(PRIV_URI,
- "shouldn't read private provider");
+ assertReadingContentUriNotAllowed(PRIV_URI, "shouldn't read private provider");
+ }
+
+ /**
+ * Test that the ctsambiguousprovider content provider cannot be read,
+ * since it doesn't have an "exported=" line.
+ */
+ public void testReadProviderWhenAmbiguous() {
+ assertReadingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't read ambiguous provider");
+ }
+
+ /**
+ * Old App Compatibility Test
+ *
+ * Test that the ctsambiguousprovidercompat content provider can be read for older
+ * API versions, because it didn't specify either exported=true or exported=false.
+ */
+ public void testReadProviderWhenAmbiguousCompat() {
+ assertReadingContentUriAllowed(AMBIGUOUS_URI_COMPAT);
+ }
+
+ /**
+ * Old App Compatibility Test
+ *
+ * Test that the ctsambiguousprovidercompat content provider can be written for older
+ * API versions, because it didn't specify either exported=true or exported=false.
+ */
+ public void testWriteProviderWhenAmbiguousCompat() {
+ assertWritingContentUriAllowed(AMBIGUOUS_URI_COMPAT);
}
/**
@@ -154,16 +184,23 @@
* since it is not exported from its app.
*/
public void testWriteProviderWhenPrivate() {
- assertWritingContentUriNotAllowed(PRIV_URI,
- "shouldn't write private provider");
+ assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write private provider");
}
- public static ClipData makeSingleClipData(Uri uri) {
+ /**
+ * Test that the ctsambiguousprovider content provider cannot be written,
+ * since it doesn't have an exported= line.
+ */
+ public void testWriteProviderWhenAmbiguous() {
+ assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write ambiguous provider");
+ }
+
+ private static ClipData makeSingleClipData(Uri uri) {
return new ClipData("foo", new String[] { "foo/bar" },
new ClipData.Item(uri));
}
- public static ClipData makeMultiClipData(Uri uri) {
+ private static ClipData makeMultiClipData(Uri uri) {
Uri grantClip1Uri = Uri.withAppendedPath(uri, "clip1");
Uri grantClip2Uri = Uri.withAppendedPath(uri, "clip2");
Uri grantClip3Uri = Uri.withAppendedPath(uri, "clip3");
@@ -187,18 +224,18 @@
return clip;
}
- public static Intent makeClipIntent(ClipData clip, int flags) {
+ private static Intent makeClipIntent(ClipData clip, int flags) {
Intent intent = new Intent();
intent.setClipData(clip);
intent.addFlags(flags);
return intent;
}
- public static Intent makeClipIntent(Uri uri, int flags) {
+ private static Intent makeClipIntent(Uri uri, int flags) {
return makeClipIntent(makeMultiClipData(uri), flags);
}
- public void doTryGrantUriActivityPermissionToSelf(Uri uri, int mode) {
+ private void doTryGrantUriActivityPermissionToSelf(Uri uri, int mode) {
Uri grantDataUri = Uri.withAppendedPath(uri, "data");
Intent grantIntent = new Intent();
grantIntent.setData(grantDataUri);
@@ -261,7 +298,7 @@
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
- public void doTryGrantUriServicePermissionToSelf(Uri uri, int mode) {
+ private void doTryGrantUriServicePermissionToSelf(Uri uri, int mode) {
Uri grantDataUri = Uri.withAppendedPath(uri, "data");
Intent grantIntent = new Intent();
grantIntent.setData(grantDataUri);
@@ -320,7 +357,7 @@
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
- static class GrantResultReceiver extends BroadcastReceiver {
+ private static class GrantResultReceiver extends BroadcastReceiver {
boolean mHaveResult = false;
boolean mGoodResult = false;
boolean mSucceeded = false;
@@ -389,7 +426,7 @@
}
}
- void grantUriPermissionFail(Uri uri, int mode, boolean service) {
+ private void grantUriPermissionFail(Uri uri, int mode, boolean service) {
Uri grantDataUri = Uri.withAppendedPath(uri, "data");
Intent grantIntent = new Intent();
grantIntent.setData(grantDataUri);
@@ -417,7 +454,7 @@
+ " when should not");
}
- void doTestGrantUriPermissionFail(Uri uri) {
+ private void doTestGrantUriPermissionFail(Uri uri) {
grantUriPermissionFail(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, false);
grantUriPermissionFail(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
grantUriPermissionFail(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, true);
@@ -450,6 +487,14 @@
}
/**
+ * Test that the ctsambiguousprovider content provider can not grant
+ * URI permissions to others.
+ */
+ public void testGrantAmbiguousNonGrantingFail() {
+ doTestGrantUriPermissionFail(AMBIGUOUS_URI);
+ }
+
+ /**
* Test that the ctsprivateprovidergranting content provider can not grant
* URI permissions to paths outside of the grant tree
*/
@@ -458,7 +503,7 @@
doTestGrantUriPermissionFail(Uri.withAppendedPath(PRIV_URI_GRANTING, "invalid"));
}
- void grantClipUriPermission(ClipData clip, int mode, boolean service) {
+ private void grantClipUriPermission(ClipData clip, int mode, boolean service) {
Intent grantIntent = new Intent();
if (clip.getItemCount() == 1) {
grantIntent.setData(clip.getItemAt(0).getUri());
@@ -482,7 +527,7 @@
getContext().sendBroadcast(intent);
}
- void assertReadingClipAllowed(ClipData clip) {
+ private void assertReadingClipAllowed(ClipData clip) {
for (int i=0; i<clip.getItemCount(); i++) {
ClipData.Item item = clip.getItemAt(i);
Uri uri = item.getUri();
@@ -510,7 +555,7 @@
}
}
- void doTestGrantActivityUriReadPermission(Uri uri, boolean useClip) {
+ private void doTestGrantActivityUriReadPermission(Uri uri, boolean useClip) {
final Uri subUri = Uri.withAppendedPath(uri, "foo");
final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
@@ -598,7 +643,7 @@
assertReadingClipNotAllowed(sub2Clip, "shouldn't read after losing granted URI");
}
- void assertWritingClipAllowed(ClipData clip) {
+ private void assertWritingClipAllowed(ClipData clip) {
for (int i=0; i<clip.getItemCount(); i++) {
ClipData.Item item = clip.getItemAt(i);
Uri uri = item.getUri();
@@ -618,7 +663,7 @@
}
}
- void doTestGrantActivityUriWritePermission(Uri uri, boolean useClip) {
+ private void doTestGrantActivityUriWritePermission(Uri uri, boolean useClip) {
final Uri subUri = Uri.withAppendedPath(uri, "foo");
final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
@@ -833,7 +878,7 @@
assertReadingClipNotAllowed(sub2Clip, "shouldn't read after losing granted URI");
}
- void doTestGrantServiceUriWritePermission(Uri uri, boolean useClip) {
+ private void doTestGrantServiceUriWritePermission(Uri uri, boolean useClip) {
final Uri subUri = Uri.withAppendedPath(uri, "foo");
final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
@@ -1069,7 +1114,7 @@
public void testGetMimeTypePermission() {
// Precondition: no current access.
- assertWritingContentUriNotAllowed(PERM_URI, "shouldn't write when starting test");
+ assertReadingContentUriNotAllowed(PERM_URI, "shouldn't read when starting test");
assertWritingContentUriNotAllowed(PERM_URI, "shouldn't write when starting test");
// All apps should be able to get MIME type regardless of permission.
@@ -1078,10 +1123,32 @@
public void testGetMimeTypePrivate() {
// Precondition: no current access.
- assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write when starting test");
+ assertReadingContentUriNotAllowed(PRIV_URI, "shouldn't read when starting test");
assertWritingContentUriNotAllowed(PRIV_URI, "shouldn't write when starting test");
// All apps should be able to get MIME type even if provider is private.
assertEquals(getContext().getContentResolver().getType(PRIV_URI), EXPECTED_MIME_TYPE);
}
+
+ public void testGetMimeTypeAmbiguous() {
+ // Precondition: no current access.
+ assertReadingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't read when starting test");
+ assertWritingContentUriNotAllowed(AMBIGUOUS_URI, "shouldn't write when starting test");
+
+ // All apps should be able to get MIME type even if provider is private.
+ assertEquals(getContext().getContentResolver().getType(AMBIGUOUS_URI), EXPECTED_MIME_TYPE);
+ }
+
+ /**
+ * Old App Compatibility Test
+ *
+ * We should be able to access the mime type of a content provider of an older
+ * application, even if that application didn't explicitly declare either
+ * exported=true or exported=false
+ */
+ public void testGetMimeTypeAmbiguousCompat() {
+ // All apps should be able to get MIME type even if provider is private.
+ assertEquals(EXPECTED_MIME_TYPE_AMBIGUOUS,
+ getContext().getContentResolver().getType(AMBIGUOUS_URI_COMPAT));
+ }
}
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
index bdb2887..9e056a9 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
@@ -22,4 +22,6 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := CtsWriteExternalStorageApp
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk b/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
index 9365af3..f6543fb 100644
--- a/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
+++ b/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
@@ -26,4 +26,8 @@
LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk b/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
index 0d76f2d..29bf9d6 100644
--- a/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
+++ b/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
@@ -26,4 +26,8 @@
LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/suite/pts/Android.mk b/suite/pts/Android.mk
new file mode 100644
index 0000000..07b30e3
--- /dev/null
+++ b/suite/pts/Android.mk
@@ -0,0 +1,18 @@
+#
+# 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 cts/suite/pts/PtsBuild.mk
+include $(call all-subdir-makefiles)
diff --git a/suite/pts/PtsBuild.mk b/suite/pts/PtsBuild.mk
new file mode 100644
index 0000000..cb79956
--- /dev/null
+++ b/suite/pts/PtsBuild.mk
@@ -0,0 +1,128 @@
+#
+# 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.
+#
+
+# several makefiles for CTS merged for PTS
+
+LOCAL_PATH:= $(call my-dir)
+
+# New packages should be added here
+PTS_TEST_PACKAGES = \
+ PtsDeviceFilePerf \
+ PtsDeviceUi
+
+PTS_SUPPORT_PACKAGES := \
+ TestDeviceSetup
+
+BUILD_PTS_PACKAGE := cts/suite/pts/build/test_package.mk
+
+PTS_JAVA_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-java-scanner
+PTS_JAVA_TEST_SCANNER_DOCLET := $(HOST_OUT_JAVA_LIBRARIES)/cts-java-scanner-doclet.jar
+
+# Generator of test XMLs from scanner output.
+PTS_XML_GENERATOR := $(HOST_OUT_EXECUTABLES)/cts-xml-generator
+
+# File indicating which tests should be blacklisted due to problems.
+PTS_EXPECTATIONS := cts/suite/pts/expectations/knownfailures.txt
+
+PTS_TESTCASES_OUT := $(HOST_OUT)/pts-testcases
+
+define pts-get-package-paths
+ $(foreach pkg,$(1),$(PTS_TESTCASES_OUT)/$(pkg).apk)
+endef
+
+define pts-get-test-xmls
+ $(foreach name,$(1),$(PTS_TESTCASES_OUT)/$(name).xml)
+endef
+
+PTS_TEST_CASE_LIST := \
+ $(PTS_SUPPORT_PACKAGES)
+
+PTS_TEST_CASES := \
+ $(call pts-get-package-paths,$(PTS_TEST_PACKAGES))
+
+PTS_TEST_XMLS := $(call pts-get-test-xmls,$(PTS_TEST_PACKAGES))
+
+pts_dir := $(HOST_OUT)/pts
+pts_tools_src_dir := cts/tools
+
+pts_name := android-pts
+
+DDMLIB_JAR := $(HOST_OUT_JAVA_LIBRARIES)/ddmlib-prebuilt.jar
+junit_host_jar := $(HOST_OUT_JAVA_LIBRARIES)/junit.jar
+HOSTTESTLIB_JAR := $(HOST_OUT_JAVA_LIBRARIES)/hosttestlib.jar
+TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+PTS_TF_JAR := $(HOST_OUT_JAVA_LIBRARIES)/cts-tradefed.jar
+PTS_TF_EXEC := $(HOST_OUT_EXECUTABLES)/pts-tradefed
+PTS_TF_README := $(pts_tools_src_dir)/tradefed-host/README
+
+
+DEFAULT_TEST_PLAN := $(pts_dir)/$(pts_name)/resource/plans/PTS.xml
+
+$(pts_dir)/all_pts_files_stamp: PRIVATE_JUNIT_HOST_JAR := $(junit_host_jar)
+
+$(pts_dir)/all_pts_files_stamp: $(PTS_TEST_CASES) $(PTS_TEST_CASE_LIST) $(junit_host_jar) $(HOSTTESTLIB_JAR) $(PTS_HOST_LIBRARY_JARS) $(TF_JAR) $(VMTESTSTF_JAR) $(PTS_TF_JAR) $(PTS_TF_EXEC) $(PTS_TF_README) $(ACP)
+# Make necessary directory for PTS
+ $(hide) rm -rf $(PRIVATE_PTS_DIR)
+ $(hide) mkdir -p $(TMP_DIR)
+ $(hide) mkdir -p $(PRIVATE_DIR)/docs
+ $(hide) mkdir -p $(PRIVATE_DIR)/tools
+ $(hide) mkdir -p $(PRIVATE_DIR)/repository/testcases
+ $(hide) mkdir -p $(PRIVATE_DIR)/repository/plans
+# Copy executable and JARs to PTS directory
+ $(hide) $(ACP) -fp $(DDMLIB_JAR) $(PRIVATE_JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(PTS_HOST_LIBRARY_JARS) $(TF_JAR) $(PTS_TF_JAR) $(PTS_TF_EXEC) $(PTS_TF_README) $(PRIVATE_DIR)/tools
+# Change mode of the executables
+ $(foreach apk,$(PTS_TEST_CASE_LIST),$(call copy-testcase-apk,$(apk)))
+ $(foreach testcase,$(PTS_TEST_CASES),$(call copy-testcase,$(testcase)))
+ $(hide) touch $@
+
+# Generate the default test plan for User.
+# Usage: buildCts.py <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath>
+
+$(DEFAULT_TEST_PLAN): $(pts_dir)/all_pts_files_stamp $(pts_tools_src_dir)/utils/buildCts.py $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar $(PTS_TEST_XMLS) | $(ACP)
+ $(hide) $(ACP) -fp $(PTS_TEST_XMLS) $(PRIVATE_DIR)/repository/testcases
+ $(hide) $(pts_tools_src_dir)/utils/buildCts.py cts/suite/pts $(PRIVATE_DIR) $(TMP_DIR) \
+ $(TOP) $(HOST_OUT_JAVA_LIBRARIES)/descGen.jar -pts
+
+# Package PTS and clean up.
+INTERNAL_PTS_TARGET := $(pts_dir)/$(pts_name).zip
+$(INTERNAL_PTS_TARGET): PRIVATE_NAME := $(pts_name)
+$(INTERNAL_PTS_TARGET): PRIVATE_PTS_DIR := $(pts_dir)
+$(INTERNAL_PTS_TARGET): PRIVATE_DIR := $(pts_dir)/$(pts_name)
+$(INTERNAL_PTS_TARGET): TMP_DIR := $(pts_dir)/temp
+$(INTERNAL_PTS_TARGET): $(pts_dir)/all_pts_files_stamp $(DEFAULT_TEST_PLAN)
+ $(hide) echo "Package PTS: $@"
+ $(hide) cd $(dir $@) && zip -rq $(notdir $@) $(PRIVATE_NAME)
+
+.PHONY: pts
+pts: $(INTERNAL_PTS_TARGET)
+cts: pts
+# generate PTS during CTS build
+ifneq ($(filter cts, $(MAKECMDGOALS)),)
+$(call dist-for-goals,cts,$(INTERNAL_PTS_TARGET))
+endif
+
+define copy-testcase-apk
+
+$(hide) $(ACP) -fp $(call intermediates-dir-for,APPS,$(1))/package.apk \
+ $(PRIVATE_DIR)/repository/testcases/$(1).apk
+
+endef
+
+define copy-testcase
+
+$(hide) $(ACP) -fp $(1) $(PRIVATE_DIR)/repository/testcases/$(notdir $1)
+
+endef
diff --git a/suite/pts/build/test_package.mk b/suite/pts/build/test_package.mk
new file mode 100644
index 0000000..f677c3b
--- /dev/null
+++ b/suite/pts/build/test_package.mk
@@ -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.
+
+# copied from cts/build. modified for PTS
+
+# Disable by default so "m pts" will work in emulator builds
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
+
+pts_package_apk := $(PTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).apk
+pts_package_xml := $(PTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).xml
+
+$(pts_package_apk): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
+$(pts_package_apk): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk | $(ACP)
+ $(hide) mkdir -p $(PTS_TESTCASES_OUT)
+ $(hide) $(ACP) -fp $< $@
+
+$(pts_package_xml): PRIVATE_PATH := $(LOCAL_PATH)
+$(pts_package_xml): PRIVATE_INSTRUMENTATION := $(LOCAL_INSTRUMENTATION_FOR)
+$(pts_package_xml): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
+$(pts_package_xml): PRIVATE_TEST_PACKAGE := com.android.pts.$(notdir $(LOCAL_PATH))
+$(pts_package_xml): PRIVATE_MANIFEST := $(LOCAL_PATH)/AndroidManifest.xml
+$(pts_package_xml): PRIVATE_TEST_TYPE := $(if $(LOCAL_PTS_TEST_RUNNER),$(LOCAL_PTS_TEST_RUNNER),'')
+$(pts_package_xml): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk $(PTS_EXPECTATIONS) $(PTS_JAVA_TEST_SCANNER_DOCLET) $(PTS_JAVA_TEST_SCANNER) $(PTS_XML_GENERATOR)
+ $(hide) echo Generating test description for java package $(PRIVATE_PACKAGE)
+ $(hide) mkdir -p $(PTS_TESTCASES_OUT)
+ $(hide) $(PTS_JAVA_TEST_SCANNER) \
+ -s $(PRIVATE_PATH) \
+ -d $(PTS_JAVA_TEST_SCANNER_DOCLET) | \
+ $(PTS_XML_GENERATOR) \
+ -t $(PRIVATE_TEST_TYPE) \
+ -m $(PRIVATE_MANIFEST) \
+ -i "$(PRIVATE_INSTRUMENTATION)" \
+ -n $(PRIVATE_PACKAGE) \
+ -p $(PRIVATE_TEST_PACKAGE) \
+ -e $(PTS_EXPECTATIONS) \
+ -o $@
diff --git a/suite/pts/deviceTests/Android.mk b/suite/pts/deviceTests/Android.mk
new file mode 100644
index 0000000..c141484
--- /dev/null
+++ b/suite/pts/deviceTests/Android.mk
@@ -0,0 +1,17 @@
+#
+# 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 $(call all-subdir-makefiles)
diff --git a/suite/pts/deviceTests/filesystemperf/Android.mk b/suite/pts/deviceTests/filesystemperf/Android.mk
new file mode 100644
index 0000000..3709ecc
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ptsutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PtsDeviceFilePerf
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_PTS_PACKAGE)
+
diff --git a/suite/pts/deviceTests/filesystemperf/AndroidManifest.xml b/suite/pts/deviceTests/filesystemperf/AndroidManifest.xml
new file mode 100644
index 0000000..0492900
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.pts.filesystemperf">
+
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.pts.filesystemperf"
+ android:label="UI Latency measurement" />
+</manifest>
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
new file mode 100644
index 0000000..3b51630
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FileUtil.java
@@ -0,0 +1,222 @@
+/*
+ * 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.pts.filesystemperf;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Random;
+
+import com.android.pts.util.MeasureRun;
+
+import android.content.Context;
+import android.util.Log;
+
+public class FileUtil {
+ private static final String TAG = "FileUtil";
+ private static final Random mRandom = new Random(0);
+ private static long mFileId = 0;
+ /**
+ * create array with different data per each call
+ *
+ * @param length
+ * @param randomSeed
+ * @return
+ */
+ public static byte[] generateRandomData(int length) {
+ byte[] buffer = new byte[length];
+ int val = mRandom.nextInt();
+ for (int i = 0; i < length / 4; i++) {
+ // in little-endian
+ buffer[i * 4] = (byte)(val & 0x000000ff);
+ buffer[i * 4 + 1] = (byte)((val & 0x0000ff00) >> 8);
+ buffer[i * 4 + 2] = (byte)((val & 0x00ff0000) >> 16);
+ buffer[i * 4 + 3] = (byte)((val & 0xff000000) >> 24);
+ val++;
+ }
+ for (int i = (length / 4) * 4; i < length; i++) {
+ buffer[i] = 0;
+ }
+ return buffer;
+ }
+
+ /**
+ * create a new file under the given dirName.
+ * Existing files will not be affected.
+ * @param context
+ * @param dirName
+ * @return
+ */
+ public static File createNewFile(Context context, String dirName) {
+ File topDir = new File(context.getFilesDir(), dirName);
+ topDir.mkdir();
+ String[] list = topDir.list();
+
+ String newFileName;
+ while (true) {
+ newFileName = Long.toString(mFileId);
+ boolean fileExist = false;
+ for (String child : list) {
+ if (child.equals(newFileName)) {
+ fileExist = true;
+ break;
+ }
+ }
+ if (!fileExist) {
+ break;
+ }
+ mFileId++;
+ }
+ mFileId++;
+ //Log.i(TAG, "filename" + Long.toString(mFileId));
+ return new File(topDir, newFileName);
+ }
+
+ /**
+ * create multiple new files
+ * @param context
+ * @param dirName
+ * @param count number of files to create
+ * @return
+ */
+ public static File[] createNewFiles(Context context, String dirName, int count) {
+ File[] files = new File[count];
+ for (int i = 0; i < count; i++) {
+ files[i] = createNewFile(context, dirName);
+ }
+ return files;
+ }
+
+ /**
+ * write file with given byte array
+ * @param file
+ * @param data
+ * @param append will append if set true. Otherwise, write from beginning
+ * @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();
+ }
+
+ /**
+ * create a new file with given length.
+ * @param context
+ * @param dirName
+ * @param length
+ * @return
+ * @throws IOException
+ */
+ public static File createNewFilledFile(Context context, String dirName, long length)
+ throws IOException {
+ final int BUFFER_SIZE = 10 * 1024 * 1024;
+ File file = createNewFile(context, dirName);
+ FileOutputStream out = new FileOutputStream(file);
+ byte[] data = generateRandomData(BUFFER_SIZE);
+ long written = 0;
+ while (written < length) {
+ out.write(data);
+ written += BUFFER_SIZE;
+ }
+ out.flush();
+ out.close();
+ return file;
+ }
+
+ /**
+ * remove given file or directory under the current app's files dir.
+ * @param context
+ * @param name
+ */
+ public static void removeFileOrDir(Context context, String name) {
+ File entry = new File(context.getFilesDir(), name);
+ if (entry.exists()) {
+ removeEntry(entry);
+ }
+ }
+
+ private static void removeEntry(File entry) {
+ if (entry.isDirectory()) {
+ String[] children = entry.list();
+ for (String child : children) {
+ removeEntry(new File(entry, child));
+ }
+ }
+ entry.delete();
+ }
+
+ /**
+ * measure time taken for each IO run with amount R/W
+ * @param count
+ * @param run
+ * @param readAmount returns amount of read in bytes for each interval.
+ * Value will not be written if /proc/self/io does not exist.
+ * @param writeAmount returns amount of write in bytes for each interval.
+ * @return time per each interval
+ * @throws IOException
+ */
+ public static double[] measureIO(int count, double[] readAmount, double[] writeAmount,
+ MeasureRun run) throws IOException {
+ double[] result = new double[count];
+ File procIo = new File("/proc/self/io");
+ boolean measureIo = procIo.exists();
+ long prev = System.currentTimeMillis();
+ RWAmount prevAmount = new RWAmount();
+ if (measureIo) {
+ prevAmount = getRWAmount(procIo);
+ }
+ for (int i = 0; i < count; i++) {
+ run.run(i);
+ long current = System.currentTimeMillis();
+ result[i] = current - prev;
+ prev = current;
+ if (measureIo) {
+ RWAmount currentAmount = getRWAmount(procIo);
+ readAmount[i] = currentAmount.mRd - prevAmount.mRd;
+ writeAmount[i] = currentAmount.mWr - prevAmount.mWr;
+ prevAmount = currentAmount;
+ }
+ }
+ return result;
+ }
+
+ private static class RWAmount {
+ public double mRd = 0.0;
+ public double mWr = 0.0;
+ };
+
+ private static RWAmount getRWAmount(File file) throws IOException {
+ RWAmount amount = new RWAmount();
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
+ String line;
+ while((line = br.readLine())!= null) {
+ if (line.startsWith("read_bytes")) {
+ amount.mRd = Double.parseDouble(line.split(" ")[1]);
+ } else if (line.startsWith("write_bytes")) {
+ amount.mWr = Double.parseDouble(line.split(" ")[1]);
+ }
+ }
+ br.close();
+ return amount;
+ }
+}
diff --git a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FullUpdateTest.java b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FullUpdateTest.java
new file mode 100644
index 0000000..261735c
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/FullUpdateTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.pts.filesystemperf;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.MeasureTime;
+import com.android.pts.util.PtsAndroidTestCase;
+import com.android.pts.util.ReportLog;
+import com.android.pts.util.SystemUtil;
+
+import android.util.Log;
+
+public class FullUpdateTest extends PtsAndroidTestCase {
+ private static final String DIR_INITIAL_FILL = "INITIAL_FILL";
+ private static final String DIR_WORK = "WORK";
+ private static final String TAG = "FullUpdateTest";
+
+ @Override
+ protected void tearDown() throws Exception {
+ FileUtil.removeFileOrDir(getContext(), DIR_INITIAL_FILL);
+ FileUtil.removeFileOrDir(getContext(), DIR_WORK);
+ super.tearDown();
+ }
+
+ // fill disk almost, update exceeding free space, then update some amount
+ // idea is to drain all free blocks and measure update performance
+ public void testAlmostFilledUpdate() throws IOException {
+ long freeDisk = SystemUtil.getFreeDiskSize(getContext());
+ final long FREE_SPACE_TO_LEAVE = 500L * 1024L * 1024L; // leave this much
+ long diskToFill = freeDisk - FREE_SPACE_TO_LEAVE;
+ Log.i(TAG, "free disk " + freeDisk + ", to fill " + diskToFill);
+ final long MAX_FILE_SIZE_TO_FILL = 1024L * 1024L * 1024L;
+ long filled = 0;
+ while (filled < diskToFill) {
+ long toFill = diskToFill - filled;
+ if (toFill > MAX_FILE_SIZE_TO_FILL) {
+ toFill = MAX_FILE_SIZE_TO_FILL;
+ }
+ Log.i(TAG, "Generating file " + toFill);
+ FileUtil.createNewFilledFile(getContext(),
+ DIR_INITIAL_FILL, toFill);
+ filled += toFill;
+ }
+
+ // now about freeSpaceToLeave should be left
+ // and try updating exceeding the free space size
+ final long FILE_SIZE = FREE_SPACE_TO_LEAVE / 2;
+ File file = FileUtil.createNewFilledFile(getContext(),
+ DIR_WORK, FILE_SIZE);
+ final int BUFFER_SIZE = 10 * 1024 * 1024;
+ final byte[] data = FileUtil.generateRandomData(BUFFER_SIZE);
+ for (int i = 0; i < 10; i++) {
+ final FileOutputStream out = new FileOutputStream(file);
+ int numberRepeat = (int)(FILE_SIZE / BUFFER_SIZE);
+ double[] times = MeasureTime.measure(numberRepeat, new MeasureRun() {
+
+ @Override
+ public void run(int i) throws IOException {
+ out.write(data);
+ out.flush();
+ }
+ });
+ out.close();
+ getReportLog().printArray(i + "-th round MB/s",
+ ReportLog.calcRatePerSecArray(BUFFER_SIZE / 1024 / 1024, times), true);
+ }
+ }
+}
diff --git a/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/RWTest.java b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/RWTest.java
new file mode 100644
index 0000000..f44e797
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/RWTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.pts.filesystemperf;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.MeasureTime;
+import com.android.pts.util.PtsAndroidTestCase;
+import com.android.pts.util.ReportLog;
+import com.android.pts.util.SystemUtil;
+
+public class RWTest extends PtsAndroidTestCase {
+ private static final String DIR_SEQ_WR = "SEQ_WR";
+ private static final String DIR_SEQ_UPD = "SEQ_UPD";
+ private static final String DIR_SEQ_RD = "SEQ_RD";
+ private static final int BUFFER_SIZE = 10 * 1024 * 1024;
+
+ @Override
+ protected void tearDown() throws Exception {
+ FileUtil.removeFileOrDir(getContext(), DIR_SEQ_WR);
+ FileUtil.removeFileOrDir(getContext(), DIR_SEQ_UPD);
+ FileUtil.removeFileOrDir(getContext(), DIR_SEQ_RD);
+ super.tearDown();
+ }
+
+ public void testSingleSequentialWrite() throws IOException {
+ final int numberOfFiles = (int)(getFileSizeExceedingMemory() / BUFFER_SIZE);
+ getReportLog().printValue("files", numberOfFiles);
+ final byte[] data = FileUtil.generateRandomData(BUFFER_SIZE);
+ final File[] files = FileUtil.createNewFiles(getContext(), DIR_SEQ_WR,
+ numberOfFiles);
+ double[] rdAmount = new double[numberOfFiles];
+ double[] wrAmount = new double[numberOfFiles];
+ double[] times = FileUtil.measureIO(numberOfFiles, rdAmount, wrAmount, new MeasureRun() {
+
+ @Override
+ public void run(int i) throws IOException {
+ FileUtil.writeFile(files[i], data, false);
+ }
+ });
+ getReportLog().printArray("try " + numberOfFiles + " files, result MB/s",
+ ReportLog.calcRatePerSecArray(BUFFER_SIZE / 1024 / 1024, times), true);
+ getReportLog().printArray("Wr amount", wrAmount, true);
+ }
+
+
+ public void testSingleSequentialUpdate() throws IOException {
+ final long fileSize = getFileSizeExceedingMemory();
+ File file = FileUtil.createNewFilledFile(getContext(),
+ DIR_SEQ_UPD, fileSize);
+ final byte[] data = FileUtil.generateRandomData(BUFFER_SIZE);
+ for (int i = 0; i < 4; i++) {
+ final FileOutputStream out = new FileOutputStream(file);
+ int numberRepeat = (int)(fileSize / BUFFER_SIZE);
+ double[] rdAmount = new double[numberRepeat];
+ double[] wrAmount = new double[numberRepeat];
+ double[] times = FileUtil.measureIO(numberRepeat, rdAmount, wrAmount, new MeasureRun() {
+
+ @Override
+ public void run(int i) throws IOException {
+ out.write(data);
+ out.flush();
+ }
+ });
+ out.close();
+ getReportLog().printArray(i + "-th round MB/s",
+ ReportLog.calcRatePerSecArray(BUFFER_SIZE / 1024 / 1024, times), true);
+ getReportLog().printArray("Wr amount", wrAmount, true);
+ }
+ }
+
+ public void testSingleSequentialRead() throws IOException {
+ final long fileSize = getFileSizeExceedingMemory();
+ long start = System.currentTimeMillis();
+ final File file = FileUtil.createNewFilledFile(getContext(),
+ DIR_SEQ_RD, fileSize);
+ long finish = System.currentTimeMillis();
+ getReportLog().printValue("write size " + fileSize + " result MB/s",
+ ReportLog.calcRatePerSec(fileSize / 1024 / 1024, finish - start));
+
+ final int NUMBER_READ = 4;
+
+ final byte[] data = new byte[BUFFER_SIZE];
+ double[] times = MeasureTime.measure(NUMBER_READ, new MeasureRun() {
+
+ @Override
+ public void run(int i) throws IOException {
+ final FileInputStream in = new FileInputStream(file);
+ long read = 0;
+ while (read < fileSize) {
+ in.read(data);
+ read += BUFFER_SIZE;
+ }
+ in.close();
+ }
+ });
+ getReportLog().printArray("read MB/s",
+ ReportLog.calcRatePerSecArray(fileSize / 1024 / 1024, times), true);
+ }
+
+ private long getFileSizeExceedingMemory() {
+ long freeDisk = SystemUtil.getFreeDiskSize(getContext());
+ long memSize = SystemUtil.getTotalMemory(getContext());
+ long diskSizeTarget = (2 * memSize / BUFFER_SIZE) * BUFFER_SIZE;
+ if (diskSizeTarget > freeDisk) {
+ fail("Free disk size " + freeDisk + " too small");
+ }
+ return diskSizeTarget;
+ }
+}
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
new file mode 100644
index 0000000..32e1878
--- /dev/null
+++ b/suite/pts/deviceTests/filesystemperf/src/com/android/pts/filesystemperf/TestTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+// code for testing, will be removed / moved before release
+
+package com.android.pts.filesystemperf;
+
+import com.android.pts.util.PtsAndroidTestCase;
+
+public class TestTest extends PtsAndroidTestCase {
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testPass() {
+ double[] array = new double[] {1.0, 2.0, 3.0};
+ getReportLog().printArray(" ", array, true);
+ getReportLog().printArray(" ", array, false);
+ getReportLog().printValue(" ", 1.0);
+ getReportLog().printValue(" ", 2.0);
+ }
+
+ public void testFail() throws Exception {
+ getReportLog().printValue(" ", 1.0);
+ getReportLog().printValue(" ", 2.0);
+ throw new Exception("failed");
+ }
+}
diff --git a/suite/pts/deviceTests/ptsutil/Android.mk b/suite/pts/deviceTests/ptsutil/Android.mk
new file mode 100644
index 0000000..d097036
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_MODULE := ptsutil
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/core/libcore/src/Dummy.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureRun.java
similarity index 60%
rename from tests/core/libcore/src/Dummy.java
rename to suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureRun.java
index 64b67de..1f6f6ed 100644
--- a/tests/core/libcore/src/Dummy.java
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureRun.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * 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.
@@ -14,11 +14,14 @@
* limitations under the License.
*/
+package com.android.pts.util;
+
+import java.io.IOException;
+
/**
- * We really just want the core-tests classes from the static java
- * library, but the build system currently needs at least one input
- * file, not just because its a sanity check, but because the static
- * class files and resources are included in the output of the local
- * java compilation.
+ * interface for measuring time for each run.
*/
-public final class Dummy {}
+public interface MeasureRun {
+
+ abstract public void run(int i) throws IOException;
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureTime.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureTime.java
new file mode 100644
index 0000000..337a472
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/MeasureTime.java
@@ -0,0 +1,40 @@
+/*
+ * 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.pts.util;
+
+import java.io.IOException;
+
+public class MeasureTime {
+ /**
+ * measure time taken for each run for given count
+ * @param count
+ * @param run
+ * @return array of time taken in each run in msec.
+ * @throws IOException
+ */
+ public static double[] measure(int count, MeasureRun run) throws IOException {
+ double[] result = new double[count];
+ long prev = System.currentTimeMillis();
+ for (int i = 0; i < count; i++) {
+ run.run(i);
+ long current = System.currentTimeMillis();
+ result[i] = current - prev;
+ prev = current;
+ }
+ return result;
+ }
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsActivityInstrumentationTestCase2.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsActivityInstrumentationTestCase2.java
new file mode 100644
index 0000000..84c1718
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsActivityInstrumentationTestCase2.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.pts.util;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase2;
+
+
+public class PtsActivityInstrumentationTestCase2<T extends Activity> extends
+ ActivityInstrumentationTestCase2<T> {
+
+ private ReportLog mReportLog = new ReportLog();
+
+ public PtsActivityInstrumentationTestCase2(Class<T> activityClass) {
+ super(activityClass);
+ }
+
+ public ReportLog getReportLog() {
+ return mReportLog;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mReportLog.throwReportToHost();
+ }
+
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsAndroidTestCase.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsAndroidTestCase.java
new file mode 100644
index 0000000..bf17956
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsAndroidTestCase.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.pts.util;
+
+import android.test.AndroidTestCase;
+
+public class PtsAndroidTestCase extends AndroidTestCase {
+
+ private ReportLog mReportLog = new ReportLog();
+
+ public ReportLog getReportLog() {
+ return mReportLog;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mReportLog.throwReportToHost();
+ }
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsException.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsException.java
new file mode 100644
index 0000000..e8ec5be
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/PtsException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.pts.util;
+
+/**
+ * Exception throw by PTS test to pass the result to host
+ * This should not be thrown by test app unless the result is complete.
+ */
+@SuppressWarnings("serial")
+public class PtsException extends Exception {
+ public PtsException(String message) {
+ super(message);
+ }
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/ReportLog.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/ReportLog.java
new file mode 100644
index 0000000..15be1aa
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/ReportLog.java
@@ -0,0 +1,154 @@
+/*
+ * 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.pts.util;
+
+import android.util.Log;
+
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ * Utility class to print performance measurement result back to host.
+ * For now, throws know exception with message.
+ *
+ * Format:
+ * LOG_SEPARATOR : separates each log
+ * Message = log [LOG_SEPARATOR log]*
+ * log for single value = classMethodName:line_number|header|d|value
+ * log for array = classMethodName:line_number|header|da|values|
+ * average average_value min|max value stddev value
+ */
+public class ReportLog {
+ private static final String TAG = "PtsReport";
+ private static final String LOG_SEPARATOR = "+++";
+ private static final String LOG_ELEM_SEPARATOR = "|";
+
+ private List<String> mMessages = new LinkedList<String> ();
+ /**
+ * print given value to the report
+ * @param header string to explain the contents. It can be unit for the value.
+ * @param val
+ */
+ public void printValue(String header, double val) {
+ String message = getClassMethodNames(4, true) + LOG_ELEM_SEPARATOR + header +
+ LOG_ELEM_SEPARATOR + "d" + LOG_ELEM_SEPARATOR + val;
+ mMessages.add(message);
+ Log.i(TAG, message);
+ }
+
+ /**
+ * array version of printValue
+ * @param header
+ * @param val
+ * @param addMin add minimum to the result. If false, add maximum to the result
+ */
+ public void printArray(String header, double[] val, boolean addMin) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(getClassMethodNames(4, true) + LOG_ELEM_SEPARATOR + header +
+ LOG_ELEM_SEPARATOR + "da" + LOG_ELEM_SEPARATOR);
+ double average = 0.0;
+ double min = val[0];
+ double max = val[0];
+ for (double v : val) {
+ builder.append(v);
+ builder.append(" ");
+ average += v;
+ if (v > max) {
+ max = v;
+ }
+ if (v < min) {
+ min = v;
+ }
+ }
+ average /= val.length;
+ double power = 0;
+ for (double v : val) {
+ double delta = v - average;
+ power += (delta * delta);
+ }
+ power /= val.length;
+ double stdDev = Math.sqrt(power);
+ builder.append(LOG_ELEM_SEPARATOR + "average " + average +
+ (addMin ? (" min " + min) : (" max " + max)) + " stddev " + stdDev);
+ mMessages.add(builder.toString());
+ Log.i(TAG, builder.toString());
+ }
+
+ public void throwReportToHost() throws PtsException {
+ StringBuilder builder = new StringBuilder();
+ for (String entry : mMessages) {
+ builder.append(entry);
+ builder.append(LOG_SEPARATOR);
+ }
+ // delete the last separator
+ if (builder.length() >= LOG_SEPARATOR.length()) {
+ builder.delete(builder.length() - LOG_SEPARATOR.length(), builder.length());
+ }
+ throw new PtsException(builder.toString());
+ }
+
+ /**
+ * calculate rate per sec for given change happened during given timeInMSec.
+ * timeInSec with 0 value will be changed to small value to prevent divide by zero.
+ * @param change
+ * @param timeInMSec
+ * @return
+ */
+ public static double calcRatePerSec(double change, double timeInMSec) {
+ if (timeInMSec == 0) {
+ return change * 1000.0 / 0.001; // do not allow zero
+ } else {
+ return change * 1000.0 / timeInMSec;
+ }
+ }
+
+ /**
+ * array version of calcRatePerSecArray
+ * @param change
+ * @param timeInMSec
+ * @return
+ */
+ public static double[] calcRatePerSecArray(double change, double[] timeInMSec) {
+ double[] result = new double[timeInMSec.length];
+ change *= 1000.0;
+ for (int i = 0; i < timeInMSec.length; i++) {
+ if (timeInMSec[i] == 0) {
+ result[i] = change / 0.001;
+ } else {
+ result[i] = change / timeInMSec[i];
+ }
+ }
+ return result;
+ }
+
+ /**
+ * get classname.methodname from call stack of the current thread
+ *
+ * @return
+ */
+ public static String getClassMethodNames() {
+ return getClassMethodNames(4, false);
+ }
+
+ private static String getClassMethodNames(int depth, boolean addLineNumber) {
+ StackTraceElement[] elements = Thread.currentThread().getStackTrace();
+ String names = elements[depth].getClassName() + "." + elements[depth].getMethodName() +
+ (addLineNumber ? ":" + elements[depth].getLineNumber() : "");
+ return names;
+ }
+}
diff --git a/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/SystemUtil.java b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/SystemUtil.java
new file mode 100644
index 0000000..7975463
--- /dev/null
+++ b/suite/pts/deviceTests/ptsutil/src/com/android/pts/util/SystemUtil.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.pts.util;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.MemoryInfo;
+import android.content.Context;
+import android.os.StatFs;
+
+public class SystemUtil {
+ public static long getFreeDiskSize(Context context) {
+ StatFs statFs = new StatFs(context.getFilesDir().getAbsolutePath());
+ return (long)statFs.getAvailableBlocks() * statFs.getBlockSize();
+ }
+
+ public static long getFreeMemory(Context context) {
+ MemoryInfo info = new MemoryInfo();
+ ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ activityManager.getMemoryInfo(info);
+ return info.availMem;
+ }
+
+ public static long getTotalMemory(Context context) {
+ MemoryInfo info = new MemoryInfo();
+ ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ activityManager.getMemoryInfo(info);
+ return info.totalMem; // TODO totalMem N/A in ICS.
+ }
+}
diff --git a/suite/pts/deviceTests/ui/Android.mk b/suite/pts/deviceTests/ui/Android.mk
new file mode 100644
index 0000000..f3c3944
--- /dev/null
+++ b/suite/pts/deviceTests/ui/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2012 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ptsutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := PtsDeviceUi
+
+LOCAL_SDK_VERSION := 16
+
+include $(BUILD_PTS_PACKAGE)
+
+
diff --git a/suite/pts/deviceTests/ui/AndroidManifest.xml b/suite/pts/deviceTests/ui/AndroidManifest.xml
new file mode 100644
index 0000000..f750d14
--- /dev/null
+++ b/suite/pts/deviceTests/ui/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.pts.ui">
+
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity
+ android:name=".ScrollingActivity"
+ android:screenOrientation="portrait"
+ android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.pts.ui"
+ android:label="UI Latency measurement" />
+</manifest>
diff --git a/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingActivity.java b/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingActivity.java
new file mode 100644
index 0000000..7bdfff9
--- /dev/null
+++ b/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingActivity.java
@@ -0,0 +1,104 @@
+/*
+ * 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.pts.ui;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class ScrollingActivity extends ListActivity implements OnScrollListener
+{
+ static final String TAG = "ScrollingActivity";
+ private static final int NUMBER_ELEMENTS = 10000;
+ private static final int SCROLL_TIME_IN_MS = 1;
+ private static final int WAIT_TIMEOUT_IN_SECS = 5 * 60;
+ private String[] mItems = new String[NUMBER_ELEMENTS];
+ private CountDownLatch mLatchStop = null;
+ private int mTargetLoc;
+
+ public void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+ for (int i = 0; i < NUMBER_ELEMENTS; i++) {
+ mItems[i] = Integer.toString(i);
+ }
+ setListAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, mItems));
+ ListView view = getListView();
+ view.setOnScrollListener(this);
+ //view.setVelocityScale(100.0f);
+ }
+
+ public boolean scrollToTop() {
+ return doScroll(0);
+ }
+ public boolean scrollToBottom() {
+ return doScroll(NUMBER_ELEMENTS - 1);
+ }
+
+ private boolean doScroll(final int loc) {
+ mLatchStop = new CountDownLatch(1);
+ mTargetLoc = loc;
+ final ListView view = getListView();
+ runOnUiThread( new Runnable() {
+ @Override
+ public void run() {
+ view.smoothScrollToPositionFromTop(loc, 0, SCROLL_TIME_IN_MS);
+ }
+ });
+ boolean result = false;
+ try {
+ result = mLatchStop.await(WAIT_TIMEOUT_IN_SECS, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ mLatchStop = null;
+ return result;
+ }
+ public void onStop()
+ {
+ super.onStop();
+ }
+
+ public void onResume()
+ {
+ super.onResume();
+ }
+
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem,
+ int visibleItemCount, int totalItemCount) {
+ //Log.i(TAG, "onScroll " + firstVisibleItem + " " + visibleItemCount);
+ if ((mTargetLoc >= firstVisibleItem) &&
+ (mTargetLoc <= (firstVisibleItem + visibleItemCount))) {
+ if (mLatchStop != null) {
+ mLatchStop.countDown();
+ }
+ }
+ }
+}
diff --git a/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingTest.java b/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingTest.java
new file mode 100644
index 0000000..a985591
--- /dev/null
+++ b/suite/pts/deviceTests/ui/src/com/android/pts/ui/ScrollingTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.pts.ui;
+
+import java.io.IOException;
+
+import com.android.pts.util.MeasureRun;
+import com.android.pts.util.MeasureTime;
+import com.android.pts.util.PtsActivityInstrumentationTestCase2;
+import com.android.pts.util.ReportLog;
+
+public class ScrollingTest extends PtsActivityInstrumentationTestCase2<ScrollingActivity> {
+ private ScrollingActivity mActivity;
+
+ public ScrollingTest() {
+ super(ScrollingActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ getInstrumentation().waitForIdleSync();
+ try {
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ }
+ });
+ } catch (Throwable e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mActivity = null;
+ super.tearDown();
+ }
+
+ public void testFullScrolling() throws IOException {
+ final int NUMBER_REPEAT = 10;
+ final ScrollingActivity activity = mActivity;
+ double[] results = MeasureTime.measure(NUMBER_REPEAT, new MeasureRun() {
+
+ @Override
+ public void run(int i) throws IOException {
+ assertTrue(activity.scrollToBottom());
+ assertTrue(activity.scrollToTop());
+ }
+ });
+ getReportLog().printArray("ms", results, false);
+ }
+}
diff --git a/suite/pts/expectations/knownfailures.txt b/suite/pts/expectations/knownfailures.txt
new file mode 100644
index 0000000..0d4f101
--- /dev/null
+++ b/suite/pts/expectations/knownfailures.txt
@@ -0,0 +1,2 @@
+[
+]
diff --git a/suite/pts/tools/Android.mk b/suite/pts/tools/Android.mk
new file mode 100644
index 0000000..c141484
--- /dev/null
+++ b/suite/pts/tools/Android.mk
@@ -0,0 +1,17 @@
+#
+# 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 $(call all-subdir-makefiles)
diff --git a/suite/pts/tools/tradefed/Android.mk b/suite/pts/tools/tradefed/Android.mk
new file mode 100644
index 0000000..09e49b1
--- /dev/null
+++ b/suite/pts/tools/tradefed/Android.mk
@@ -0,0 +1,22 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PREBUILT_EXECUTABLES := pts-tradefed
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/suite/pts/tools/tradefed/pts-tradefed b/suite/pts/tools/tradefed/pts-tradefed
new file mode 100755
index 0000000..fedbfaf
--- /dev/null
+++ b/suite/pts/tools/tradefed/pts-tradefed
@@ -0,0 +1,86 @@
+#!/bin/bash
+
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# launcher script for cts-tradefed harness for PTS
+# can be used from an Android build environment, or a standalone pts zip
+
+checkFile() {
+ if [ ! -f "$1" ]; then
+ echo "Unable to locate $1"
+ exit
+ fi;
+}
+
+checkPath() {
+ if ! type -P $1 &> /dev/null; then
+ echo "Unable to find $1 in path."
+ exit
+ fi;
+}
+
+checkPath adb
+checkPath java
+
+# check java version
+JAVA_VERSION=$(java -version 2>&1 | head -n 1 | grep '[ "]1\.6[\. "$$]')
+if [ "${JAVA_VERSION}" == "" ]; then
+ echo "Wrong java version. 1.6 is required."
+ exit
+fi
+
+# check debug flag and set up remote debugging
+if [ -n "${TF_DEBUG}" ]; then
+ if [ -z "${TF_DEBUG_PORT}" ]; then
+ TF_DEBUG_PORT=10088
+ fi
+ RDBG_FLAG=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${TF_DEBUG_PORT}
+fi
+
+
+# check if in Android build env
+if [ ! -z ${ANDROID_BUILD_TOP} ]; then
+ HOST=`uname`
+ if [ "$HOST" == "Linux" ]; then
+ OS="linux-x86"
+ elif [ "$HOST" == "Darwin" ]; then
+ OS="darwin-x86"
+ else
+ echo "Unrecognized OS"
+ exit
+ fi;
+ PTS_ROOT=${ANDROID_BUILD_TOP}/out/host/${OS}/pts
+ if [ ! -d ${PTS_ROOT} ]; then
+ echo "Could not find $PTS_ROOT in Android build environment. Try 'make pts'"
+ exit
+ fi;
+fi;
+
+if [ -z ${PTS_ROOT} ]; then
+ # assume we're in an extracted pts install
+ PTS_ROOT="$(dirname $0)/../.."
+fi;
+
+JAR_DIR=${PTS_ROOT}/android-pts/tools
+JARS="ddmlib-prebuilt.jar tradefed-prebuilt.jar hosttestlib.jar cts-tradefed.jar"
+
+for JAR in $JARS; do
+ checkFile ${JAR_DIR}/${JAR}
+ JAR_PATH=${JAR_PATH}:${JAR_DIR}/${JAR}
+done
+
+java $RDBG_FLAG \
+ -cp ${JAR_PATH} -DCTS_ROOT=${PTS_ROOT} -DPTS=1 com.android.cts.tradefed.command.CtsConsole "$@"
+
diff --git a/tests/Android.mk b/tests/Android.mk
index 77340df..15705dd 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -36,6 +36,8 @@
LOCAL_STATIC_JAVA_LIBRARIES := ctsutil ctstestserver ctstestrunner
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
# Build the test APK using its own makefile, and any other CTS-related packages
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index f9999f4..590ee36 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -118,7 +118,8 @@
<application android:label="Android TestCase"
android:icon="@drawable/size_48x48"
- android:name="android.app.cts.MockApplication">
+ android:name="android.app.cts.MockApplication"
+ android:supportsRtl="true">
<activity android:name="android.app.cts.ActionBarActivity" />
<activity android:name="android.widget.cts.TwoLineListItemStubActivity"
@@ -243,6 +244,14 @@
</intent-filter>
</activity>
+ <activity android:name="android.widget.cts.LayoutDirectionStubActivity"
+ android:label="LayoutDirectionStubActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
<activity android:name="android.widget.cts.ProgressBarStubActivity"
android:label="ProgressBarStubActivity">
<intent-filter>
diff --git a/tests/SignatureTest/Android.mk b/tests/SignatureTest/Android.mk
index 3ebab34..cc0d53c 100644
--- a/tests/SignatureTest/Android.mk
+++ b/tests/SignatureTest/Android.mk
@@ -19,6 +19,8 @@
LOCAL_MODULE_TAGS := optional
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+# and because it is in data, do not strip classes.dex
+LOCAL_DEX_PREOPT := false
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/acceleration/Android.mk b/tests/acceleration/Android.mk
index 6e30f59..bb6b89f 100644
--- a/tests/acceleration/Android.mk
+++ b/tests/acceleration/Android.mk
@@ -20,6 +20,8 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_DEX_PREOPT := false
+
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/accessibility/Android.mk b/tests/accessibility/Android.mk
index 2ffe162..43fa291 100644
--- a/tests/accessibility/Android.mk
+++ b/tests/accessibility/Android.mk
@@ -24,4 +24,8 @@
LOCAL_SDK_VERSION := current
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/tests/accessibilityservice/Android.mk b/tests/accessibilityservice/Android.mk
index 50fe6b0..f9fec93 100644
--- a/tests/accessibilityservice/Android.mk
+++ b/tests/accessibilityservice/Android.mk
@@ -20,6 +20,8 @@
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_DEX_PREOPT := false
+
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/core/ctscore.mk b/tests/core/ctscore.mk
index 049a58e..27ff881 100644
--- a/tests/core/ctscore.mk
+++ b/tests/core/ctscore.mk
@@ -12,60 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# First we build an apk without the core-tests resource
-cts_ORIGINAL_PACKAGE_NAME := $(LOCAL_PACKAGE_NAME)
-
-LOCAL_PACKAGE_NAME := $(LOCAL_PACKAGE_NAME).no-core-tests-res
-# Make sure this apk won't get installed
-LOCAL_UNINSTALLABLE_MODULE := true
-
LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_DEX_PREOPT := false
-include $(BUILD_PACKAGE)
-# Vars set by $(BUILD_PACKAGE) and needed by the below module definition.
-cts_no-core-tests-res_BUILT_MODULE := $(LOCAL_BUILT_MODULE)
-cts_no-core-tests-res_private_key := $(private_key)
-cts_no-core-tests-res_certificate := $(certificate)
-
-##################################
-# Now the rules to build the apk with core-tests resource
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := $(cts_ORIGINAL_PACKAGE_NAME)
-LOCAL_MODULE_CLASS := APPS
# don't include these packages in any target
LOCAL_MODULE_TAGS := optional
-# and when built explicitly put them in the data partition
+# and when installed explicitly put them in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
-LOCAL_BUILT_MODULE_STEM := package.apk
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-CORETESTS_INTERMEDIATES := $(call intermediates-dir-for,JAVA_LIBRARIES,core-tests,,COMMON)
-
-$(LOCAL_BUILT_MODULE): PRIVATE_INTERMEDIATES_COMMON := $(intermediates.COMMON)
-$(LOCAL_BUILT_MODULE): PRIVATE_CORETESTS_INTERMEDIATES_COMMON := $(CORETESTS_INTERMEDIATES)
-$(LOCAL_BUILT_MODULE): PRIVATE_PRIVATE_KEY := $(cts_no-core-tests-res_private_key)
-$(LOCAL_BUILT_MODULE): PRIVATE_CERTIFICATE := $(cts_no-core-tests-res_certificate)
-$(LOCAL_BUILT_MODULE): $(cts_no-core-tests-res_BUILT_MODULE) $(CORETESTS_INTERMEDIATES)/javalib.jar
- @echo "Add resources to package ($@)"
- $(hide) mkdir -p $(dir $@) $(PRIVATE_INTERMEDIATES_COMMON)
- $(hide) rm -rf $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses
- # javalib.jar should only contain .dex files, but the harmony tests also include
- # some .class files, so get rid of them
- $(hide) unzip -qo $(PRIVATE_CORETESTS_INTERMEDIATES_COMMON)/javalib.jar \
- -d $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses
- $(hide) find $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses -type f -name "*.class" -delete
- $(hide) rm -f $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses/classes.dex
- $(hide) cp $< $@
- $(hide) jar uf $@ -C $(PRIVATE_INTERMEDIATES_COMMON)/ctsclasses .
- $(sign-package)
- $(align-package)
-
-# some global vars set in $(BUILD_PACKAGE), not sure if we really need here
-PACKAGES.$(cts_ORIGINAL_PACKAGE_NAME).PRIVATE_KEY := $(cts_no-core-tests-res_private_key)
-PACKAGES.$(cts_ORIGINAL_PACKAGE_NAME).CERTIFICATE := $(cts_no-core-tests-res_certificate)
-PACKAGES := $(PACKAGES) $(cts_ORIGINAL_PACKAGE_NAME)
+# Don't delete META-INF from the core-tests jar
+LOCAL_DONT_DELETE_JAR_META_INF := true
+include $(BUILD_PACKAGE)
diff --git a/tests/core/libcore/com/Android.mk b/tests/core/libcore/com/Android.mk
index 91a5da0..02dc3de 100644
--- a/tests/core/libcore/com/Android.mk
+++ b/tests/core/libcore/com/Android.mk
@@ -19,7 +19,6 @@
endif
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.com
LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/dalvik/Android.mk b/tests/core/libcore/dalvik/Android.mk
index 45f6e7e..7b77a75 100644
--- a/tests/core/libcore/dalvik/Android.mk
+++ b/tests/core/libcore/dalvik/Android.mk
@@ -19,7 +19,6 @@
endif
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.dalvik
LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/libcore/Android.mk b/tests/core/libcore/libcore/Android.mk
index 97e32bc..382b386 100644
--- a/tests/core/libcore/libcore/Android.mk
+++ b/tests/core/libcore/libcore/Android.mk
@@ -19,7 +19,6 @@
endif
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.libcore
LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/org/Android.mk b/tests/core/libcore/org/Android.mk
index 8fad8de..d7a96b3 100644
--- a/tests/core/libcore/org/Android.mk
+++ b/tests/core/libcore/org/Android.mk
@@ -19,7 +19,6 @@
endif
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.org
LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/sun/Android.mk b/tests/core/libcore/sun/Android.mk
index 5fc0c48..44d3d70 100644
--- a/tests/core/libcore/sun/Android.mk
+++ b/tests/core/libcore/sun/Android.mk
@@ -19,7 +19,6 @@
endif
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.sun
LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/tests/Android.mk b/tests/core/libcore/tests/Android.mk
index bcb6628..bfd235f 100644
--- a/tests/core/libcore/tests/Android.mk
+++ b/tests/core/libcore/tests/Android.mk
@@ -19,7 +19,6 @@
endif
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := ../src/Dummy.java
LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.tests
LOCAL_STATIC_JAVA_LIBRARIES := core-tests
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/runner/Android.mk b/tests/core/runner/Android.mk
index 7658b7a..fb548fc 100644
--- a/tests/core/runner/Android.mk
+++ b/tests/core/runner/Android.mk
@@ -27,4 +27,6 @@
LOCAL_PACKAGE_NAME := android.core.tests.runner
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests
+
include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java b/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
index 6dce943..d992839 100644
--- a/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
+++ b/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
@@ -119,16 +119,6 @@
*/
private Class<?> lastClass;
- /**
- * The minimum time we expect a test to take.
- */
- private static final int MINIMUM_TIME = 100;
-
- /**
- * The start time of our current test in System.currentTimeMillis().
- */
- private long startTime;
-
@Override
public void startTest(Test test) {
if (test.getClass() != lastClass) {
@@ -140,30 +130,12 @@
test.getClass().getClassLoader());
mEnvironment.reset();
-
- startTime = System.currentTimeMillis();
}
@Override
public void endTest(Test test) {
if (test instanceof TestCase) {
cleanup((TestCase)test);
-
- /*
- * Make sure all tests take at least MINIMUM_TIME to
- * complete. If they don't, we wait a bit. The Cupcake
- * Binder can't handle too many operations in a very
- * short time, which causes headache for the CTS.
- */
- long timeTaken = System.currentTimeMillis() - startTime;
-
- if (timeTaken < MINIMUM_TIME) {
- try {
- Thread.sleep(MINIMUM_TIME - timeTaken);
- } catch (InterruptedException ignored) {
- // We don't care.
- }
- }
}
}
diff --git a/tests/deviceadmin/Android.mk b/tests/deviceadmin/Android.mk
index 7322ad5..c354599 100644
--- a/tests/deviceadmin/Android.mk
+++ b/tests/deviceadmin/Android.mk
@@ -28,4 +28,6 @@
LOCAL_SDK_VERSION := current
+LOCAL_DEX_PREOPT := false
+
include $(BUILD_PACKAGE)
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 9228564..0d4f101 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -1,77 +1,2 @@
[
- {
- names: [
- "com.android.cts.appsecurity.AppSecurityTests#testReadExternalStorageEnforced",
- "com.android.cts.appsecurity.AppSecurityTests#testReadExternalStorageUnenforced"
- ],
- bug: 6721185
- },
- {
- name: "android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverText",
- bug: 6468754
- },
- {
- name: "android.accessibilityservice.cts.AccessibilityWindowQueryTest#testPerformGlobalActionBack",
- bug: 6365037
- },
- {
- names: [
- "android.media.cts.StreamingMediaPlayerTest#testRTSP_MPEG4SP_AAC_Video1",
- "android.media.cts.StreamingMediaPlayerTest#testRTSP_MPEG4SP_AAC_Video2"
- ],
- bug: 6422606
- },
- {
- names: [
- "android.media.cts.StreamingMediaPlayerTest#testRTSP_H263_AMR_Video1",
- "android.media.cts.StreamingMediaPlayerTest#testRTSP_H263_AMR_Video2"
- ],
- bug: 6216077
- },
- {
- names: [
- "android.media.cts.StreamingMediaPlayerTest#testRTSP_H264Base_AAC_Video1",
- "android.media.cts.StreamingMediaPlayerTest#testRTSP_H264Base_AAC_Video2"
- ],
- bug: 6215719
- },
- {
- name: "android.nativemedia.sl.SLObjectCreationTest#testAudioRecorderCreation",
- bug: 4970300
- },
- {
- name: "android.opengl.cts.AttachShaderTest#test_glAttachedShaders_invalidshader",
- bug: 6404341
- },
- {
- name: "android.openglperf.cts.GlVboPerfTest#testVboWithVaryingIndexBufferNumbers",
- bug: 5898262
- },
- {
- name: "android.text.cts.AndroidCharacterTest#testMirror",
- bug: 4371654
- },
- {
- name: "android.text.format.cts.DateUtilsTest#test2038",
- bug: 6293653
- },
- {
- description: "flakey libcore tests",
- names: [
- "libcore.java.net.ConcurrentCloseTest",
- "libcore.java.net.SocketTest#testAvailable",
- "libcore.java.net.URLConnectionTest",
- "libcore.java.util.prefs.OldAbstractPreferencesTest",
- "libcore.java.util.prefs.OldPreferencesTest#testAddNodeChangeListener",
- "libcore.net.http.HttpResponseCacheTest#testClientPrematureDisconnectWithChunkedEncoding",
- "org.apache.harmony.luni.tests.java.net.URLConnectionTest",
- "org.apache.harmony.xnet.provider.jsse.NativeCryptoTest#test_SSL_do_handshake_server_timeout"
- ]
- },
- {
- description: "MediaPlayerFlakyNetworkTest tests",
- name: "android.media.cts.MediaPlayerFlakyNetworkTest",
- bug: 6782035
- }
]
-
diff --git a/tests/res/layout/layoutdirection_layout.xml b/tests/res/layout/layoutdirection_layout.xml
new file mode 100644
index 0000000..e506dc1
--- /dev/null
+++ b/tests/res/layout/layoutdirection_layout.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2012 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout android:id="@+id/layout_linearlayout_ltr"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="ltr">
+
+ <LinearLayout android:id="@+id/layout_linearlayout_ltr_child_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="ltr" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_ltr_child_2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="rtl" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_ltr_child_3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="inherit" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_ltr_child_4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="locale" />
+
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/layout_linearlayout_rtl"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="rtl">
+
+ <LinearLayout android:id="@+id/layout_linearlayout_rtl_child_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="ltr" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_rtl_child_2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="rtl" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_rtl_child_3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="inherit" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_rtl_child_4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="locale" />
+
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/layout_linearlayout_locale"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="locale">
+
+ <LinearLayout android:id="@+id/layout_linearlayout_locale_child_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="ltr" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_locale_child_2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="rtl" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_locale_child_3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="inherit" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_locale_child_4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="locale" />
+
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/layout_linearlayout_inherit"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="inherit">
+
+ <LinearLayout android:id="@+id/layout_linearlayout_inherit_child_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="ltr" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_inherit_child_2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="rtl" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_inherit_child_3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="inherit" />
+
+ <LinearLayout android:id="@+id/layout_linearlayout_inherit_child_4"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layoutDirection="locale" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/tests/res/layout/relative_layout.xml b/tests/res/layout/relative_layout.xml
index 669e86e..db4b2e8 100644
--- a/tests/res/layout/relative_layout.xml
+++ b/tests/res/layout/relative_layout.xml
@@ -162,4 +162,97 @@
android:layout_height="match_parent"
android:prompt="@string/text_view_hello"/>
+ <RelativeLayout
+ android:id="@+id/relative_sublayout_attrs_2"
+ android:background="@drawable/blue"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <!-- view21, centered within its parent. -->
+ <TextView
+ android:id="@+id/relative_view21"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:text="@string/relative_view1"/>
+
+ <!-- view22, below view1 and has same start position with view21. -->
+ <TextView
+ android:id="@+id/relative_view22"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/relative_view21"
+ android:layout_alignStart="@id/relative_view21"
+ android:text="@string/relative_view2"/>
+
+ <!-- view23, has same top position with view21 and same bottom position with view22,
+ and on the end of view1. -->
+ <TextView
+ android:id="@+id/relative_view23"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignTop="@id/relative_view21"
+ android:layout_alignBottom="@id/relative_view22"
+ android:layout_toEndOf="@id/relative_view21"
+ android:text="@string/relative_view3"/>
+
+ <!-- view24, has same end position with view23 and above view23. -->
+ <TextView
+ android:id="@+id/relative_view24"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignEnd="@id/relative_view23"
+ android:layout_above="@id/relative_view23"
+ android:text="@string/relative_view4"/>
+
+ <!-- view25 goes on the start-bottom -->
+ <TextView
+ android:id="@+id/relative_view25"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentStart="true"
+ android:text="@string/relative_view5"/>
+
+ <!-- view26 goes on the top-end -->
+ <TextView
+ android:id="@+id/relative_view26"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentEnd="true"
+ android:text="@string/relative_view6"/>
+
+ <!-- view27, has same baseline with view26 and centered horizontally within its parent. -->
+ <TextView
+ android:id="@+id/relative_view27"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@id/relative_view26"
+ android:layout_centerHorizontal="true"
+ android:text="@string/relative_view7"/>
+
+ <!-- view28, centered vertically within its parent and on the start of view21. -->
+ <TextView
+ android:id="@+id/relative_view28"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toStartOf="@id/relative_view21"
+ android:layout_centerVertical="true"
+ android:text="@string/relative_view8"/>
+
+ <!-- view29, has same top and bottom position with view23 and same start position
+ with its parent. -->
+ <TextView
+ android:id="@+id/relative_view29"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignStart="@id/gravity_bottom"
+ android:layout_alignTop="@id/relative_view23"
+ android:layout_alignBottom="@id/relative_view23"
+ android:layout_alignWithParentIfMissing="true"
+ android:text="@string/relative_view9"/>
+
+ </RelativeLayout>
+
</RelativeLayout>
diff --git a/tests/src/android/widget/cts/LayoutDirectionStubActivity.java b/tests/src/android/widget/cts/LayoutDirectionStubActivity.java
new file mode 100644
index 0000000..66f24f7
--- /dev/null
+++ b/tests/src/android/widget/cts/LayoutDirectionStubActivity.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import com.android.cts.stub.R;
+
+/**
+ * A minimal application for layout direction test.
+ */
+public class LayoutDirectionStubActivity extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.layoutdirection_layout);
+ }
+}
diff --git a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
index 5cac9f9..73883e2 100644
--- a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
+++ b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
@@ -30,7 +30,7 @@
public class AccessibilityNodeInfoTest extends AndroidTestCase {
/** The number of properties of the {@link AccessibilityNodeInfo} class. */
- private static final int NON_STATIC_FIELD_COUNT = 19;
+ private static final int NON_STATIC_FIELD_COUNT = 17;
@SmallTest
public void testMarshaling() throws Exception {
diff --git a/tests/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml b/tests/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml
index 383f209..cb3d153 100644
--- a/tests/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml
+++ b/tests/tests/accessibilityservice/res/layout/accessibility_focus_and_input_focus_sync_test.xml
@@ -20,6 +20,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
+ android:layoutDirection="ltr"
android:contentDescription="@string/firstLinearLayout" >
<TextView
@@ -55,6 +56,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
+ android:layoutDirection="rtl"
android:contentDescription="@string/secondLinearLayout"
android:clickable="true"
android:importantForAccessibility="no" >
diff --git a/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml b/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
index 1c15f8e..5b3d2e6 100644
--- a/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
+++ b/tests/tests/accessibilityservice/res/layout/accessibility_text_traversal_test.xml
@@ -40,6 +40,7 @@
android:layout_height="200dip"
android:maxLines="1000"
android:scrollbars="vertical"
+ android:focusable="false"
/>
</LinearLayout>
diff --git a/tests/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml b/tests/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
index 26f60bf..fe420bc 100644
--- a/tests/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
+++ b/tests/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
@@ -4,6 +4,7 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
+ android:layoutDirection="rtl"
android:importantForAccessibility="yes"
android:contentDescription="@string/rootLinearLayout">
@@ -20,6 +21,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
+ android:layoutDirection="ltr"
android:importantForAccessibility="no"
android:contentDescription="@string/firstLinearLayout" >
@@ -57,6 +59,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
+ android:layoutDirection="rtl"
android:contentDescription="@string/secondLinearLayout"
android:clickable="true"
android:importantForAccessibility="no" >
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
index 80ddd87..0f687d0 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
@@ -77,8 +77,11 @@
AccessibilityServiceInfo.FEEDBACK_SPOKEN));
assertEquals("[FEEDBACK_VISUAL]", AccessibilityServiceInfo.feedbackTypeToString(
AccessibilityServiceInfo.FEEDBACK_VISUAL));
+ assertEquals("[FEEDBACK_BRAILLE]", AccessibilityServiceInfo.feedbackTypeToString(
+ AccessibilityServiceInfo.FEEDBACK_BRAILLE));
assertEquals("[FEEDBACK_SPOKEN, FEEDBACK_HAPTIC, FEEDBACK_AUDIBLE, FEEDBACK_VISUAL,"
- + " FEEDBACK_GENERIC]", AccessibilityServiceInfo.feedbackTypeToString(
+ + " FEEDBACK_GENERIC, FEEDBACK_BRAILLE]",
+ AccessibilityServiceInfo.feedbackTypeToString(
AccessibilityServiceInfo.FEEDBACK_ALL_MASK));
}
diff --git a/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java b/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
index 71945ac..f8f1f43 100644
--- a/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
+++ b/tests/tests/animation/src/android/animation/cts/ObjectAnimatorTest.java
@@ -20,7 +20,6 @@
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
-import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Interpolator;
@@ -250,5 +249,3 @@
this.runTestOnUiThread(mAnimationRunnable);
}
}
-
-
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
index e8e32ee..e64da89 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BasicAdapterTest.java
@@ -31,8 +31,8 @@
* BluetoothAdapter}.
*/
public class BasicAdapterTest extends AndroidTestCase {
- private static final int DISABLE_TIMEOUT = 60000; // ms timeout for BT disable
- private static final int ENABLE_TIMEOUT = 60000; // ms timeout for BT enable
+ private static final int DISABLE_TIMEOUT = 5000; // ms timeout for BT disable
+ private static final int ENABLE_TIMEOUT = 10000; // ms timeout for BT enable
private static final int POLL_TIME = 400; // ms to poll BT state
private boolean mHasBluetooth;
@@ -227,13 +227,12 @@
return;
}
+ assertEquals(BluetoothAdapter.STATE_ON, adapter.getState());
+ assertTrue(adapter.isEnabled());
adapter.disable();
for (int i=0; i<DISABLE_TIMEOUT/POLL_TIME; i++) {
sleep(POLL_TIME);
switch (adapter.getState()) {
- case BluetoothAdapter.STATE_ON:
- assertTrue(adapter.isEnabled());
- continue;
case BluetoothAdapter.STATE_OFF:
assertFalse(adapter.isEnabled());
return;
@@ -256,13 +255,12 @@
return;
}
+ assertEquals(BluetoothAdapter.STATE_OFF, adapter.getState());
+ assertFalse(adapter.isEnabled());
adapter.enable();
for (int i=0; i<ENABLE_TIMEOUT/POLL_TIME; i++) {
sleep(POLL_TIME);
switch (adapter.getState()) {
- case BluetoothAdapter.STATE_OFF:
- assertFalse(adapter.isEnabled());
- continue;
case BluetoothAdapter.STATE_ON:
assertTrue(adapter.isEnabled());
return;
diff --git a/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java b/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
index 70443b0..9c13fe1 100644
--- a/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
@@ -22,6 +22,8 @@
import android.content.res.Configuration;
import android.os.Parcel;
import android.test.AndroidTestCase;
+import android.util.LocaleUtil;
+import android.view.View;
public class ConfigurationTest extends AndroidTestCase {
@@ -154,24 +156,29 @@
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC, mConfigDefault, config);
config.locale = Locale.getDefault();
+ config.setLayoutDirection(config.locale);
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
- | ActivityInfo.CONFIG_LOCALE, mConfigDefault, config);
+ | ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION, mConfigDefault, config);
config.screenLayout = 1;
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
| ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
| ActivityInfo.CONFIG_SCREEN_LAYOUT, mConfigDefault, config);
config.touchscreen = 1;
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
| ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
| ActivityInfo.CONFIG_SCREEN_LAYOUT
| ActivityInfo.CONFIG_TOUCHSCREEN, mConfigDefault, config);
config.keyboard = 1;
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
| ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
| ActivityInfo.CONFIG_SCREEN_LAYOUT
| ActivityInfo.CONFIG_TOUCHSCREEN
| ActivityInfo.CONFIG_KEYBOARD, mConfigDefault, config);
@@ -179,6 +186,7 @@
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
| ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
| ActivityInfo.CONFIG_SCREEN_LAYOUT
| ActivityInfo.CONFIG_TOUCHSCREEN
| ActivityInfo.CONFIG_KEYBOARD
@@ -188,6 +196,7 @@
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
| ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
| ActivityInfo.CONFIG_SCREEN_LAYOUT
| ActivityInfo.CONFIG_TOUCHSCREEN
| ActivityInfo.CONFIG_KEYBOARD
@@ -197,6 +206,7 @@
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
| ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
| ActivityInfo.CONFIG_SCREEN_LAYOUT
| ActivityInfo.CONFIG_TOUCHSCREEN
| ActivityInfo.CONFIG_KEYBOARD
@@ -205,6 +215,7 @@
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
| ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
| ActivityInfo.CONFIG_SCREEN_LAYOUT
| ActivityInfo.CONFIG_TOUCHSCREEN
| ActivityInfo.CONFIG_KEYBOARD
@@ -214,6 +225,7 @@
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
| ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
| ActivityInfo.CONFIG_SCREEN_LAYOUT
| ActivityInfo.CONFIG_TOUCHSCREEN
| ActivityInfo.CONFIG_KEYBOARD
@@ -224,6 +236,7 @@
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
| ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
| ActivityInfo.CONFIG_SCREEN_LAYOUT
| ActivityInfo.CONFIG_TOUCHSCREEN
| ActivityInfo.CONFIG_KEYBOARD
@@ -235,6 +248,7 @@
doConfigCompare(ActivityInfo.CONFIG_MCC
| ActivityInfo.CONFIG_MNC
| ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_LAYOUT_DIRECTION
| ActivityInfo.CONFIG_SCREEN_LAYOUT
| ActivityInfo.CONFIG_TOUCHSCREEN
| ActivityInfo.CONFIG_KEYBOARD
@@ -280,6 +294,62 @@
assertWriteToParcel(createConfig(Locale.JAPAN), Parcel.obtain());
}
+ public void testSetLocale() {
+ Configuration config = new Configuration();
+
+ config.setLocale(Locale.getDefault());
+ assertEquals(Locale.getDefault(), config.locale);
+ assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+ config.setLocale(Locale.ENGLISH);
+ assertEquals(Locale.ENGLISH, config.locale);
+ assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+ config.setLocale(Locale.US);
+ assertEquals(Locale.US, config.locale);
+ assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+ final Locale arEGLocale = new Locale("ar", "EG");
+ config.setLocale(arEGLocale);
+ assertEquals(arEGLocale, config.locale);
+ assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+ final Locale faFALocale = new Locale("fa", "FA");
+ config.setLocale(faFALocale);
+ assertEquals(faFALocale, config.locale);
+ assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+ final Locale iwILLocale = new Locale("iw", "IL");
+ config.setLocale(iwILLocale);
+ assertEquals(iwILLocale, config.locale);
+ assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+ }
+
+ public void testSetGetLayoutDirection() {
+ Configuration config = new Configuration();
+
+ config.setLayoutDirection(Locale.getDefault());
+ assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+ config.setLayoutDirection(Locale.ENGLISH);
+ assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+ config.setLayoutDirection(Locale.US);
+ assertEquals(View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+ final Locale arEGLocale = new Locale("ar", "EG");
+ config.setLayoutDirection(arEGLocale);
+ assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+ final Locale faFALocale = new Locale("fa", "FA");
+ config.setLayoutDirection(faFALocale);
+ assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+ final Locale iwILLocale = new Locale("iw", "IL");
+ config.setLayoutDirection(iwILLocale);
+ assertEquals(View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+ }
+
private Configuration createConfig(Locale locale) {
Configuration config = new Configuration();
config.fontScale = 13.37f;
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index bc9a822..75e90cf 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -535,6 +535,41 @@
assertEquals(Align.RIGHT, p.getTextAlign());
}
+ public void testAccessTextLocale() {
+ Paint p = new Paint();
+
+ final Locale defaultLocale = Locale.getDefault();
+
+ // Check default
+ assertEquals(defaultLocale, p.getTextLocale());
+
+ // Check setter / getter
+ p.setTextLocale(Locale.US);
+ assertEquals(Locale.US, p.getTextLocale());
+
+ p.setTextLocale(Locale.CHINESE);
+ assertEquals(Locale.CHINESE, p.getTextLocale());
+
+ p.setTextLocale(Locale.JAPANESE);
+ assertEquals(Locale.JAPANESE, p.getTextLocale());
+
+ p.setTextLocale(Locale.KOREAN);
+ assertEquals(Locale.KOREAN, p.getTextLocale());
+
+ // Check reverting back to default
+ p.setTextLocale(defaultLocale);
+ assertEquals(defaultLocale, p.getTextLocale());
+
+ // Check that we cannot pass a null locale
+ try {
+ p.setTextLocale(null);
+ assertFalse(true);
+ }
+ catch (IllegalArgumentException iae) {
+ // OK !!
+ }
+ }
+
public void testGetFillPath() {
Paint p = new Paint();
Path path1 = new Path();
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
index 33d81f3..5af5607 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
@@ -397,7 +397,7 @@
}
}
- private class MockCallback implements Drawable.Callback2 {
+ private class MockCallback implements Drawable.Callback {
private Drawable mInvalidateDrawable;
private Drawable mScheduleDrawable;
private Runnable mRunnable;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
index d2c2244..0672db6 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
@@ -943,7 +943,7 @@
}
}
- private class MockCallBack implements Drawable.Callback2 {
+ private class MockCallBack implements Drawable.Callback {
private boolean mCalledInvalidateDrawable;
private boolean mCalledScheduleDrawable;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
index f14f59f..df29211 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
@@ -567,17 +567,6 @@
assertSame(mockDrawable, mockDrawable.mutate());
}
- public void getResolvedLayoutDirectionSelf() {
- MockDrawable mockDrawable = new MockDrawable();
- MockCallback mockCallback = new MockCallback(1);
- mockDrawable.setCallback(mockCallback);
- assertEquals(1, mockDrawable.getResolvedLayoutDirectionSelf());
-
- mockCallback = new MockCallback(0);
- mockDrawable.setCallback(mockCallback);
- assertEquals(0, mockDrawable.getResolvedLayoutDirectionSelf());
- }
-
private static class MockDrawable extends Drawable {
private ColorFilter mColorFilter;
@@ -612,20 +601,13 @@
}
}
- private static class MockCallback implements Drawable.Callback2 {
+ private static class MockCallback implements Drawable.Callback {
private Drawable mInvalidateDrawable;
private Drawable mScheduleDrawable;
private Runnable mRunnable;
private long mWhen;
- private int mLayoutDirection;
public MockCallback() {
- // 0 for LTR layout direction
- this(0);
- }
-
- public MockCallback(int direction) {
- mLayoutDirection = direction;
}
public Drawable getInvalidateDrawable() {
@@ -658,9 +640,5 @@
mScheduleDrawable = who;
mRunnable = what;
}
-
- public int getResolvedLayoutDirection(Drawable who) {
- return mLayoutDirection;
- }
}
}
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
index bf688d2..4e4648f 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
@@ -335,7 +335,7 @@
assertFalse(cb.hasCalledUnschedule());
}
- private static class MockCallback implements Drawable.Callback2 {
+ private static class MockCallback implements Drawable.Callback {
private boolean mCalledInvalidate;
private boolean mCalledSchedule;
private boolean mCalledUnschedule;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java
index 75838e0..a3398f6 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/RotateDrawableTest.java
@@ -231,7 +231,7 @@
assertEquals(50, ((BitmapDrawable) d3.getDrawable()).getPaint().getAlpha());
}
- private static class MockCallback implements Drawable.Callback2 {
+ private static class MockCallback implements Drawable.Callback {
private boolean mCalledInvalidate;
private boolean mCalledSchedule;
private boolean mCalledUnschedule;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
index 305f32d..e0cd2ee 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
@@ -114,7 +114,7 @@
assertFalse(cb.hasCalledUnschedule());
}
- private static class MockCallback implements Drawable.Callback2 {
+ private static class MockCallback implements Drawable.Callback {
private boolean mCalledInvalidate;
private boolean mCalledSchedule;
private boolean mCalledUnschedule;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java
index aeb21cf..25b08d5 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/TransitionDrawableTest.java
@@ -242,7 +242,7 @@
}
}
- private class MockCallBack implements Drawable.Callback2 {
+ private class MockCallBack implements Drawable.Callback {
private boolean mHasCalledInvalidateDrawable;
public boolean hasCalledInvalidateDrawable() {
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
index d0a2bf0..440d054 100755
--- a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
@@ -2754,4 +2754,63 @@
}
terminateMessageLooper();
}
+
+ public void testPreviewCallbackWithPicture() throws Exception {
+ int nCameras = Camera.getNumberOfCameras();
+ for (int id = 0; id < nCameras; id++) {
+ Log.v(TAG, "Camera id=" + id);
+ testPreviewCallbackWithPictureByCamera(id);
+ }
+ }
+
+ private void testPreviewCallbackWithPictureByCamera(int cameraId)
+ throws Exception {
+ initializeMessageLooper(cameraId);
+
+ SimplePreviewStreamCb callback = new SimplePreviewStreamCb(1);
+ mCamera.setPreviewCallback(callback);
+
+ Log.v(TAG, "Starting preview");
+ mCamera.startPreview();
+
+ // Wait until callbacks are flowing
+ for (int i = 0; i < 30; i++) {
+ assertTrue("testPreviewCallbackWithPicture: Not receiving preview callbacks!",
+ mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE ) );
+ mPreviewDone.close();
+ }
+
+ // Now take a picture
+ Log.v(TAG, "Taking picture now");
+
+ Size pictureSize = mCamera.getParameters().getPictureSize();
+ mCamera.takePicture(mShutterCallback, mRawPictureCallback,
+ mJpegPictureCallback);
+
+ waitForSnapshotDone();
+
+ assertTrue("Shutter callback not received", mShutterCallbackResult);
+ assertTrue("Raw picture callback not received", mRawPictureCallbackResult);
+ assertTrue("Jpeg picture callback not received", mJpegPictureCallbackResult);
+ assertNotNull(mJpegData);
+ BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
+ bmpOptions.inJustDecodeBounds = true;
+ BitmapFactory.decodeByteArray(mJpegData, 0, mJpegData.length, bmpOptions);
+ assertEquals(pictureSize.width, bmpOptions.outWidth);
+ assertEquals(pictureSize.height, bmpOptions.outHeight);
+
+ // Restart preview, confirm callbacks still happen
+ Log.v(TAG, "Restarting preview");
+ mCamera.startPreview();
+
+ for (int i = 0; i < 30; i++) {
+ assertTrue("testPreviewCallbackWithPicture: Not receiving preview callbacks!",
+ mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE ) );
+ mPreviewDone.close();
+ }
+
+ mCamera.stopPreview();
+
+ terminateMessageLooper();
+ }
}
diff --git a/tests/tests/holo/res/drawable-hdpi/display_info.png b/tests/tests/holo/res/drawable-hdpi/display_info.png
deleted file mode 100644
index 10b3950..0000000
--- a/tests/tests/holo/res/drawable-hdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-land-hdpi/display_info.png b/tests/tests/holo/res/drawable-land-hdpi/display_info.png
deleted file mode 100644
index a665018..0000000
--- a/tests/tests/holo/res/drawable-land-hdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-land-ldpi/display_info.png b/tests/tests/holo/res/drawable-land-ldpi/display_info.png
deleted file mode 100644
index 64c8f3a..0000000
--- a/tests/tests/holo/res/drawable-land-ldpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-land-mdpi/display_info.png b/tests/tests/holo/res/drawable-land-mdpi/display_info.png
deleted file mode 100644
index f3e6765..0000000
--- a/tests/tests/holo/res/drawable-land-mdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-land-tvdpi/display_info.png b/tests/tests/holo/res/drawable-land-tvdpi/display_info.png
deleted file mode 100644
index 99de970..0000000
--- a/tests/tests/holo/res/drawable-land-tvdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-land-xhdpi/display_info.png b/tests/tests/holo/res/drawable-land-xhdpi/display_info.png
deleted file mode 100644
index 4c0c2b4..0000000
--- a/tests/tests/holo/res/drawable-land-xhdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-ldpi/display_info.png b/tests/tests/holo/res/drawable-ldpi/display_info.png
deleted file mode 100644
index af1fda5..0000000
--- a/tests/tests/holo/res/drawable-ldpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-mdpi/display_info.png b/tests/tests/holo/res/drawable-mdpi/display_info.png
deleted file mode 100644
index 4378b14..0000000
--- a/tests/tests/holo/res/drawable-mdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-hdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-hdpi/display_info.png
deleted file mode 100644
index 1e61b19..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-hdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-land-hdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-land-hdpi/display_info.png
deleted file mode 100644
index 123440e..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-land-hdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-land-ldpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-land-ldpi/display_info.png
deleted file mode 100644
index 7b8a0ad..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-land-ldpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-land-mdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-land-mdpi/display_info.png
deleted file mode 100644
index e285898..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-land-mdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-land-tvdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-land-tvdpi/display_info.png
deleted file mode 100644
index af4eaaa..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-land-tvdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-land-xhdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-land-xhdpi/display_info.png
deleted file mode 100644
index 995af67..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-land-xhdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-ldpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-ldpi/display_info.png
deleted file mode 100644
index 4d9d810..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-ldpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-mdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-mdpi/display_info.png
deleted file mode 100644
index b875d76..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-mdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-tvdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-tvdpi/display_info.png
deleted file mode 100644
index 6db0c61..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-tvdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-sw600dp-xhdpi/display_info.png b/tests/tests/holo/res/drawable-sw600dp-xhdpi/display_info.png
deleted file mode 100644
index 0ebb8c7..0000000
--- a/tests/tests/holo/res/drawable-sw600dp-xhdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-tvdpi/display_info.png b/tests/tests/holo/res/drawable-tvdpi/display_info.png
deleted file mode 100644
index d9825fb..0000000
--- a/tests/tests/holo/res/drawable-tvdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/drawable-xhdpi/display_info.png b/tests/tests/holo/res/drawable-xhdpi/display_info.png
deleted file mode 100644
index 585af2f..0000000
--- a/tests/tests/holo/res/drawable-xhdpi/display_info.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/holo/res/layout/display_info.xml b/tests/tests/holo/res/layout/display_info.xml
index 9804b8c..130ce1f 100644
--- a/tests/tests/holo/res/layout/display_info.xml
+++ b/tests/tests/holo/res/layout/display_info.xml
@@ -13,20 +13,8 @@
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:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- <ImageView
- android:src="@drawable/display_info"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <TextView
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
android:layout_width="fill_parent"
- android:layout_height="wrap_content"
+ android:layout_height="fill_parent"
/>
-</LinearLayout>
-
diff --git a/tests/tests/holo/res/values/strings.xml b/tests/tests/holo/res/values/strings.xml
index d2f6fd6..5eb7d82 100644
--- a/tests/tests/holo/res/values/strings.xml
+++ b/tests/tests/holo/res/values/strings.xml
@@ -24,7 +24,7 @@
<string name="task_clear_diff_bitmaps">Clear Diff Bitmaps</string>
<string name="display_info">Display Info</string>
- <string name="display_info_text">Density DPI: %1$d\nDensity Bucket: %2$s\nWidth DP: %3$d\nHeight DP: %4$d</string>
+ <string name="display_info_text">Density DPI: %1$d\nDensity Bucket: %2$s</string>
<string name="pick_theme">Pick Theme</string>
<string name="pick_layout">Pick Layout</string>
diff --git a/tests/tests/holo/src/android/holo/cts/DisplayInfoActivity.java b/tests/tests/holo/src/android/holo/cts/DisplayInfoActivity.java
index bdd7925..a11179a 100644
--- a/tests/tests/holo/src/android/holo/cts/DisplayInfoActivity.java
+++ b/tests/tests/holo/src/android/holo/cts/DisplayInfoActivity.java
@@ -37,13 +37,9 @@
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
- DisplayMetrics dm = getResources().getDisplayMetrics();
- int width = Math.round(dm.widthPixels / dm.density);
- int height = Math.round(dm.heightPixels / dm.density);
-
TextView text = (TextView) findViewById(R.id.text);
text.setText(getString(R.string.display_info_text, metrics.densityDpi,
- getScreenDensityBucket(metrics), width, height));
+ getScreenDensityBucket(metrics)));
}
private String getScreenDensityBucket(DisplayMetrics metrics) {
diff --git a/tests/tests/location/src/android/location/cts/LocationManagerTest.java b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
index 46e777f..0fc9b4d 100755
--- a/tests/tests/location/src/android/location/cts/LocationManagerTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
@@ -33,10 +33,10 @@
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Looper;
+import android.os.SystemClock;
import android.provider.Settings;
import android.test.InstrumentationTestCase;
-import java.lang.Thread;
import java.util.List;
import java.lang.Thread;
@@ -54,6 +54,8 @@
private static final String UNKNOWN_PROVIDER_NAME = "unknown_provider";
+ private static final String FUSED_PROVIDER_NAME = "fused";
+
private LocationManager mManager;
private Context mContext;
@@ -454,7 +456,7 @@
i.setAction("android.location.cts.TEST_GET_GPS_STATUS_ACTION");
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_ONE_SHOT);
- mManager.addProximityAlert(0, 0, 0, 5000, pi);
+ mManager.addProximityAlert(0, 0, 1.0f, 5000, pi);
mManager.removeProximityAlert(pi);
}
@@ -608,9 +610,6 @@
// now update to trigger exit proximity proximity
mIntentReceiver.clearReceivedIntents();
-
- // delay 2 seconds since location update in less than 1s will be neglected.
- Thread.sleep(2000);
updateLocation(20, 20);
waitForReceiveBroadcast();
assertProximityType(false);
@@ -623,12 +622,17 @@
* @param expiration - expiration of proximity alert
*/
private void doTestEnterProximity(long expiration) throws Exception {
+ // need to mock the fused location provider for proximity tests
+ mockFusedLocation();
+
// update location to outside proximity range
- updateLocation(30, 30);
+ updateLocation(FUSED_PROVIDER_NAME, 30, 30);
registerProximityListener(0, 0, 1000, expiration);
- updateLocation(0, 0);
+ updateLocation(FUSED_PROVIDER_NAME, 0, 0);
waitForReceiveBroadcast();
assertProximityType(true);
+
+ unmockFusedLocation();
}
private void registerIntentReceiver() {
@@ -679,8 +683,9 @@
Location location = new Location(providerName);
location.setLatitude(latitude);
location.setLongitude(longitude);
-
+ location.setAccuracy(1.0f);
location.setTime(java.lang.System.currentTimeMillis());
+ location.setElapsedRealtimeNano(SystemClock.elapsedRealtimeNano());
mManager.setTestProviderLocation(providerName, location);
}
@@ -688,6 +693,14 @@
updateLocation(TEST_MOCK_PROVIDER_NAME, latitude, longitude);
}
+ private void mockFusedLocation() {
+ addTestProvider(FUSED_PROVIDER_NAME);
+ }
+
+ private void unmockFusedLocation() {
+ mManager.removeTestProvider(FUSED_PROVIDER_NAME);
+ }
+
/**
* Helper class that receives a proximity intent and notifies the main class
* when received
diff --git a/tests/tests/media/res/raw/test_subtitle1_srt.3gp b/tests/tests/media/res/raw/test_subtitle1_srt.3gp
new file mode 100644
index 0000000..8dbc240
--- /dev/null
+++ b/tests/tests/media/res/raw/test_subtitle1_srt.3gp
@@ -0,0 +1,39 @@
+1
+00:00:0,000 --> 00:00:0,500
+2:0000
+
+2
+00:00:1,000 --> 00:00:1,500
+2:1000
+
+3
+00:00:2,000 --> 00:00:2,500
+2:2000
+
+4
+00:00:3,000 --> 00:00:3,500
+2:3000
+
+5
+00:00:4,000 --> 00:00:4,500
+2:4000
+
+6
+00:00:5,000 --> 00:00:5,500
+2:5000
+
+7
+00:00:6,000 --> 00:00:6,500
+2:6000
+
+8
+00:00:7,000 --> 00:00:7,500
+2:7000
+
+9
+00:00:8,000 --> 00:00:8,500
+2:8000
+
+10
+00:00:9,000 --> 00:00:9,500
+2:9000
diff --git a/tests/tests/media/res/raw/test_subtitle2_srt.3gp b/tests/tests/media/res/raw/test_subtitle2_srt.3gp
new file mode 100644
index 0000000..7ac2e72
--- /dev/null
+++ b/tests/tests/media/res/raw/test_subtitle2_srt.3gp
@@ -0,0 +1,39 @@
+1
+00:00:0,500 --> 00:00:1,000
+3:500
+
+2
+00:00:1,500 --> 00:00:2,000
+3:1500
+
+3
+00:00:2,500 --> 00:00:3,000
+3:2500
+
+4
+00:00:3,500 --> 00:00:4,000
+3:3500
+
+5
+00:00:4,500 --> 00:00:5,000
+3:4500
+
+6
+00:00:5,500 --> 00:00:6,000
+3:5500
+
+7
+00:00:6,500 --> 00:00:7,000
+3:6500
+
+8
+00:00:7,500 --> 00:00:8,000
+3:7500
+
+9
+00:00:8,500 --> 00:00:9,000
+3:8500
+
+10
+00:00:9,500 --> 00:00:10,000
+3:9500
diff --git a/tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp b/tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp
new file mode 100644
index 0000000..1de14a5
--- /dev/null
+++ b/tests/tests/media/res/raw/testvideo_with_2_subtitles.3gp
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index f85375d..94fc008 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -22,6 +22,8 @@
import android.test.AndroidTestCase;
import android.util.Log;
+import java.nio.ByteBuffer;
+
public class AudioTrackTest extends AndroidTestCase {
private String TAG = "AudioTrackTest";
private final long WAIT_MSEC = 200;
@@ -1314,6 +1316,27 @@
track.release();
}
+ public void testResourceLeakage() throws Exception {
+ final int BUFFER_SIZE = 600 * 1024;
+ ByteBuffer data = ByteBuffer.allocate(BUFFER_SIZE);
+ for (int i = 0; i < 10; i++) {
+ Log.i(TAG, "testResourceLeakage round " + i);
+ data.rewind();
+ AudioTrack track = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
+ 44100,
+ AudioFormat.CHANNEL_OUT_STEREO,
+ AudioFormat.ENCODING_PCM_16BIT,
+ data.capacity(),
+ AudioTrack.MODE_STREAM);
+ assertTrue(track != null);
+ track.write(data.array(), 0, data.capacity());
+ track.play();
+ Thread.sleep(100);
+ track.stop();
+ track.release();
+ }
+ }
+
private class MockAudioTrack extends AudioTrack {
public MockAudioTrack(int streamType, int sampleRateInHz, int channelConfig,
diff --git a/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java b/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
index 3f28218..1df5011 100644
--- a/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
+++ b/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
@@ -266,6 +266,7 @@
return true;
}
}
+ Log.e(TAG, "Size (" + width + "x" + height + ") is not supported");
return false;
}
}
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 0c39531..4e78805 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -23,15 +23,20 @@
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
+import android.media.MediaMetadataRetriever;
+import android.media.TimedText;
import android.media.audiofx.AudioEffect;
import android.media.audiofx.Visualizer;
import android.net.Uri;
import android.os.Environment;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.util.Log;
import java.io.File;
+import java.util.StringTokenizer;
import java.util.UUID;
+import java.util.Vector;
import java.util.concurrent.CountDownLatch;
/**
@@ -44,10 +49,63 @@
public class MediaPlayerTest extends MediaPlayerTestBase {
private String RECORDED_FILE;
+ private static final String LOG_TAG = "MediaPlayerTest";
private static final int RECORDED_VIDEO_WIDTH = 176;
private static final int RECORDED_VIDEO_HEIGHT = 144;
private static final long RECORDED_DURATION_MS = 3000;
+ private Vector<Integer> mTimedTextTrackIndex = new Vector<Integer>();
+
+ public class SubtitleMonitor {
+ private int selectedTrack;
+ private int numSignal;
+
+ public synchronized void reset() {
+ selectedTrack = 0;
+ numSignal = 0;
+ }
+
+ public synchronized void setSelectedTrack(int index) {
+ selectedTrack = index;
+ }
+
+ public synchronized int getSelectedTrack() {
+ return selectedTrack;
+ }
+
+ public synchronized void signal() {
+ numSignal++;
+ notifyAll();
+ }
+
+ public synchronized int getNumSignal() {
+ return numSignal;
+ }
+
+ public synchronized void waitForSignal(int targetCount) throws InterruptedException {
+ while (numSignal < targetCount) {
+ wait();
+ }
+ }
+
+ public synchronized void waitForSignal(int targetCount, long millis)
+ throws InterruptedException {
+ if (millis == 0) {
+ waitForSignal(targetCount);
+ return;
+ }
+ long deadline = System.currentTimeMillis() + millis;
+ while (numSignal < targetCount) {
+ long delay = deadline - System.currentTimeMillis();
+ if (delay < 0) {
+ return;
+ }
+ wait(delay);
+ }
+ }
+ }
+
+ private SubtitleMonitor mSubtitleStatus = new SubtitleMonitor();
private File mOutFile;
@@ -412,6 +470,7 @@
checkOrientation(angle);
recordVideo(width, height, angle, file, durationMs);
checkDisplayedVideoSize(width, height, angle, file);
+ checkVideoRotationAngle(angle, file);
}
private void checkOrientation(int angle) throws Exception {
@@ -453,6 +512,17 @@
playVideoTest(file, displayWidth, displayHeight);
}
+ private void checkVideoRotationAngle(int angle, String file) {
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ retriever.setDataSource(file);
+ String rotation = retriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
+ retriever.release();
+ retriever = null;
+ assertNotNull(rotation);
+ assertEquals(Integer.parseInt(rotation), angle);
+ }
+
public void testLocalVideo_MP4_H264_480x360_500kbps_25fps_AAC_Stereo_128kbps_44110Hz()
throws Exception {
playVideoTest(
@@ -639,6 +709,100 @@
R.raw.video_176x144_3gp_h263_300kbps_25fps_aac_stereo_128kbps_22050hz, 176, 144);
}
+ private void readTimedTextTracks() throws Exception {
+ mTimedTextTrackIndex.clear();
+ MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
+ if (trackInfos == null || trackInfos.length == 0) {
+ return;
+ }
+ for (int i = 0; i < trackInfos.length; ++i) {
+ if (trackInfos[i] == null) continue;
+ if (trackInfos[i].getTrackType() ==
+ MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
+ mTimedTextTrackIndex.add(i);
+ }
+ }
+ }
+
+ private int getTimedTextTrackCount() {
+ return mTimedTextTrackIndex.size();
+ }
+
+ private void selectSubtitleTrack(int index) throws Exception {
+ int trackIndex = mTimedTextTrackIndex.get(index);
+ mMediaPlayer.selectTrack(trackIndex);
+ mSubtitleStatus.setSelectedTrack(index);
+ }
+
+ public void testChangeSubtitleTrack() throws Exception {
+ loadResource(R.raw.testvideo_with_2_subtitles);
+ readTimedTextTracks();
+ assertEquals(getTimedTextTrackCount(), 2);
+
+ // Adds two more external subtitle files.
+ loadSubtitleSource(R.raw.test_subtitle1_srt);
+ loadSubtitleSource(R.raw.test_subtitle2_srt);
+ readTimedTextTracks();
+ assertEquals(getTimedTextTrackCount(), 4);
+
+ mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
+ mMediaPlayer.setScreenOnWhilePlaying(true);
+ mMediaPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+ mMediaPlayer.setOnTimedTextListener(new MediaPlayer.OnTimedTextListener() {
+ @Override
+ public void onTimedText(MediaPlayer mp, TimedText text) {
+ final int toleranceMs = 100;
+ final int durationMs = 500;
+ int posMs = mMediaPlayer.getCurrentPosition();
+ if (text != null) {
+ String plainText = text.getText();
+ if (plainText != null) {
+ StringTokenizer tokens = new StringTokenizer(plainText.trim(), ":");
+ int subtitleTrackIndex = Integer.parseInt(tokens.nextToken());
+ int startMs = Integer.parseInt(tokens.nextToken());
+ Log.w(LOG_TAG, "text: " + plainText.trim() +
+ ", trackId: " + subtitleTrackIndex + ", posMs: " + posMs);
+ assertTrue(posMs >= startMs - toleranceMs);
+ assertTrue(posMs < startMs + durationMs + toleranceMs);
+ assertEquals(mSubtitleStatus.getSelectedTrack(), subtitleTrackIndex);
+ mSubtitleStatus.signal();
+ }
+ }
+ }
+ });
+
+ mMediaPlayer.prepare();
+ assertFalse(mMediaPlayer.isPlaying());
+
+ mSubtitleStatus.reset();
+ selectSubtitleTrack(0);
+
+ mMediaPlayer.start();
+ assertTrue(mMediaPlayer.isPlaying());
+
+ // Waits until at least two subtitles are fired. Timeout is 2 sec.
+ // Please refer the test srt files:
+ // test_subtitle1_srt.3gp and test_subtitle2_srt.3gp
+ mSubtitleStatus.waitForSignal(2, 2000);
+ assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+ mSubtitleStatus.reset();
+
+ selectSubtitleTrack(1);
+ mSubtitleStatus.waitForSignal(2, 2000);
+ assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+ mSubtitleStatus.reset();
+
+ selectSubtitleTrack(2);
+ mSubtitleStatus.waitForSignal(2, 2000);
+ assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+ mSubtitleStatus.reset();
+
+ selectSubtitleTrack(3);
+ mSubtitleStatus.waitForSignal(2, 2000);
+ assertTrue(mSubtitleStatus.getNumSignal() >= 2);
+ mMediaPlayer.stop();
+ }
+
public void testCallback() throws Throwable {
final int mp4Duration = 8484;
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
index 8b9da47..203afc2 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
@@ -33,6 +33,7 @@
protected static final int SLEEP_TIME = 1000;
protected static final int LONG_SLEEP_TIME = 6000;
protected static final int STREAM_RETRIES = 20;
+ protected static boolean sUseScaleToFitMode = false;
public static class Monitor {
private boolean signalled;
@@ -74,6 +75,7 @@
}
protected Monitor mOnVideoSizeChangedCalled = new Monitor();
+ protected Monitor mOnVideoRenderingStartCalled = new Monitor();
protected Monitor mOnBufferingUpdateCalled = new Monitor();
protected Monitor mOnPrepareCalled = new Monitor();
protected Monitor mOnSeekCompleteCalled = new Monitor();
@@ -132,6 +134,25 @@
try {
mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
afd.getLength());
+
+ // Although it is only meant for video playback, it should not
+ // cause issues for audio-only playback.
+ int videoScalingMode = sUseScaleToFitMode?
+ MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT
+ : MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING;
+
+ mMediaPlayer.setVideoScalingMode(videoScalingMode);
+ } finally {
+ afd.close();
+ }
+ sUseScaleToFitMode = !sUseScaleToFitMode; // Alternate the scaling mode
+ }
+
+ protected void loadSubtitleSource(int resid) throws Exception {
+ AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
+ try {
+ mMediaPlayer.addTimedTextSource(afd.getFileDescriptor(), afd.getStartOffset(),
+ afd.getLength(), MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP);
} finally {
afd.close();
}
@@ -209,6 +230,15 @@
return true;
}
});
+ mMediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
+ @Override
+ public boolean onInfo(MediaPlayer mp, int what, int extra) {
+ if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
+ mOnVideoRenderingStartCalled.signal();
+ }
+ return true;
+ }
+ });
try {
mMediaPlayer.prepare();
} catch (IOException e) {
@@ -218,6 +248,7 @@
mMediaPlayer.start();
mOnVideoSizeChangedCalled.waitForSignal();
+ mOnVideoRenderingStartCalled.waitForSignal();
mMediaPlayer.setVolume(leftVolume, rightVolume);
// waiting to complete
diff --git a/tests/tests/media/src/android/media/cts/MediaRandomTest.java b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
new file mode 100644
index 0000000..adee09d
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
@@ -0,0 +1,347 @@
+/*
+ * 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.media.MediaRecorder;
+import android.media.MediaPlayer;
+import android.view.SurfaceHolder;
+import android.test.ActivityInstrumentationTestCase2;
+import android.os.Environment;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.util.Log;
+
+import java.util.Random;
+
+/**
+ * Tests for the MediaPlayer.java and MediaRecorder.java APIs
+ *
+ * These testcases make randomized calls to the public APIs available, and
+ * the focus is on whether the randomized calls can lead to crash in
+ * mediaserver process and/or ANRs.
+ *
+ * The files in res/raw used by testLocalVideo* are (c) copyright 2008,
+ * Blender Foundation / www.bigbuckbunny.org, and are licensed under the Creative Commons
+ * Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
+ */
+public class MediaRandomTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
+ private static final String TAG = "MediaRandomTest";
+
+ private static final String OUTPUT_FILE =
+ Environment.getExternalStorageDirectory().toString() + "/record.3gp";
+
+ private static final int NUMBER_OF_RECORDER_RANDOM_ACTIONS = 100000;
+ private static final int NUMBER_OF_PLAYER_RANDOM_ACTIONS = 100000;
+
+ private MediaRecorder mRecorder;
+ private MediaPlayer mPlayer;
+ private SurfaceHolder mSurfaceHolder;
+ private Resources mResources;
+
+ // Modified across multiple threads
+ private volatile boolean mMediaServerDied;
+ private volatile int mAction;
+ private volatile int mParam;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ getInstrumentation().waitForIdleSync();
+ mMediaServerDied = false;
+ mSurfaceHolder = getActivity().getSurfaceHolder();
+ mResources = getInstrumentation().getTargetContext().getResources();
+ try {
+ // Running this on UI thread make sure that
+ // onError callback can be received.
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ mRecorder = new MediaRecorder();
+ mPlayer = new MediaPlayer();
+ }
+ });
+ } catch (Throwable e) {
+ e.printStackTrace();
+ fail();
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (mRecorder != null) {
+ mRecorder.release();
+ mRecorder = null;
+ }
+ if (mPlayer != null) {
+ mPlayer.release();
+ mPlayer = null;
+ }
+ super.tearDown();
+ }
+
+ /**
+ * This is a watchdog used to stop the process if it hasn't been pinged
+ * for more than specified milli-seconds. It is used like:
+ *
+ * Watchdog w = new Watchdog(10000); // 10 seconds.
+ * w.start(); // start the watchdog.
+ * ...
+ * w.ping();
+ * ...
+ * w.ping();
+ * ...
+ * w.end(); // ask the watchdog to stop.
+ * w.join(); // join the thread.
+ */
+ class Watchdog extends Thread {
+ private final long mTimeoutMs;
+ private boolean mWatchdogStop;
+ private boolean mWatchdogPinged;
+
+ public Watchdog(long timeoutMs) {
+ mTimeoutMs = timeoutMs;
+ mWatchdogStop = false;
+ mWatchdogPinged = false;
+ }
+
+ public synchronized void run() {
+ while (true) {
+ // avoid early termination by "spurious" waitup.
+ final long startTimeMs = System.currentTimeMillis();
+ long remainingWaitTimeMs = mTimeoutMs;
+ do {
+ try {
+ wait(remainingWaitTimeMs);
+ } catch (InterruptedException ex) {
+ // ignore.
+ }
+ remainingWaitTimeMs = mTimeoutMs - (System.currentTimeMillis() - startTimeMs);
+ } while (remainingWaitTimeMs > 0);
+
+ if (mWatchdogStop) {
+ break;
+ }
+
+ if (!mWatchdogPinged) {
+ fail("Action " + mAction + " Param " + mParam
+ + " waited over " + (mTimeoutMs - remainingWaitTimeMs) + " ms");
+ return;
+ }
+ mWatchdogPinged = false;
+ }
+ }
+
+ public synchronized void ping() {
+ mWatchdogPinged = true;
+ this.notify();
+ }
+
+ public synchronized void end() {
+ mWatchdogStop = true;
+ this.notify();
+ }
+ }
+
+ public MediaRandomTest() {
+ super("com.android.cts.media", MediaStubActivity.class);
+ }
+
+ private void loadSource(int resid) throws Exception {
+ AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
+ try {
+ mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
+ afd.getLength());
+ } finally {
+ afd.close();
+ }
+ }
+
+ public void testPlayerRandomAction() throws Exception {
+ try {
+ mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+ @Override
+ public boolean onError(MediaPlayer mp, int what, int extra) {
+ if (mPlayer == mp &&
+ what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
+ Log.e(TAG, "mediaserver process died");
+ mMediaServerDied = true;
+ }
+ return true;
+ }
+ });
+ loadSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
+ mPlayer.setDisplay(mSurfaceHolder);
+ mPlayer.prepare();
+ mPlayer.start();
+
+ long seed = System.currentTimeMillis();
+ Log.v(TAG, "seed = " + seed);
+ Random r = new Random(seed);
+
+ Watchdog watchdog = new Watchdog(5000);
+ watchdog.start();
+ for (int i = 0; i < NUMBER_OF_PLAYER_RANDOM_ACTIONS; i++){
+ watchdog.ping();
+ assertTrue(!mMediaServerDied);
+
+ mAction = (int)(r.nextInt() % 12);
+ mParam = (int)(r.nextInt() % 1000000);
+ try {
+ switch (mAction) {
+ case 0:
+ mPlayer.getCurrentPosition();
+ break;
+ case 1:
+ mPlayer.getDuration();
+ break;
+ case 2:
+ mPlayer.getVideoHeight();
+ break;
+ case 3:
+ mPlayer.getVideoWidth();
+ break;
+ case 4:
+ mPlayer.isPlaying();
+ break;
+ case 5:
+ mPlayer.pause();
+ break;
+ case 6:
+ // Don't add mPlayer.prepare() call here for two reasons:
+ // 1. calling prepare() is a bad idea since it is a blocking call, and
+ // 2. when prepare() is in progress, mediaserver died message will not be sent to apps
+ mPlayer.prepareAsync();
+ break;
+ case 7:
+ mPlayer.seekTo((int)(mParam));
+ break;
+ case 8:
+ mPlayer.setLooping(mParam % 2 == 0);
+ break;
+ case 9:
+ mPlayer.setVolume((mParam % 1000) / 500.0f,
+ (mParam / 1000) / 500.0f);
+ break;
+ case 10:
+ mPlayer.start();
+ break;
+ case 11:
+ Thread.sleep(mParam % 20);
+ break;
+ }
+ } catch (Exception e) {
+ }
+ }
+ mPlayer.stop();
+ watchdog.end();
+ watchdog.join();
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ }
+
+ public void testRecorderRandomAction() throws Exception {
+ try {
+ long seed = System.currentTimeMillis();
+ Log.v(TAG, "seed = " + seed);
+ Random r = new Random(seed);
+
+ mMediaServerDied = false;
+ mRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {
+ @Override
+ public void onError(MediaRecorder recorder, int what, int extra) {
+ if (mRecorder == recorder &&
+ what == MediaRecorder.MEDIA_ERROR_SERVER_DIED) {
+ Log.e(TAG, "mediaserver process died");
+ mMediaServerDied = true;
+ }
+ }
+ });
+
+ final int[] width = {176, 352, 320, 640, 1280, 1920};
+ final int[] height = {144, 288, 240, 480, 720, 1080};
+
+ Watchdog watchdog = new Watchdog(5000);
+ watchdog.start();
+ for (int i = 0; i < NUMBER_OF_RECORDER_RANDOM_ACTIONS; i++) {
+ watchdog.ping();
+ assertTrue(!mMediaServerDied);
+
+ mAction = (int)(r.nextInt(14));
+ mParam = (int)(r.nextInt(1000000));
+ try {
+ switch (mAction) {
+ case 0:
+ mRecorder.setAudioSource(mParam % 3);
+ break;
+ case 1:
+ // XXX:
+ // Fix gralloc source and change
+ // mRecorder.setVideoSource(mParam % 3);
+ mRecorder.setVideoSource(mParam % 2);
+ break;
+ case 2:
+ mRecorder.setOutputFormat(mParam % 5);
+ break;
+ case 3:
+ mRecorder.setAudioEncoder(mParam % 3);
+ break;
+ case 4:
+ mRecorder.setVideoEncoder(mParam % 5);
+ break;
+ case 5:
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+ break;
+ case 6:
+ int index = mParam % width.length;
+ mRecorder.setVideoSize(width[index], height[index]);
+ break;
+ case 7:
+ mRecorder.setVideoFrameRate(mParam % 40 - 5);
+ break;
+ case 8:
+ mRecorder.setOutputFile(OUTPUT_FILE);
+ break;
+ case 9:
+ mRecorder.prepare();
+ break;
+ case 10:
+ mRecorder.start();
+ break;
+ case 11:
+ Thread.sleep(mParam % 20);
+ break;
+ case 12:
+ mRecorder.stop();
+ break;
+ case 13:
+ mRecorder.reset();
+ break;
+ default:
+ break;
+ }
+ } catch (Exception e) {
+ }
+ }
+ watchdog.end();
+ watchdog.join();
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index 55be9ac..f31f552 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -18,11 +18,13 @@
import android.content.pm.PackageManager;
import android.hardware.Camera;
+import android.media.MediaMetadataRetriever;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.media.MediaRecorder.OnInfoListener;
import android.media.MediaMetadataRetriever;
import android.os.Environment;
+import android.os.ConditionVariable;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.view.Surface;
@@ -43,6 +45,7 @@
private final String OUTPUT_PATH2;
private static final float TOLERANCE = 0.0002f;
private static final int RECORD_TIME = 3000;
+ private static final int THREE_MINUTES = 180000;
private static final int VIDEO_WIDTH = 176;
private static final int VIDEO_HEIGHT = 144;
private static final int VIDEO_BIT_RATE_IN_BPS = 128000;
@@ -62,6 +65,8 @@
private MediaStubActivity mActivity = null;
private MediaRecorder mMediaRecorder;
+ private ConditionVariable mMaxDurationCond;
+ private ConditionVariable mMaxFileSizeCond;
public MediaRecorderTest() {
super("com.android.cts.media", MediaStubActivity.class);
@@ -97,10 +102,23 @@
mMediaRecorder = new MediaRecorder();
mOutFile = new File(OUTPUT_PATH);
mOutFile2 = new File(OUTPUT_PATH2);
+
+ mMaxDurationCond = new ConditionVariable();
+ mMaxFileSizeCond = new ConditionVariable();
+
mMediaRecorder.setOutputFile(OUTPUT_PATH);
mMediaRecorder.setOnInfoListener(new OnInfoListener() {
public void onInfo(MediaRecorder mr, int what, int extra) {
mOnInfoCalled = true;
+ if (what ==
+ MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
+ Log.v(TAG, "max duration reached");
+ mMaxDurationCond.open();
+ } else if (what ==
+ MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
+ Log.v(TAG, "max file size reached");
+ mMaxFileSizeCond.open();
+ }
}
});
mMediaRecorder.setOnErrorListener(new OnErrorListener() {
@@ -127,6 +145,10 @@
mCamera.release();
mCamera = null;
}
+ mMaxDurationCond.close();
+ mMaxDurationCond = null;
+ mMaxFileSizeCond.close();
+ mMaxFileSizeCond = null;
mActivity = null;
super.tearDown();
}
@@ -352,30 +374,74 @@
if (!hasMicrophone()) {
return;
}
+ testSetMaxDuration(20000, 1000);
+ }
+
+ private void testSetMaxDuration(long durationMs, long toleranceMs) throws Exception {
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- mMediaRecorder.setMaxDuration(0);
+ mMediaRecorder.setMaxDuration((int)durationMs);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.prepare();
mMediaRecorder.start();
- Thread.sleep(RECORD_TIME * 30);
+ long startTimeMs = System.currentTimeMillis();
+ if (!mMaxDurationCond.block(durationMs + toleranceMs)) {
+ fail("timed out waiting for MEDIA_RECORDER_INFO_MAX_DURATION_REACHED");
+ }
+ long endTimeMs = System.currentTimeMillis();
+ long actualDurationMs = endTimeMs - startTimeMs;
mMediaRecorder.stop();
- checkOutputExist();
+ checkRecordedTime(durationMs, actualDurationMs, toleranceMs);
+ }
+
+ private void checkRecordedTime(long expectedMs, long actualMs, long tolerance) {
+ assertEquals(expectedMs, actualMs, tolerance);
+ long actualFileDurationMs = getRecordedFileDurationMs(OUTPUT_PATH);
+ assertEquals(actualFileDurationMs, actualMs, tolerance);
+ }
+
+ private int getRecordedFileDurationMs(final String fileName) {
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ retriever.setDataSource(fileName);
+ String durationStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
+ assertNotNull(durationStr);
+ return Integer.parseInt(durationStr);
}
public void testSetMaxFileSize() throws Exception {
if (!hasMicrophone()) {
return;
}
+ testSetMaxFileSize(512 * 1024, 50 * 1024);
+ }
+
+ private void testSetMaxFileSize(
+ long fileSize, long tolerance) throws Exception {
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- mMediaRecorder.setMaxFileSize(0);
+ mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
+ mMediaRecorder.setVideoSize(VIDEO_WIDTH, VIDEO_HEIGHT);
+ mMediaRecorder.setVideoEncodingBitRate(256000);
+ mMediaRecorder.setPreviewDisplay(mActivity.getSurfaceHolder().getSurface());
+ mMediaRecorder.setMaxFileSize(fileSize);
mMediaRecorder.prepare();
mMediaRecorder.start();
- Thread.sleep(RECORD_TIME * 30);
+
+ // Recording a scene with moving objects would greatly help reduce
+ // the time for waiting.
+ if (!mMaxFileSizeCond.block(THREE_MINUTES)) {
+ fail("timed out waiting for MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED");
+ }
mMediaRecorder.stop();
- checkOutputExist();
+ checkOutputFileSize(OUTPUT_PATH, fileSize, tolerance);
+ }
+
+ private void checkOutputFileSize(final String fileName, long fileSize, long tolerance) {
+ assertTrue(mOutFile.exists());
+ assertEquals(fileSize, mOutFile.length(), tolerance);
+ assertTrue(mOutFile.delete());
}
public void testOnErrorListener() throws Exception {
diff --git a/tests/tests/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java b/tests/tests/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java
index b8d0ea4..590ce89 100644
--- a/tests/tests/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java
+++ b/tests/tests/net/src/android/net/cts/NetworkInfo_DetailedStateTest.java
@@ -37,7 +37,7 @@
public void testValues() {
DetailedState[] expected = DetailedState.values();
- assertEquals(12, expected.length);
+ assertEquals(13, expected.length);
assertEquals(DetailedState.IDLE, expected[0]);
assertEquals(DetailedState.SCANNING, expected[1]);
assertEquals(DetailedState.CONNECTING, expected[2]);
@@ -50,6 +50,7 @@
assertEquals(DetailedState.FAILED, expected[9]);
assertEquals(DetailedState.BLOCKED, expected[10]);
assertEquals(DetailedState.VERIFYING_POOR_LINK, expected[11]);
+ assertEquals(DetailedState.CAPTIVE_PORTAL_CHECK, expected[12]);
}
}
diff --git a/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java
index 26cfff8..c9b82ee 100644
--- a/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/ScanResultTest.java
@@ -26,6 +26,7 @@
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.test.AndroidTestCase;
+import android.util.Log;
public class ScanResultTest extends AndroidTestCase {
private static class MySync {
@@ -39,11 +40,14 @@
private static final int STATE_NULL = 0;
private static final int STATE_WIFI_CHANGING = 1;
private static final int STATE_WIFI_CHANGED = 2;
+ private static final int STATE_START_SCAN = 3;
+ private static final int STATE_SCAN_RESULTS_AVAILABLE = 4;
private static final String TAG = "WifiInfoTest";
private static final int TIMEOUT_MSEC = 6000;
private static final int WAIT_MSEC = 60;
- private static final int DURATION = 10000;
+ private static final int ENABLE_WAIT_MSEC = 10000;
+ private static final int SCAN_WAIT_MSEC = 10000;
private IntentFilter mIntentFilter;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -54,6 +58,11 @@
mMySync.expectedState = STATE_WIFI_CHANGED;
mMySync.notify();
}
+ } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+ synchronized (mMySync) {
+ mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE;
+ mMySync.notify();
+ }
}
}
};
@@ -83,7 +92,7 @@
mWifiLock.acquire();
if (!mWifiManager.isWifiEnabled())
setWifiEnabled(true);
- Thread.sleep(DURATION);
+ Thread.sleep(ENABLE_WAIT_MSEC);
assertTrue(mWifiManager.isWifiEnabled());
mMySync.expectedState = STATE_NULL;
}
@@ -99,7 +108,7 @@
mContext.unregisterReceiver(mReceiver);
if (!mWifiManager.isWifiEnabled())
setWifiEnabled(true);
- Thread.sleep(DURATION);
+ Thread.sleep(ENABLE_WAIT_MSEC);
super.tearDown();
}
@@ -107,11 +116,15 @@
synchronized (mMySync) {
mMySync.expectedState = STATE_WIFI_CHANGING;
assertTrue(mWifiManager.setWifiEnabled(enable));
- long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
- while (System.currentTimeMillis() < timeout
- && mMySync.expectedState == STATE_WIFI_CHANGING)
- mMySync.wait(WAIT_MSEC);
- }
+ waitForBroadcast(TIMEOUT_MSEC, STATE_WIFI_CHANGED);
+ }
+ }
+
+ private void waitForBroadcast(long timeout, int expectedState) throws Exception {
+ long waitTime = System.currentTimeMillis() + timeout;
+ while (System.currentTimeMillis() < waitTime
+ && mMySync.expectedState != expectedState)
+ mMySync.wait(WAIT_MSEC);
}
public void testScanResultProperties() {
@@ -127,4 +140,49 @@
}
}
+ private void scanAndWait() throws Exception {
+ synchronized (mMySync) {
+ mMySync.expectedState = STATE_START_SCAN;
+ mWifiManager.startScan();
+ waitForBroadcast(SCAN_WAIT_MSEC, STATE_SCAN_RESULTS_AVAILABLE);
+ }
+ }
+
+ public void testScanResultTimeStamp() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+
+ long timestamp = 0;
+ String BSSID = null;
+
+ /* Multiple scans to ensure bssid is updated */
+ scanAndWait();
+ scanAndWait();
+ scanAndWait();
+
+ List<ScanResult> scanResults = mWifiManager.getScanResults();
+ for (ScanResult result : scanResults) {
+ BSSID = result.BSSID;
+ timestamp = result.timestamp;
+ assertTrue(timestamp != 0);
+ break;
+ }
+
+ scanAndWait();
+ scanAndWait();
+ scanAndWait();
+
+ scanResults = mWifiManager.getScanResults();
+ for (ScanResult result : scanResults) {
+ if (result.BSSID.equals(BSSID)) {
+ long timeDiff = (result.timestamp - timestamp) / 1000;
+ assertTrue (timeDiff > 0);
+ assertTrue (timeDiff < 6 * SCAN_WAIT_MSEC);
+ }
+ }
+
+ }
+
}
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 5fc23e7..a64477d 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -21,17 +21,22 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
import android.net.wifi.WifiConfiguration.Status;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.TxPacketCountListener;
import android.net.wifi.WifiManager.WifiLock;
import android.test.AndroidTestCase;
import android.util.Log;
+import java.net.HttpURLConnection;
+import java.net.URL;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
public class WifiManagerTest extends AndroidTestCase {
private static class MySync {
@@ -42,6 +47,7 @@
private WifiLock mWifiLock;
private static MySync mMySync;
private List<ScanResult> mScanResult = null;
+ private NetworkInfo mNetworkInfo;
// Please refer to WifiManager
private static final int MIN_RSSI = -100;
@@ -78,6 +84,13 @@
mMySync.expectedState = STATE_WIFI_CHANGED;
mMySync.notify();
}
+ } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+ synchronized (mMySync) {
+ mNetworkInfo =
+ (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+ if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED)
+ mMySync.notify();
+ }
}
}
};
@@ -148,6 +161,18 @@
}
}
+ private void connectWifi() throws Exception {
+ synchronized (mMySync) {
+ if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED) return;
+ assertTrue(mWifiManager.reconnect());
+ long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+ while (System.currentTimeMillis() < timeout
+ && mNetworkInfo.getState() != NetworkInfo.State.CONNECTED)
+ mMySync.wait(WAIT_MSEC);
+ assertTrue(mNetworkInfo.getState() == NetworkInfo.State.CONNECTED);
+ }
+ }
+
private boolean existSSID(String ssid) {
for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) {
if (w.SSID.equals(ssid))
@@ -339,4 +364,65 @@
rssiB = 4;
assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) > 0);
}
+
+ private int getTxPacketCount() throws Exception {
+ final AtomicInteger ret = new AtomicInteger(-1);
+
+ mWifiManager.getTxPacketCount(new TxPacketCountListener() {
+ @Override
+ public void onSuccess(int count) {
+ ret.set(count);
+ }
+ @Override
+ public void onFailure(int reason) {
+ ret.set(0);
+ }
+ });
+
+ long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+ while (ret.get() < 0 && System.currentTimeMillis() < timeout)
+ Thread.sleep(WAIT_MSEC);
+ assertTrue(ret.get() >= 0);
+ return ret.get();
+ }
+
+ /**
+ * The new WiFi watchdog requires kernel/driver to export some packet loss
+ * counters. This CTS tests whether those counters are correctly exported.
+ * To pass this CTS test, a connected WiFi link is required.
+ */
+ public void testWifiWatchdog() throws Exception {
+ // Make sure WiFi is enabled
+ if (!mWifiManager.isWifiEnabled()) {
+ setWifiEnabled(true);
+ Thread.sleep(DURATION);
+ }
+ assertTrue(mWifiManager.isWifiEnabled());
+
+ // Wait for a WiFi connection
+ connectWifi();
+
+ // Read TX packet counter
+ int txcount1 = getTxPacketCount();
+
+ // Do some network operations
+ HttpURLConnection connection = null;
+ try {
+ URL url = new URL("http://www.google.com/");
+ connection = (HttpURLConnection) url.openConnection();
+ connection.setInstanceFollowRedirects(false);
+ connection.setConnectTimeout(TIMEOUT_MSEC);
+ connection.setReadTimeout(TIMEOUT_MSEC);
+ connection.setUseCaches(false);
+ connection.getInputStream();
+ } catch (Exception e) {
+ // ignore
+ } finally {
+ if (connection != null) connection.disconnect();
+ }
+
+ // Read TX packet counter again and make sure it increases
+ int txcount2 = getTxPacketCount();
+ assertTrue(txcount2 > txcount1);
+ }
}
diff --git a/tests/tests/opengl/Android.mk b/tests/tests/opengl/Android.mk
index 0610c5f..98f11e9 100644
--- a/tests/tests/opengl/Android.mk
+++ b/tests/tests/opengl/Android.mk
@@ -27,9 +27,9 @@
# All tests should include android.test.runner.
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_JNI_SHARED_LIBRARIES := libopengltest_jni
-LOCAL_JNI_SHARED_LIBRARIES := libopengltest
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/opengl/AndroidManifest.xml b/tests/tests/opengl/AndroidManifest.xml
index 4619512..266216f 100644
--- a/tests/tests/opengl/AndroidManifest.xml
+++ b/tests/tests/opengl/AndroidManifest.xml
@@ -31,15 +31,17 @@
<activity
android:label="@string/app_name"
android:name="android.opengl.cts.OpenGLES20ActivityOne">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
+ </activity>
+ <activity
+ android:label="@string/app_name"
+ android:name="android.opengl.cts.OpenGLES20ActivityTwo">
</activity>
<uses-library android:name="android.test.runner" />
<activity
- android:name="android.opengl.cts.OpenGLES20NativeActivity"
+ android:name="android.opengl.cts.OpenGLES20NativeActivityOne"
+ android:label="@string/app_name" />
+ <activity
+ android:name="android.opengl.cts.OpenGLES20NativeActivityTwo"
android:label="@string/app_name" />
</application>
diff --git a/tests/tests/opengl/libopengltest/Android.mk b/tests/tests/opengl/libopengltest/Android.mk
index a54816e..a141550 100755
--- a/tests/tests/opengl/libopengltest/Android.mk
+++ b/tests/tests/opengl/libopengltest/Android.mk
@@ -17,7 +17,7 @@
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE := libopengltest
+LOCAL_MODULE := libopengltest_jni
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := common.cpp \
gl2_jni_libone.cpp \
@@ -27,6 +27,12 @@
attach_shader_four.cpp \
attach_shader_five.cpp \
attach_shader_six.cpp \
+ attach_shader_seven.cpp \
+ attach_shader_eight.cpp \
+ attach_shader_nine.cpp \
+ attach_shader_ten.cpp \
+ attach_shader_eleven.cpp \
+ color_one.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
diff --git a/tests/tests/opengl/libopengltest/attach_shader_eight.cpp b/tests/tests/opengl/libopengltest/attach_shader_eight.cpp
new file mode 100755
index 0000000..180399b
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_eight.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "attach_shader_eight.h"
+
+#define LOG_TAG "attach_shader_eight"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+Data attachShaderEight(){
+ GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+
+ GLuint program = glCreateProgram();
+ glAttachShader(program, fragmentShader);
+
+ GLint error = glGetError();
+ Data data = {error, -9 , -1};
+ glDeleteShader(fragmentShader);
+ glDeleteProgram(program);
+ return data;
+}
diff --git a/tests/tests/opengl/libopengltest/attach_shader_eight.h b/tests/tests/opengl/libopengltest/attach_shader_eight.h
new file mode 100755
index 0000000..2f317e2
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_eight.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ATTACH_SHADER_EIGHT_H_
+#define _ATTACH_SHADER_EIGHT_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+Data attachShaderEight();
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/attach_shader_eleven.cpp b/tests/tests/opengl/libopengltest/attach_shader_eleven.cpp
new file mode 100755
index 0000000..597de83
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_eleven.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "attach_shader_eleven.h"
+#include "common.h"
+#include "vertex.h"
+
+#define LOG_TAG "attach_shader_eleven"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+Data attachShaderEleven(){
+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, attach_shader_successful_complile_vertex);
+ GLuint program = glCreateProgram();
+ glAttachShader(program, vertexShader);
+
+ GLsizei maxCount = 10;
+ GLsizei count;
+ GLuint shaders[maxCount];
+
+ glGetAttachedShaders(program, maxCount,
+ &count,
+ shaders);
+ LOGI("Attached Shader First element : %d\n", *shaders);
+ LOGI("ShaderCount %d\n", count);
+ GLint error = glGetError();
+ Data data = {error, count, -1};
+
+ glDeleteProgram(program);
+ return data;
+}
diff --git a/tests/tests/opengl/libopengltest/attach_shader_eleven.h b/tests/tests/opengl/libopengltest/attach_shader_eleven.h
new file mode 100755
index 0000000..5cb39c1
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_eleven.h
@@ -0,0 +1,29 @@
+/*
+ * 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 <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+#ifndef _ATTACH_SHADER_ELEVEN_H_
+#define _ATTACH_SHADER_ELEVEN_H_
+
+Data attachShaderEleven();
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/attach_shader_nine.cpp b/tests/tests/opengl/libopengltest/attach_shader_nine.cpp
new file mode 100755
index 0000000..154c351
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_nine.cpp
@@ -0,0 +1,35 @@
+/*
+ * 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 <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "attach_shader_nine.h"
+
+#define LOG_TAG "attach_shader_nine"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+Data attachShaderNine(){
+ GLuint fragmentShader = 0;
+ GLuint program = glCreateProgram();
+ glAttachShader(program, fragmentShader);
+
+ GLint error = glGetError();
+ Data data = {error, -9, -1};
+ glDeleteShader(fragmentShader);
+ glDeleteProgram(program);
+ return data;
+}
diff --git a/tests/tests/opengl/libopengltest/attach_shader_nine.h b/tests/tests/opengl/libopengltest/attach_shader_nine.h
new file mode 100755
index 0000000..e2ea44f
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_nine.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ATTACH_SHADER_NINE_H_
+#define _ATTACH_SHADER_NINE_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+Data attachShaderNine();
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/attach_shader_seven.cpp b/tests/tests/opengl/libopengltest/attach_shader_seven.cpp
new file mode 100755
index 0000000..f7e9c47
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_seven.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "attach_shader_seven.h"
+
+#define LOG_TAG "attach_shader_seven"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+Data attachShaderSeven(){
+ GLuint vertexShaderOne = glCreateShader(GL_VERTEX_SHADER);
+ GLuint vertexShaderTwo = glCreateShader(GL_VERTEX_SHADER);
+
+ GLuint program = glCreateProgram();
+ glAttachShader(program, vertexShaderOne);
+ glAttachShader(program, vertexShaderTwo);
+
+
+ GLint error = glGetError();
+ Data data = {error, -9 , -1};
+ glDeleteShader(vertexShaderOne);
+ glDeleteShader(vertexShaderTwo);
+ glDeleteProgram(program);
+ return data;
+}
diff --git a/tests/tests/opengl/libopengltest/attach_shader_seven.h b/tests/tests/opengl/libopengltest/attach_shader_seven.h
new file mode 100755
index 0000000..b13ac55
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_seven.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ATTACH_SHADER_SEVEN_H_
+#define _ATTACH_SHADER_SEVEN_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+Data attachShaderSeven();
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/attach_shader_ten.cpp b/tests/tests/opengl/libopengltest/attach_shader_ten.cpp
new file mode 100755
index 0000000..3bc197e
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_ten.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "attach_shader_ten.h"
+#include "common.h"
+#include "shader.h"
+#define LOG_TAG "attach_shader_ten"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+
+Data attachShaderTen(){
+ GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, attach_shader_successful_complile_shader);
+ GLuint program = glCreateProgram();
+ glAttachShader(program, fragmentShader);
+
+ GLsizei maxCount = 10;
+ GLsizei count;
+ GLuint shaders[maxCount];
+
+ glGetAttachedShaders(program, maxCount,
+ &count,
+ shaders);
+ LOGI("Attached Shader First element : %d\n", *shaders);
+ LOGI("ShaderCount %d\n", count);
+ GLint error = glGetError();
+ Data data = {error, count, -1};
+ glDeleteShader(fragmentShader);
+ glDeleteProgram(program);
+ return data;
+}
diff --git a/tests/tests/opengl/libopengltest/attach_shader_ten.h b/tests/tests/opengl/libopengltest/attach_shader_ten.h
new file mode 100755
index 0000000..9bb8d0b
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/attach_shader_ten.h
@@ -0,0 +1,29 @@
+/*
+ * 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 <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+#ifndef _ATTACH_SHADER_TEN_H_
+#define _ATTACH_SHADER_TEN_H_
+
+Data attachShaderTen();
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/color_one.cpp b/tests/tests/opengl/libopengltest/color_one.cpp
new file mode 100755
index 0000000..27d400c
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/color_one.cpp
@@ -0,0 +1,130 @@
+/*
+ * 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 <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "color_one.h"
+#include "common.h"
+#include "vertex.h"
+#include "shader.h"
+
+#define LOG_TAG "color_one"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+
+static const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f };
+GLuint gProgram;
+GLuint gvPositionHandle;
+GLuint gvColorHandle;
+int width;
+int height;
+
+float dataFloat[4];
+void initColorOne(int w, int h){
+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, color_one_vertex_shader_one);
+ GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, color_one_fragment_shader_one);
+ gProgram = glCreateProgram();
+ LOGI("Program %d\n", gProgram);
+ width = w;
+ height = h;
+ glAttachShader(gProgram, vertexShader);
+ checkGlError("glAttachShader");
+ glAttachShader(gProgram, fragmentShader);
+ checkGlError("glAttachShader");
+ glBindAttribLocation(gProgram, 0, "vPosition");
+ glBindAttribLocation(gProgram, 1, "vColor");
+ glLinkProgram(gProgram);
+ GLint linkStatus = GL_FALSE;
+ glGetProgramiv(gProgram, GL_LINK_STATUS, &linkStatus);
+ if (linkStatus != GL_TRUE) {
+ GLint bufLength = 0;
+ glGetProgramiv(gProgram, GL_INFO_LOG_LENGTH, &bufLength);
+ if (bufLength) {
+ char* buf = (char*) malloc(bufLength);
+ if (buf) {
+ glGetProgramInfoLog(gProgram, bufLength, NULL, buf);
+ LOGE("Could not link program:\n%s\n", buf);
+ free(buf);
+ }
+ }
+ }
+ LOGI("w %d, h %d\n",w, h);
+ glViewport(0, 0, w, h);
+
+ checkGlError("glViewport");
+ gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+ gvColorHandle = glGetAttribLocation(gProgram, "vColor");
+ GLsizei maxCount = 10;
+ GLsizei count;
+ GLuint shaders[maxCount];
+
+ glGetAttachedShaders(gProgram, maxCount,
+ &count,
+ shaders);
+ LOGI("Attached Shader First element : %d\n", *shaders);
+ LOGI("ShaderCount %d\n", count);
+ GLint error = glGetError();
+ return;
+}
+
+float* drawColorOne(float mColor[]){
+ LOGI("drawColorOne start");
+ static float grey;
+ grey = 0.01f;
+
+ glClearColor(grey, grey, grey, 1.0f);
+ checkGlError("glClearColor");
+ glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ checkGlError("glClear");
+
+ glUseProgram(gProgram);
+ checkGlError("glUseProgram");
+
+ glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+ checkGlError("glVertexAttribPointer");
+ glEnableVertexAttribArray(0);
+ checkGlError("glEnableVertexAttribArray");
+
+ glVertexAttribPointer(gvColorHandle,4, GL_FLOAT, GL_FALSE, 0, mColor);
+ checkGlError("glVertexAttribPointer");
+ glEnableVertexAttribArray(1);
+ checkGlError("glEnableVertexAttribArray");
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ checkGlError("glDrawArrays");
+ GLubyte data[4*1];
+
+
+ glReadPixels(width/2, height/2, 1,1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&data);
+ for(int i = 0; i < sizeof(data); i++){
+ dataFloat[i] = data[i];
+ }
+
+ return dataFloat;
+}
+
+void deleteColorOne() {
+ glDeleteProgram(gProgram);
+}
+
+static void checkGlError(const char* op) {
+ for (GLint error = glGetError(); error; error
+ = glGetError()) {
+ LOGI("after %s() glError (0x%x)\n", op, error);
+ }
+}
diff --git a/tests/tests/opengl/libopengltest/color_one.h b/tests/tests/opengl/libopengltest/color_one.h
new file mode 100755
index 0000000..21dd9fd
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/color_one.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#ifndef _COLOR_ONE_H_
+#define _COLOR_ONE_H_
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <android/log.h>
+#include "types.h"
+
+void initColorOne(int w,int h);
+float* drawColorOne(float color[]);
+
+static void checkGlError(const char* op);
+
+#endif
+
diff --git a/tests/tests/opengl/libopengltest/gl2_jni_libone.cpp b/tests/tests/opengl/libopengltest/gl2_jni_libone.cpp
index 9433702..fe49b1b 100755
--- a/tests/tests/opengl/libopengltest/gl2_jni_libone.cpp
+++ b/tests/tests/opengl/libopengltest/gl2_jni_libone.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-
#include <jni.h>
#include <android/log.h>
@@ -24,12 +23,19 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
+
#include "attach_shader_one.h"
#include "attach_shader_two.h"
#include "attach_shader_three.h"
#include "attach_shader_four.h"
#include "attach_shader_five.h"
#include "attach_shader_six.h"
+#include "attach_shader_seven.h"
+#include "attach_shader_eight.h"
+#include "attach_shader_nine.h"
+#include "attach_shader_ten.h"
+#include "attach_shader_eleven.h"
+#include "color_one.h"
#define LOG_TAG "gl2_jni_libone"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
@@ -40,7 +46,7 @@
extern "C" JNIEXPORT void JNICALL Java_android_opengl_cts_GL2JniLibOne_init
- (JNIEnv *, jclass pClass, jint pCategory, jint pSubCategory) {
+ (JNIEnv *, jclass pClass, jint pCategory, jint pSubCategory, jint width, jint height) {
LOGI("Category : %d\n", pCategory);
if(pCategory == 1) {
@@ -72,6 +78,34 @@
Data data = attachShaderSix();
LOGI("Attach Shader Error : %d\n", data.mShaderError);
errorAttachShader = data.mShaderError;
+ }else if(pSubCategory == 7) {
+ Data data = attachShaderSeven();
+ LOGI("Attach Shader Error : %d\n", data.mShaderError);
+ errorAttachShader = data.mShaderError;
+ }else if(pSubCategory == 8) {
+ Data data = attachShaderEight();
+ LOGI("Attach Shader Error : %d\n", data.mShaderError);
+ errorAttachShader = data.mShaderError;
+ }else if(pSubCategory == 9) {
+ Data data = attachShaderNine();
+ LOGI("Attach Shader Error : %d\n", data.mShaderError);
+ errorAttachShader = data.mShaderError;
+ }else if(pSubCategory == 10) {
+ Data data = attachShaderTen();
+ LOGI("Attach Shader Error : %d\n", data.mShaderError);
+ LOGI("Shader Count : %d\n", data.mShaderCount);
+ errorAttachShader = data.mShaderError;
+ shaderCount = data.mShaderCount;
+ }else if(pSubCategory == 11) {
+ Data data = attachShaderEleven();
+ LOGI("Attach Shader Error : %d\n", data.mShaderError);
+ LOGI("Shader Count : %d\n", data.mShaderCount);
+ errorAttachShader = data.mShaderError;
+ shaderCount = data.mShaderCount;
+ }
+ }else if(pCategory == 3){//Color Test
+ if(pSubCategory == 1){
+ initColorOne( width,height);
}
}
}
@@ -97,4 +131,23 @@
return shaderCount;
}
+extern "C" JNIEXPORT jfloatArray JNICALL Java_android_opengl_cts_GL2JniLibOne_draw(JNIEnv * env,
+ jclass obj, jint pCategory, jint pSubCategory, jfloatArray color)
+{
+ LOGI("Inside draw %d %d", pCategory, pSubCategory);
+ jfloatArray result;
+ if(pCategory == 3){
+ if(pSubCategory == 1){
+ result = env->NewFloatArray(4);
+ jfloat *lColor = env->GetFloatArrayElements(color,0);
+
+ float * actualColor = drawColorOne(lColor);
+ for( int i= 0; i < sizeof(actualColor); i++) {
+ LOGI("actualColor[%d] ; %f", i, actualColor[i]);
+ }
+ env->SetFloatArrayRegion(result, 0, 4, actualColor);
+ }
+ }
+ return result;
+}
diff --git a/tests/tests/opengl/libopengltest/shader.h b/tests/tests/opengl/libopengltest/shader.h
new file mode 100755
index 0000000..12131f1
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/shader.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _SHADER_H_
+#define _SHADER_H_
+
+static const char attach_shader_successful_complile_shader[] =
+ "attribute vec3 gtf_Normal;\n"
+ "attribute vec4 gtf_Vertex;\n"
+ "uniform mat3 gtf_NormalMatrix;\n"
+ "uniform mat4 gtf_ModelViewMatrix;\n"
+ "uniform mat4 gtf_ModelViewProjectionMatrix;\n"
+
+ "varying float lightIntensity;\n"
+ "varying vec3 Position;\n"
+ "uniform vec3 LightPosition;\n"
+ "uniform float Scale;\n"
+ "void main(void) {\n"
+ "vec4 pos = gtf_ModelViewMatrix * gtf_Vertex;\n"
+ "Position = vec3(gtf_Vertex) * Scale;\n"
+ "vec3 tnorm = normalize(gtf_NormalMatrix * gtf_Normal);\n"
+ "lightIntensity = dot(normalize(LightPosition - vec3(pos)), tnorm) * 1.5;\n"
+ "gl_Position = gtf_ModelViewProjectionMatrix * gtf_Vertex;\n";
+
+static const char color_one_fragment_shader_one[] =
+ "precision mediump float; \n"
+ "varying vec4 varyColor; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = varyColor; \n"
+ "} ";
+
+static const char color_one_fragment_shader[] =
+ "precision mediump float; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n"
+ "} ";
+
+#endif
diff --git a/tests/tests/opengl/libopengltest/vertex.h b/tests/tests/opengl/libopengltest/vertex.h
new file mode 100755
index 0000000..50a4c7a
--- /dev/null
+++ b/tests/tests/opengl/libopengltest/vertex.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+#ifndef _VERTEX_H_
+#define _VERTEX_H_
+
+static const char attach_shader_successful_complile_vertex[] =
+ "#ifdef GL_ES \n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "uniform float mortarThickness;\n"
+ "uniform vec3 brickColor;\n"
+ "uniform vec3 mortarColor;\n"
+ " \n"
+ "uniform float brickMortarWidth;\n"
+ "uniform float brickMortarHeight;\n"
+ "uniform float mwf; \n"
+ "uniform float mhf; \n"
+ ""
+ "varying vec3 Position; \n"
+ "varying float lightIntensity; \n"
+ " \n"
+ "void main (void) \n"
+ "{\n"
+ " vec3 ct; \n"
+ " float ss, tt, w, h; \n"
+ " \n"
+ " vec3 pos = Position; \n"
+ ""
+ " ss = pos.x / brickMortarWidth; \n"
+ " tt = pos.z / brickMortarHeight; \n"
+ ""
+ " if (fract (tt * 0.5) > 0.5) \n"
+ " ss += 0.5; \n"
+ ""
+ " ss = fract (ss); \n"
+ " tt = fract (tt); \n"
+
+ " w = step (mwf, ss) - step (1.0 - mwf, ss); \n"
+ " h = step (mhf, tt) - step (1.0 - mhf, tt); \n"
+ ""
+ " ct = clamp(mix (mortarColor, brickColor, w * h) * lightIntensity, 0.0, 1.0); \n"
+ ""
+ " gl_FragColor = vec4 (ct, 1.0); \n"
+ "} \n";
+
+static const char color_one_vertex_shader_one[] =
+ "attribute vec4 vPosition; \n"
+ "attribute vec4 vColor; \n"
+ "varying vec4 varyColor; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = vPosition; \n"
+ " varyColor = vColor; \n"
+ "} \n";
+
+static const char color_one_vertex_shader[] =
+ "attribute vec4 vPosition; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = vPosition; \n"
+ "} \n";
+
+#endif
diff --git a/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java
index 21efd6f..62ca1f9 100644
--- a/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java
@@ -29,8 +29,8 @@
private OpenGLES20ActivityOne getShaderActivity(int viewType, int viewIndex) {
Intent intent = new Intent();
- intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_TYPE, viewType);
- intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_INDEX, viewIndex);
+ intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_TYPE, viewType);
+ intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_INDEX, viewIndex);
setActivityIntent(intent);
OpenGLES20ActivityOne activity = getActivity();
assertTrue(activity.waitForFrameDrawn());
@@ -133,4 +133,16 @@
int error = mActivity.glGetError();
assertEquals(GLES20.GL_NO_ERROR, error);
}
+
+ public void test_glAttachShaders_successfulcompile_attach_vert() throws Throwable {
+ mActivity = getShaderActivity(Constants.SHADER, 11);
+ int error = mActivity.glGetError();
+ assertEquals(GLES20.GL_NO_ERROR, error);
+ }
+
+ public void test_glAttachShaders_successfulcompile_attach_invalid_handle_frag() throws Throwable {
+ mActivity = getShaderActivity(Constants.SHADER, 12);
+ int error = mActivity.glGetError();
+ assertTrue(GLES20.GL_NO_ERROR != error);
+ }
}
diff --git a/tests/tests/opengl/src/android/opengl/cts/ColorBufferTest.java b/tests/tests/opengl/src/android/opengl/cts/ColorBufferTest.java
new file mode 100755
index 0000000..5ec1ce1
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/ColorBufferTest.java
@@ -0,0 +1,198 @@
+/*
+ * 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.opengl.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+public class ColorBufferTest extends ActivityInstrumentationTestCase2<OpenGLES20ActivityTwo> {
+ private static final long SLEEP_TIME = 500l;
+ public ColorBufferTest(Class<OpenGLES20ActivityTwo> activityClass) {
+ super(activityClass);
+ }
+
+ private OpenGLES20ActivityTwo mActivity;
+
+ public ColorBufferTest() {
+ super(OpenGLES20ActivityTwo.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+ /**
+ *Test: Attach an two valid shaders to a program
+ * <pre>
+ * shader count : 2
+ * error : GLES20.GL_NO_ERROR
+ * </pre>
+ */
+ public void test_RGBA_1001() throws Throwable {
+ float r = 1.0f;
+ float g = 0.0f;
+ float b = 0.0f;
+ float a = 1.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+ mActivity = getActivity();
+ float[] expectedColor = {r, g, b, a};
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_1101() throws Throwable {
+ float r = 1.0f;
+ float g = 1.0f;
+ float b = 0.0f;
+ float a = 1.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_1111() throws Throwable {
+ float r = 1.0f;
+ float g = 1.0f;
+ float b = 1.0f;
+ float a = 1.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_0101() throws Throwable {
+ float r = 0.0f;
+ float g = 1.0f;
+ float b = 0.0f;
+ float a = 1.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_0011() throws Throwable {
+ float r = 0.0f;
+ float g = 0.0f;
+ float b = 1.0f;
+ float a = 1.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_0000() throws Throwable {
+ float r = 0.0f;
+ float g = 0.0f;
+ float b = 0.0f;
+ float a = 0.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_rand_val_one() throws Throwable {
+ float r = 0.6f;
+ float g = 0.7f;
+ float b = 0.25f;
+ float a = 0.5f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ private float[] getVertexColors(float r, float g, float b, float a) {
+ float[] vertexColors =
+ { r, g, b, a,
+ r, g, b, a,
+ r, g, b, a,
+ r, g, b, a
+ };
+ return vertexColors;
+ }
+
+ private void compare(float[] expectedColor, float[] actualColor) {
+ assertNotNull(actualColor);
+ assertEquals(4, actualColor.length);
+ float r = expectedColor[0];
+ float g = expectedColor[1];
+ float b = expectedColor[2];
+ float a = expectedColor[3];
+ //We are giving 0.1 buffer as colors might not be exactly same as input color
+ assertTrue(Math.abs(r - (actualColor[0]/255)) < 0.1f);
+ assertTrue(Math.abs(g - (actualColor[1]/255)) < 0.1f);
+ assertTrue(Math.abs(b - (actualColor[2]/255)) < 0.1f);
+ //assertTrue(Math.abs(a - (actualColor[3]/255)) < 0.1f);
+ }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/Constants.java b/tests/tests/opengl/src/android/opengl/cts/Constants.java
index 9bd1acc..cba455a 100644
--- a/tests/tests/opengl/src/android/opengl/cts/Constants.java
+++ b/tests/tests/opengl/src/android/opengl/cts/Constants.java
@@ -18,4 +18,5 @@
public class Constants {
public static final int SHADER = 1;
public static final int PROGRAM = 2;
+ public static final int COLOR = 3;
}
diff --git a/tests/tests/opengl/src/android/opengl/cts/GL2JniLibOne.java b/tests/tests/opengl/src/android/opengl/cts/GL2JniLibOne.java
index 26de6ff..c306fc7 100755
--- a/tests/tests/opengl/src/android/opengl/cts/GL2JniLibOne.java
+++ b/tests/tests/opengl/src/android/opengl/cts/GL2JniLibOne.java
@@ -18,11 +18,12 @@
public class GL2JniLibOne {
static {
- System.loadLibrary("opengltest");
+ System.loadLibrary("opengltest_jni");
}
- public static native void init(int category, int subcategory);
+ public static native void init(int category, int subcategory, int width, int height);
public static native void step();
+ public static native float[] draw(int category, int subcategory, float[] color);
public static native int getAttachShaderError();
public static native int getLoadShaderError();
diff --git a/tests/tests/opengl/src/android/opengl/cts/NativeAttachShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/NativeAttachShaderTest.java
index dbe3ea6..9985e87 100755
--- a/tests/tests/opengl/src/android/opengl/cts/NativeAttachShaderTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/NativeAttachShaderTest.java
@@ -20,24 +20,20 @@
import android.test.ActivityInstrumentationTestCase2;
public class NativeAttachShaderTest
- extends ActivityInstrumentationTestCase2<OpenGLES20NativeActivity> {
+ extends ActivityInstrumentationTestCase2<OpenGLES20NativeActivityOne> {
- public NativeAttachShaderTest(Class<OpenGLES20NativeActivity> activityClass) {
- super(activityClass);
- }
-
- private OpenGLES20NativeActivity mActivity;
+ private OpenGLES20NativeActivityOne mActivity;
public NativeAttachShaderTest() {
- super(OpenGLES20NativeActivity.class);
+ super(OpenGLES20NativeActivityOne.class);
}
- private OpenGLES20NativeActivity getShaderActivity(int viewType, int viewIndex) {
+ private OpenGLES20NativeActivityOne getShaderActivity(int viewType, int viewIndex) {
Intent intent = new Intent();
- intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_TYPE, viewType);
- intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_INDEX, viewIndex);
+ intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_TYPE, viewType);
+ intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_INDEX, viewIndex);
setActivityIntent(intent);
- OpenGLES20NativeActivity activity = getActivity();
+ OpenGLES20NativeActivityOne activity = getActivity();
assertTrue(activity.waitForFrameDrawn());
return activity;
}
@@ -113,4 +109,37 @@
int error = mActivity.mRenderer.mAttachShaderError;;
assertEquals(GLES20.GL_NO_ERROR, error);
}
+
+ public void test_glAttachShaders_emptyvertexshader_emptyvertexshader() throws Throwable {
+ mActivity = getShaderActivity(Constants.SHADER, 7);
+ int error = mActivity.mRenderer.mAttachShaderError;
+ assertTrue(GLES20.GL_NO_ERROR != error);
+ }
+
+ public void test_glAttachShaders_programobject_attach_fragshaderobject() throws Throwable {
+ mActivity = getShaderActivity(Constants.SHADER, 8);
+ int error = mActivity.mRenderer.mAttachShaderError;
+ // The operations are valid
+ assertEquals(GLES20.GL_NO_ERROR, error);
+ }
+
+ public void test_glAttachShaders_invalidshader_attach_valid_handle() throws Throwable{
+ mActivity = getShaderActivity(Constants.SHADER, 9);
+ int error = mActivity.mRenderer.mAttachShaderError;
+ assertTrue(GLES20.GL_NO_ERROR != error);
+ }
+
+ public void test_glAttachShaders_successfulcompile_attach_frag() throws Throwable {
+ mActivity = getShaderActivity(Constants.SHADER, 10);
+ int shaderCount = mActivity.mRenderer.mShaderCount;
+ assertEquals(1,shaderCount);
+ int error = mActivity.mRenderer.mAttachShaderError;
+ assertEquals(GLES20.GL_NO_ERROR, error);
+ }
+
+ public void test_glAttachShaders_successfulcompile_attach_vert() throws Throwable {
+ mActivity = getShaderActivity(Constants.SHADER, 11);
+ int error = mActivity.mRenderer.mAttachShaderError;
+ assertEquals(GLES20.GL_NO_ERROR, error);
+ }
}
diff --git a/tests/tests/opengl/src/android/opengl/cts/NativeColorBufferTest.java b/tests/tests/opengl/src/android/opengl/cts/NativeColorBufferTest.java
new file mode 100755
index 0000000..7f4dbb2
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/NativeColorBufferTest.java
@@ -0,0 +1,194 @@
+/*
+ * 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.opengl.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+public class NativeColorBufferTest extends ActivityInstrumentationTestCase2<OpenGLES20NativeActivityTwo> {
+ private static final long SLEEP_TIME = 500l;
+ private static final String TAG = NativeColorBufferTest.class.getName();
+ public NativeColorBufferTest(Class<OpenGLES20NativeActivityTwo> activityClass) {
+ super(activityClass);
+ }
+
+ private OpenGLES20NativeActivityTwo mActivity;
+
+ public NativeColorBufferTest() {
+ super(OpenGLES20NativeActivityTwo.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+
+ public void test_RGBA_1001() throws Throwable {
+ float r = 1.0f;
+ float g = 0.0f;
+ float b = 0.0f;
+ float a = 1.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+ mActivity = getActivity();
+ float[] expectedColor = {r, g, b, a};
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_1101() throws Throwable {
+ float r = 1.0f;
+ float g = 1.0f;
+ float b = 0.0f;
+ float a = 1.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_1111() throws Throwable {
+ float r = 1.0f;
+ float g = 1.0f;
+ float b = 1.0f;
+ float a = 1.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_0101() throws Throwable {
+ float r = 0.0f;
+ float g = 1.0f;
+ float b = 0.0f;
+ float a = 1.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_0011() throws Throwable {
+ float r = 0.0f;
+ float g = 0.0f;
+ float b = 1.0f;
+ float a = 1.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_0000() throws Throwable {
+ float r = 0.0f;
+ float g = 0.0f;
+ float b = 0.0f;
+ float a = 0.0f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ public void test_RGBA_rand_val_one() throws Throwable {
+ float r = 0.6f;
+ float g = 0.7f;
+ float b = 0.25f;
+ float a = 0.5f;
+ final float[] vertexColors = getVertexColors(r, g, b, a);
+
+ float[] expectedColor = {r, g, b, a};
+ mActivity = getActivity();
+ this.runTestOnUiThread(new Runnable() {
+ public void run() {
+ mActivity.setView(Constants.COLOR, 1, vertexColors);
+ }
+ });
+ assertTrue(mActivity.waitForFrameDrawn());
+ float[] actualColor = mActivity.getActualColor();
+ compare(expectedColor, actualColor);
+ }
+
+ private float[] getVertexColors(float r, float g, float b, float a) {
+ float[] vertexColors =
+ { r, g, b, a,
+ r, g, b, a,
+ r, g, b, a
+ };
+ return vertexColors;
+ }
+
+ private void compare(float[] expectedColor, float[] actualColor) {
+ assertNotNull(actualColor);
+ assertEquals(4, actualColor.length);
+ float r = expectedColor[0];
+ float g = expectedColor[1];
+ float b = expectedColor[2];
+ float a = expectedColor[3];
+ //We are giving 0.1 buffer as colors might not be exactly same as input color
+ assertTrue(Math.abs(r - (actualColor[0]/255.0)) < 0.1f);
+ assertTrue(Math.abs(g - (actualColor[1]/255.0)) < 0.1f);
+ assertTrue(Math.abs(b - (actualColor[2]/255.0)) < 0.1f);
+ float actualAlpha = (float) (actualColor[3]/255.0);
+ //Commented as of now as the Alpha being returned is always 1
+ //assertTrue(Math.abs(a - (actualColor[3]/255)) < 0.1f);
+ }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/NativeRendererOneColorBufferTest.java b/tests/tests/opengl/src/android/opengl/cts/NativeRendererOneColorBufferTest.java
new file mode 100755
index 0000000..623daea
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/NativeRendererOneColorBufferTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.opengl.cts;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+import java.util.concurrent.CountDownLatch;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.util.Log;
+
+public class NativeRendererOneColorBufferTest extends RendererBase {
+ private int mProgramObject;
+ private int mWidth;
+ private int mHeight;
+ private FloatBuffer mVertices;
+ private ShortBuffer mIndexBuffer;
+
+ private static String TAG = "HelloTriangleRenderer";
+
+ // Our vertices.
+ private float mVerticesData[] = {
+ -0.5f, 0.5f, 0.0f, // 0, Top Left
+ -0.5f, -0.5f, 0.0f, // 1, Bottom Left
+ 0.5f, -0.5f, 0.0f, // 2, Bottom Right
+ 0.5f, 0.5f, 0.0f, // 3, Top Right
+ };
+
+ private float[] mVertexColor = {};
+
+ private short[] mIndices = { 0, 1, 2, 0, 2, 3 };
+ private FloatBuffer mColor;
+
+ public NativeRendererOneColorBufferTest(Context context, CountDownLatch latch) {
+ super(latch);
+ }
+
+ public NativeRendererOneColorBufferTest(Context context, float[] color, CountDownLatch latch) {
+ super(latch);
+ this.mVertexColor = color;
+ }
+
+ public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
+
+ }
+
+ public void doOnDrawFrame(GL10 glUnused) {
+ Log.i(TAG,"onDrawFrame start");
+
+ float[] result = GL2JniLibOne.draw(3, 1, mVertexColor);
+ mColorOne = result;
+ }
+
+ public float[] getActualRGBA() {
+ return this.mColorOne;
+ }
+
+ public void onSurfaceChanged(GL10 glUnused, int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ Log.i(TAG,"onSurfaceCreated start");
+ GL2JniLibOne.init(3,1, width, height);
+ Log.i(TAG,"onSurfaceCreated finish");
+ }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java
index a8388c2..5acac32 100644
--- a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java
@@ -89,6 +89,7 @@
public OpenGLES20View(Context context, int type, int index, CountDownLatch latch) {
super(context);
setEGLContextClientVersion(2);
+
if (type == Constants.SHADER) {
if (index == 1) {
mRenderer = new RendererOneShaderTest(latch);
@@ -110,6 +111,10 @@
mRenderer = new RendererNineShaderTest(latch);
} else if(index == 10) {
mRenderer = new RendererTenShaderTest(latch);
+ } else if(index == 11) {
+ mRenderer = new RendererElevenShaderTest(latch);
+ } else if(index == 12) {
+ mRenderer = new RendererTwelveShaderTest(latch);
} else {
throw new RuntimeException();
}
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityTwo.java b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityTwo.java
new file mode 100755
index 0000000..6bb34e4
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityTwo.java
@@ -0,0 +1,110 @@
+/*
+ * 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.opengl.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLSurfaceView.Renderer;
+import android.os.Bundle;
+
+import java.lang.InterruptedException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+
+public class OpenGLES20ActivityTwo extends Activity {
+ OpenGLES20View view;
+ Renderer mRenderer;
+ int mRendererType;
+ private CountDownLatch mLatch = new CountDownLatch(1);
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ public boolean waitForFrameDrawn() {
+ boolean result = false;
+ try {
+ result = mLatch.await(10L, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ // just return false
+ }
+ return result;
+ }
+
+ public void setView(int type, int i, float[] vertexColors ) {
+ view = new OpenGLES20View(this,type,i, vertexColors, mLatch);
+ setContentView(view);
+ }
+
+ public void setView(int type, int i) {
+ float[] f = {};
+ view = new OpenGLES20View(this, type, i, f, mLatch) ;
+ setContentView(view);
+ }
+
+ public int getNoOfAttachedShaders() {
+ return ((RendererBase)mRenderer).mShaderCount[0];
+ }
+
+ public int glGetError() {
+ return ((RendererBase)mRenderer).mError;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ view.onPause();
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if(view != null) {
+ view.onResume();
+ }
+ }
+
+ public float[] getActualColor() {
+ return ((RendererBase) mRenderer).mColorOne;
+ }
+
+ class OpenGLES20View extends GLSurfaceView {
+
+ public OpenGLES20View(Context context, int type, int index, float[] rgba,
+ CountDownLatch latch) {
+ super(context);
+ setEGLContextClientVersion(2);
+ if(type == Constants.COLOR) {
+ if(index == 1) {
+ mRenderer = new RendererOneColorBufferTest(context, rgba, latch);
+ }else {
+ throw new RuntimeException();
+ }
+ }
+ setRenderer(mRenderer);
+ }
+
+ @Override
+ public void setEGLContextClientVersion(int version) {
+ super.setEGLContextClientVersion(version);
+ }
+
+ }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivity.java b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityOne.java
similarity index 81%
rename from tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivity.java
rename to tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityOne.java
index 36f986b..ac4fce5 100755
--- a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivity.java
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityOne.java
@@ -1,23 +1,9 @@
-/*
- * 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.opengl.cts;
import android.app.Activity;
import android.content.Context;
import android.opengl.GLSurfaceView;
+
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
@@ -30,7 +16,7 @@
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
-public class OpenGLES20NativeActivity extends Activity {
+public class OpenGLES20NativeActivityOne extends Activity {
public static final String EXTRA_VIEW_TYPE = "viewType";
public static final String EXTRA_VIEW_INDEX = "viewIndex";
@@ -49,7 +35,6 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
@@ -122,16 +107,16 @@
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
-
- }
-
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Log.i(TAG ,"onSurfaceCreated");
- GL2JniLibOne.init(mCategory, mTestCase);
+ GL2JniLibOne.init(mCategory, mTestCase, width, height);
this.mAttachShaderError = GL2JniLibOne.getAttachShaderError();
Log.i(TAG,"error:" + mAttachShaderError);
this.mShaderCount = GL2JniLibOne.getAttachedShaderCount();
Log.i(TAG,"ShaderCount:" + mShaderCount);
mLatch.countDown();
}
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+
+ }
}
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityTwo.java b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityTwo.java
new file mode 100755
index 0000000..6bdf95f
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20NativeActivityTwo.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLSurfaceView.Renderer;
+import android.os.Bundle;
+
+import java.lang.InterruptedException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class OpenGLES20NativeActivityTwo extends Activity {
+ OpenGLES20View view;
+ Renderer mRenderer;
+ int mRendererType;
+
+ private CountDownLatch mLatch = new CountDownLatch(1);
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ public boolean waitForFrameDrawn() {
+ boolean result = false;
+ try {
+ result = mLatch.await(10L, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ // just return false
+ }
+ return result;
+ }
+
+ public void setView(int type, int i, float[] vertexColors ) {
+ view = new OpenGLES20View(this,type,i, vertexColors, mLatch);
+ setContentView(view);
+ }
+
+ public void setView(int type, int i) {
+
+ }
+
+ public int getNoOfAttachedShaders() {
+ return ((RendererBase)mRenderer).mShaderCount[0];
+ }
+
+ public int glGetError() {
+ return ((RendererBase)mRenderer).mError;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ if(view != null) {
+ view.onPause();
+ }
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ if(view != null) {
+ view.onResume();
+ }
+ }
+
+ public float[] getActualColor() {
+ return ((RendererBase) mRenderer).mColorOne;
+ }
+
+ class OpenGLES20View extends GLSurfaceView {
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ public OpenGLES20View(Context context, int type, int index, float[] rgba,
+ CountDownLatch latch) {
+ super(context);
+ setEGLContextClientVersion(2);
+ if(type == Constants.COLOR) {
+ if(index == 1) {
+ mRenderer = new NativeRendererOneColorBufferTest(context, rgba, latch);
+ }else {
+ throw new RuntimeException();
+ }
+ }
+ setRenderer(mRenderer);
+ }
+
+ @Override
+ public void setEGLContextClientVersion(int version) {
+ super.setEGLContextClientVersion(version);
+ }
+
+ }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/ProgramTest.java b/tests/tests/opengl/src/android/opengl/cts/ProgramTest.java
index 4c59070..a69c8e5 100644
--- a/tests/tests/opengl/src/android/opengl/cts/ProgramTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/ProgramTest.java
@@ -29,8 +29,8 @@
private OpenGLES20ActivityOne getShaderActivity(int viewType, int viewIndex) {
Intent intent = new Intent();
- intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_TYPE, viewType);
- intent.putExtra(OpenGLES20NativeActivity.EXTRA_VIEW_INDEX, viewIndex);
+ intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_TYPE, viewType);
+ intent.putExtra(OpenGLES20NativeActivityOne.EXTRA_VIEW_INDEX, viewIndex);
setActivityIntent(intent);
return getActivity();
}
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererBase.java b/tests/tests/opengl/src/android/opengl/cts/RendererBase.java
index d015fcd..994c1c6 100644
--- a/tests/tests/opengl/src/android/opengl/cts/RendererBase.java
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererBase.java
@@ -30,6 +30,7 @@
FloatBuffer floatBuffer;
int mProgram;
int maPositionHandle;
+ float[] mColorOne = new float[4];
int[] mShaderCount = null;
int mError;
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererElevenShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/RendererElevenShaderTest.java
new file mode 100755
index 0000000..35df7b5
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererElevenShaderTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+import java.util.concurrent.CountDownLatch;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+
+public class RendererElevenShaderTest extends RendererBase {
+ private String fragmentShaderCode = Vertex.successfulcompile_vertex;
+
+ public RendererElevenShaderTest(CountDownLatch latch) {
+ super(latch);
+ }
+
+ @Override
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+ int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+ mProgram = GLES20.glCreateProgram();
+
+ GLES20.glAttachShader(mProgram, fragmentShader);
+ GLES20.glLinkProgram(mProgram);
+
+ mError = GLES20.glGetError();
+ mLatch.countDown();
+ }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererOneColorBufferTest.java b/tests/tests/opengl/src/android/opengl/cts/RendererOneColorBufferTest.java
new file mode 100755
index 0000000..50a4085
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererOneColorBufferTest.java
@@ -0,0 +1,238 @@
+/*
+ * 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.opengl.cts;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+import java.util.concurrent.CountDownLatch;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.util.Log;
+
+public class RendererOneColorBufferTest extends RendererBase {
+ private int mProgramObject;
+ private int mWidth;
+ private int mHeight;
+ private FloatBuffer mVertices;
+ private ShortBuffer mIndexBuffer;
+
+ private static String TAG = "HelloTriangleRenderer";
+
+ // Our vertices.
+ private float mVerticesData[] = {
+ -0.5f, 0.5f, 0.0f, // 0, Top Left
+ -0.5f, -0.5f, 0.0f, // 1, Bottom Left
+ 0.5f, -0.5f, 0.0f, // 2, Bottom Right
+ 0.5f, 0.5f, 0.0f, // 3, Top Right
+ };
+
+ private float[] mVertexColor = {1.0f,0.0f,0.0f,1.0f,
+ 1.0f,0.0f,0.0f,1.0f,
+ 1.0f,0.0f,0.0f,1.0f,
+ 1.0f,0.0f,0.0f,1.0f};
+
+ // The order we like to connect them.
+ private short[] mIndices = { 0, 1, 2, 0, 2, 3 };
+ private FloatBuffer mColor;
+
+
+ public RendererOneColorBufferTest(Context context, CountDownLatch latch) {
+ super(latch);
+ mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4)
+ .order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mVertices.put(mVerticesData).position(0);
+
+ ByteBuffer ibb = ByteBuffer.allocateDirect(mIndices.length * 2);
+ ibb.order(ByteOrder.nativeOrder());
+ mIndexBuffer = ibb.asShortBuffer();
+ mIndexBuffer.put(mIndices);
+ mIndexBuffer.position(0);
+
+ mColor = ByteBuffer.allocateDirect(mVertexColor.length*4).
+ order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mColor.put(mVertexColor).position(0);
+ }
+
+ public RendererOneColorBufferTest(Context context, float[] colors, CountDownLatch latch) {
+ super(latch);
+ mVertexColor = colors;
+ mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4)
+ .order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mVertices.put(mVerticesData).position(0);
+
+ ByteBuffer ibb = ByteBuffer.allocateDirect(mIndices.length * 2);
+ ibb.order(ByteOrder.nativeOrder());
+ mIndexBuffer = ibb.asShortBuffer();
+ mIndexBuffer.put(mIndices);
+ mIndexBuffer.position(0);
+
+ mColor = ByteBuffer.allocateDirect(mVertexColor.length*4).
+ order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mColor.put(mVertexColor).position(0);
+ }
+
+ private int LoadShader(int type, String shaderSrc) {
+ int shader;
+ int[] compiled = new int[1];
+
+ // Create the shader object
+ shader = GLES20.glCreateShader(type);
+
+ if (shader == 0)
+ return 0;
+
+ // Load the shader source
+ GLES20.glShaderSource(shader, shaderSrc);
+
+ // Compile the shader
+ GLES20.glCompileShader(shader);
+
+ // Check the compile status
+ GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
+
+ if (compiled[0] == 0) {
+ Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
+ GLES20.glDeleteShader(shader);
+ return 0;
+ }
+ return shader;
+ }
+
+
+ public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
+ String vShaderStr =
+ "attribute vec4 vPosition; \n"
+ + "attribute vec4 vColor; \n"
+ + "varying vec4 varyColor; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_Position = vPosition; \n"
+ + " varyColor = vColor; \n"
+ + "} \n";
+
+ String fShaderStr =
+ "precision mediump float; \n"
+ + "varying vec4 varyColor; \n"
+ + "void main() \n"
+ + "{ \n"
+ + " gl_FragColor = varyColor; \n"
+ + "} \n";
+
+ int vertexShader;
+ int fragmentShader;
+ int programObject;
+ int[] linked = new int[1];
+
+ // Load the vertex/fragment shaders
+ vertexShader = LoadShader(GLES20.GL_VERTEX_SHADER, vShaderStr);
+ fragmentShader = LoadShader(GLES20.GL_FRAGMENT_SHADER, fShaderStr);
+
+ // Create the program object
+ programObject = GLES20.glCreateProgram();
+
+ if (programObject == 0)
+ return;
+
+ GLES20.glAttachShader(programObject, vertexShader);
+ GLES20.glAttachShader(programObject, fragmentShader);
+
+ // Bind vPosition to attribute 0
+ GLES20.glBindAttribLocation(programObject, 0, "vPosition");
+ GLES20.glBindAttribLocation(programObject, 1, "vColor");
+
+ // Link the program
+ GLES20.glLinkProgram(programObject);
+
+ // Check the link status
+ GLES20.glGetProgramiv(programObject, GLES20.GL_LINK_STATUS, linked, 0);
+
+ if (linked[0] == 0)
+ {
+ Log.e(TAG, "Error linking program:");
+ Log.e(TAG, GLES20.glGetProgramInfoLog(programObject));
+ GLES20.glDeleteProgram(programObject);
+ return;
+ }
+
+ // Store the program object
+ mProgramObject = programObject;
+
+ GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ }
+
+ public void doOnDrawFrame(GL10 glUnused)
+ {
+ // Set the viewport
+ GLES20.glViewport(0, 0, mWidth, mHeight);
+
+ // Clear the color buffer
+ GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+
+ // Use the program object
+ GLES20.glUseProgram(mProgramObject);
+
+ // Load the vertex data
+ GLES20.glVertexAttribPointer(0,3, GLES20.GL_FLOAT, false, 0, mVertices);
+ GLES20.glEnableVertexAttribArray(0);
+
+ int mColorHandle = GLES20.glGetAttribLocation(mProgramObject, "vColor");
+ GLES20.glVertexAttribPointer(mColorHandle,4, GLES20.GL_FLOAT, false, 0, mColor);
+ GLES20.glEnableVertexAttribArray(1);
+
+ GLES20.glDrawElements(GLES20.GL_TRIANGLES, mIndices.length,
+ GLES20.GL_UNSIGNED_SHORT, mIndexBuffer);
+
+ int x = 1;
+ int y =1;
+ IntBuffer pinbuffer = IntBuffer.allocate(1*1*4);
+ IntBuffer poutbuffer = IntBuffer.allocate(x*y*4);
+ int i,j,z;
+ int [] pin = pinbuffer.array();
+ int [] pout = poutbuffer.array();
+
+ GLES20.glReadPixels(mWidth/2, mWidth/2, 1, 1, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE,
+ pinbuffer);
+ int pixel = pin[0];
+ float a = (pixel >> 24) & 0xFF;
+ float b = (pixel >> 16) & 0xFF;
+ float g = (pixel >> 8) & 0xFF;
+ float r = pixel & 0xFF;
+ Log.i(TAG,"rgba" + r + " " + g + " " + b + " " + a);
+ mColorOne[0] = r;
+ mColorOne[1] = g;
+ mColorOne[2] = b;
+ mColorOne[3] = a;
+ }
+
+ public float[] getActualRGBA() {
+ return this.mColorOne;
+ }
+
+ public void onSurfaceChanged(GL10 glUnused, int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererTwelveShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/RendererTwelveShaderTest.java
new file mode 100755
index 0000000..a3dab8e
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererTwelveShaderTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+import java.util.concurrent.CountDownLatch;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+
+public class RendererTwelveShaderTest extends RendererBase {
+ private String fragmentShaderCode = Shaders.successfulcompile_frag;
+
+ public RendererTwelveShaderTest(CountDownLatch latch) {
+ super(latch);
+ }
+
+ @Override
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+ int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+ //invalid value
+ mProgram = 0;
+
+ GLES20.glAttachShader(mProgram, fragmentShader);
+ GLES20.glLinkProgram(mProgram);
+
+ mError = GLES20.glGetError();
+ mLatch.countDown();
+ }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/Vertex.java b/tests/tests/opengl/src/android/opengl/cts/Vertex.java
new file mode 100755
index 0000000..5041167
--- /dev/null
+++ b/tests/tests/opengl/src/android/opengl/cts/Vertex.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.opengl.cts;
+
+public class Vertex {
+ public static String successfulcompile_vertex =
+ "attribute vec3 gtf_Normal; \n"
+ + "attribute vec4 gtf_Vertex; \n"
+ + "uniform mat3 gtf_NormalMatrix; \n"
+ + "uniform mat4 gtf_ModelViewMatrix; \n"
+ + "uniform mat4 gtf_ModelViewProjectionMatrix; \n"
+ + "\n"
+ + "varying float lightIntensity; \n"
+ + "varying vec3 Position; \n"
+ + "uniform vec3 LightPosition; \n"
+ + "uniform float Scale; \n"
+ + "\n"
+ + "void main(void) { \n"
+ + " vec4 pos = gtf_ModelViewMatrix * gtf_Vertex; \n"
+ + " Position = vec3(gtf_Vertex) * Scale; \n"
+ + " vec3 tnorm = normalize(gtf_NormalMatrix * gtf_Normal); \n"
+ + " lightIntensity = dot(normalize(LightPosition - vec3(pos)), tnorm) * 1.5; \n"
+ + " gl_Position = gtf_ModelViewProjectionMatrix * gtf_Vertex; \n"
+ + "}";
+}
diff --git a/tests/tests/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java b/tests/tests/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java
index dca2bde..7ff67eb 100644
--- a/tests/tests/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java
+++ b/tests/tests/permission/src/android/permission/cts/PackageManagerRequiringPermissionsTest.java
@@ -81,4 +81,34 @@
// expected
}
}
+
+ /**
+ * Verify that PackageManager.verifyPendingInstall requires permission.
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#PACKAGE_VERIFICATION_AGENT}
+ */
+ public void testVerifyPendingInstall() {
+ try {
+ mPackageManager.verifyPendingInstall(1, 1);
+ fail("PackageManager.verifyPendingInstall did not throw SecurityException"
+ + " as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Verify that PackageManager.extendVerificationTimeout requires permission.
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#PACKAGE_VERIFICATION_AGENT}.
+ */
+ public void testExtendVerificationTimeout() {
+ try {
+ mPackageManager.extendVerificationTimeout(1, 1, 10000);
+ fail("PackageManager.extendVerificationTimeout did not throw SecurityException"
+ + " as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
}
diff --git a/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java b/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java
index aa8874c..7e06697 100644
--- a/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java
+++ b/tests/tests/text/src/android/text/cts/StaticLayoutLineBreakingTest.java
@@ -20,14 +20,17 @@
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.StaticLayout;
+import android.text.TextDirectionHeuristics;
import android.text.TextPaint;
import android.text.Layout.Alignment;
import android.text.style.MetricAffectingSpan;
+import android.util.Log;
public class StaticLayoutLineBreakingTest extends AndroidTestCase {
// Span test are currently not supported because text measurement uses the MeasuredText
// internal mWorkPaint instead of the provided MockTestPaint.
private static final boolean SPAN_TESTS_SUPPORTED = false;
+ private static final boolean DEBUG = false;
private static final float SPACE_MULTI = 1.0f;
private static final float SPACE_ADD = 0.0f;
@@ -89,7 +92,7 @@
case 'L': return 50.0f;
case 'C': return 100.0f; // equals to WIDTH
case ' ': return 10.0f;
- case '.': return 0.0f; // 0-width character
+ case '_': return 0.0f; // 0-width character
case SURR_FIRST: return 7.0f;
case SURR_SECOND: return 3.0f; // Sum of SURR_FIRST-SURR_SECOND is 10
default: return 10.0f;
@@ -100,11 +103,13 @@
return new StaticLayout(source, mTextPaint, width, ALIGN, SPACE_MULTI, SPACE_ADD, false);
}
- private static StaticLayout getStaticLayout(CharSequence source) {
- return getStaticLayout(source, WIDTH);
+ private static int[] getBreaks(CharSequence source) {
+ return getBreaks(source, WIDTH);
}
- private static int[] getBreaks(StaticLayout staticLayout) {
+ private static int[] getBreaks(CharSequence source, int width) {
+ StaticLayout staticLayout = getStaticLayout(source, width);
+
int[] breaks = new int[staticLayout.getLineCount() - 1];
for (int line = 0; line < breaks.length; line++) {
breaks[line] = staticLayout.getLineEnd(line);
@@ -112,14 +117,28 @@
return breaks;
}
- private static void layout(CharSequence source, int[] breaks) {
- StaticLayout staticLayout = getStaticLayout(source);
- layout(staticLayout, source, breaks);
+ private static void debugLayout(CharSequence source, StaticLayout staticLayout) {
+ if (DEBUG) {
+ int count = staticLayout.getLineCount();
+ Log.i("StaticLayoutLineBreakingTest", "\"" + source.toString() + "\": " +
+ count + " lines");
+ for (int line = 0; line < count; line++) {
+ int lineStart = staticLayout.getLineStart(line);
+ int lineEnd = staticLayout.getLineEnd(line);
+ Log.i("StaticLayoutLineBreakingTest", "Line " + line + " [" + lineStart + ".." +
+ lineEnd + "]\t" + source.subSequence(lineStart, lineEnd));
+ }
+ }
}
- private static void layout(StaticLayout staticLayout, CharSequence source, int[] breaks) {
- //Log.i("StaticLayoutLineWrappingTest", "String " + source.toString() + "; " +
- // staticLayout.getLineCount() + " lines");
+ private static void layout(CharSequence source, int[] breaks) {
+ layout(source, breaks, WIDTH);
+ }
+
+ private static void layout(CharSequence source, int[] breaks, int width) {
+ StaticLayout staticLayout = getStaticLayout(source, width);
+
+ debugLayout(source, staticLayout);
int lineCount = breaks.length + 1;
assertEquals("Number of lines", lineCount, staticLayout.getLineCount());
@@ -128,9 +147,6 @@
int lineStart = staticLayout.getLineStart(line);
int lineEnd = staticLayout.getLineEnd(line);
- //Log.i("StaticLayoutLineWrappingTest", "Line " + line + " [" + lineStart + ".." +
- // lineEnd + "]\t" + source.subSequence(lineStart, lineEnd));
-
if (line == 0) {
assertEquals("Line start for first line", 0, lineStart);
} else {
@@ -145,6 +161,34 @@
}
}
+ private static void layoutMaxLines(CharSequence source, int[] breaks, int maxLines) {
+ StaticLayout staticLayout = new StaticLayout(source, 0, source.length(), mTextPaint, WIDTH,
+ ALIGN, TextDirectionHeuristics.LTR, SPACE_MULTI, SPACE_ADD, false /* includePad */,
+ null, WIDTH, maxLines);
+
+ debugLayout(source, staticLayout);
+
+ int lineCount = staticLayout.getLineCount();
+ assertTrue("Number of lines", lineCount <= maxLines);
+
+ for (int line = 0; line < lineCount; line++) {
+ int lineStart = staticLayout.getLineStart(line);
+ int lineEnd = staticLayout.getLineEnd(line);
+
+ if (line == 0) {
+ assertEquals("Line start for first line", 0, lineStart);
+ } else {
+ assertEquals("Line start for line " + line, breaks[line - 1], lineStart);
+ }
+
+ if (line == lineCount - 1 && line != breaks.length - 1) {
+ assertEquals("Line end for last line", source.length(), lineEnd);
+ } else {
+ assertEquals("Line end for line " + line, breaks[line], lineEnd);
+ }
+ }
+ }
+
final static int MAX_SPAN_COUNT = 10;
final static int[] spanStarts = new int[MAX_SPAN_COUNT];
final static int[] spanEnds = new int[MAX_SPAN_COUNT];
@@ -218,7 +262,7 @@
layout(" XX XXX ", NO_BREAK);
layout("XX XXX XXX ", NO_BREAK);
layout("XX XXX XXX ", NO_BREAK);
- layout("XXXXXXXXXX ", new int[] {10}); // Bug, should be NO_BREAK as above
+ layout("XXXXXXXXXX ", NO_BREAK);
// 01234567890
}
@@ -235,18 +279,18 @@
layout("XXXXXXX XXX", new int[] {8});
layout("XXXXXX XXXX", new int[] {7});
// 01234567890
- layout("LL LL", new int[] {2, 3}); // Bug: should be {3}
+ layout("LL LL", new int[] {3});
layout("LLLL", new int[] {2});
- layout("C C", new int[] {1, 2}); // Bug: should be {2}
+ layout("C C", new int[] {2});
layout("CC", new int[] {1});
}
public void testSpaceAtBreak() {
// 0123456789012
layout("XXXX XXXXX X", new int[] {11});
- layout("XXXXXXXXXX X", new int[] {10}); // Bug: should be {11}. Consume spaces in the non ok case too
- layout("XXXXXXXXXV X", new int[] {10}); // Bug: should be {11}
- layout("C X", new int[] {1}); // Should be 2
+ layout("XXXXXXXXXX X", new int[] {11});
+ layout("XXXXXXXXXV X", new int[] {11});
+ layout("C X", new int[] {2});
}
public void testMultipleSpacesAtBreak() {
@@ -260,10 +304,10 @@
public void testZeroWidthCharacters() {
// 0123456789012345678901234
- layout("X.X.X.X.X.X.X.X.X.X", NO_BREAK);
- layout("...X.X.X.X.X.X.X.X.X.X...", NO_BREAK);
- layout("C.X", new int[] {2});
- layout("C..X", new int[] {3});
+ layout("X_X_X_X_X_X_X_X_X_X", NO_BREAK);
+ layout("___X_X_X_X_X_X_X_X_X_X___", NO_BREAK);
+ layout("C_X", new int[] {2});
+ layout("C__X", new int[] {3});
}
/**
@@ -289,11 +333,6 @@
layout(spanify("012 456 89 <LXX> XX XX"), new int[] {11, 18});
}
- public void testWithOverlappingSpans() {
- // TODO Also try overlapping spans. The current implementation does not care, but would be
- // good to have before any serious refactoring.
- }
-
/*
* Adding a span to the string should not change the layout, since the metrics are unchanged.
*/
@@ -307,8 +346,7 @@
for (String text : texts) {
// Get the line breaks without any span
- StaticLayout sl = getStaticLayout(text);
- int[] breaks = getBreaks(sl);
+ int[] breaks = getBreaks(text);
// Add spans on all possible offsets
for (int spanStart = 0; spanStart < text.length(); spanStart++) {
@@ -333,8 +371,7 @@
for (String text : texts) {
// Get the line breaks without any span
- StaticLayout sl = getStaticLayout(text);
- int[] breaks = getBreaks(sl);
+ int[] breaks = getBreaks(text);
// Add spans on all possible offsets
for (int spanStart1 = 0; spanStart1 < text.length(); spanStart1++) {
@@ -355,8 +392,82 @@
}
}
- public void testBreakCondition() {
- // Try all the different line break characters, space, tab, ','...
+ public static String replace(String string, char c, char r) {
+ return string.replaceAll(String.valueOf(c), String.valueOf(r));
+ }
+
+ public void testClassIS() {
+ char[] classISCharacters = new char[] {'.', ',', ':', ';'};
+ char[] digitCharacters = new char[] {'0', '\u0660', '\u06F0', '\u0966', '\uFF10'};
+
+ for (char c : classISCharacters) {
+ // .,:; are class IS breakpoints...
+ // 01234567
+ layout(replace("L XXX#X", '#', c), new int[] {6});
+ layout(replace("L XXXX#X", '#', c), new int[] {2});
+
+ // ...except when adjacent to digits
+ for (char d : digitCharacters) {
+ // 01234567
+ layout(replace(replace("L XX0#X", '#', c), '0', d), new int[] {2});
+ layout(replace(replace("L XXX#0", '#', c), '0', d), new int[] {2});
+ layout(replace(replace("L XXX0#X", '#', c), '0', d), new int[] {2});
+ layout(replace(replace("L XXXX#0", '#', c), '0', d), new int[] {2});
+ }
+ }
+ }
+
+ public void testClassSYandHY() {
+ char[] classSYorHYCharacters = new char[] {'/', '-'};
+ char[] digitCharacters = new char[] {'0', '\u0660', '\u06F0', '\u0966', '\uFF10'};
+
+ for (char c : classSYorHYCharacters) {
+ // / is a class SY breakpoint, - a class HY...
+ // 01234567
+ layout(replace("L XXX#X", '#', c), new int[] {6});
+ layout(replace("L XXXX#X", '#', c), new int[] {2});
+
+ // ...except when followed by a digits
+ for (char d : digitCharacters) {
+ // 01234567
+ layout(replace(replace("L XX0#X", '#', c), '0', d), new int[] {6});
+ layout(replace(replace("L XXX#0", '#', c), '0', d), new int[] {2});
+ layout(replace(replace("L XXX0#X", '#', c), '0', d), new int[] {2});
+ layout(replace(replace("L XXXX#0", '#', c), '0', d), new int[] {2});
+ }
+ }
+ }
+
+ public void testClassID() {
+ char ideographic = '\u8a9e'; // regular ideographic character
+ char hyphen = '\u30A0'; // KATAKANA-HIRAGANA DOUBLE HYPHEN, ideographic but non starter
+
+ // Single ideographs are normal characters
+ layout("L XXX" + ideographic, NO_BREAK);
+ layout("L XXX" + ideographic + "X", new int[] {2});
+ layout("L XXXX" + ideographic, new int[] {2});
+ layout("L XXXX" + ideographic + "X", new int[] {2});
+
+ // Two adjacent ideographs create a possible breakpoint
+ layout("L X" + ideographic + ideographic + "X", NO_BREAK);
+ layout("L X" + ideographic + ideographic + "XX", new int[] {4});
+ layout("L XX" + ideographic + ideographic + "XX", new int[] {5});
+ layout("L XXX" + ideographic + ideographic + "X", new int[] {6});
+ layout("L XXXX" + ideographic + ideographic + "X", new int[] {2});
+
+ // Except when the second one is a non starter
+ layout("L X" + ideographic + hyphen + "X", NO_BREAK);
+ layout("L X" + ideographic + hyphen + "XX", new int[] {2});
+ layout("L XX" + ideographic + hyphen + "XX", new int[] {2});
+ layout("L XXX" + ideographic + hyphen + "X", new int[] {2});
+ layout("L XXXX" + ideographic + hyphen + "X", new int[] {2});
+
+ // When the non-starter is first, a pair of ideographic characters is a line break
+ layout("L X" + hyphen + ideographic + "X", NO_BREAK);
+ layout("L X" + hyphen + ideographic + "XX", new int[] {4});
+ layout("L XX" + hyphen + ideographic + "XX", new int[] {5});
+ layout("L XXX" + hyphen + ideographic + "X", new int[] {6});
+ layout("L XXXX" + hyphen + ideographic + "X", new int[] {2});
}
public void testReplacementSpan() {
@@ -387,19 +498,58 @@
public void testNarrowWidth() {
int[] widths = new int[] { 0, 4, 10 };
- String[] texts = new String[] { "", "X", " ", "XX", "XX ", "X ", "XXX", "XXX ", "X X",
- " X X " /* Bug "X X", ".X..", " ", "XX ", "X." should work too */ };
+ String[] texts = new String[] { "", "X", " ", "XX", " X", "XXX" };
for (String text: texts) {
// 15 is such that only one character will fit
- StaticLayout reference = getStaticLayout(text, 15);
- int[] breaks = getBreaks(reference);
+ int[] breaks = getBreaks(text, 15);
// Width under 15 should all lead to the same line break
for (int width: widths) {
- StaticLayout sl = getStaticLayout(text, width);
- layout(sl, text, breaks);
+ layout(text, breaks, width);
}
}
}
+
+ public void testNarrowWidthWithSpace() {
+ int[] widths = new int[] { 0, 4 };
+ for (int width: widths) {
+ layout("X ", new int[] {1}, width);
+ layout("X ", new int[] {1}, width);
+ layout("XX ", new int[] {1, 2}, width);
+ layout("XX ", new int[] {1, 2}, width);
+ layout("X X", new int[] {1, 3}, width);
+ layout("X X", new int[] {1, 2}, width);
+
+ layout(" ", NO_BREAK, width);
+ layout(" X", new int[] {1}, width);
+ layout(" ", NO_BREAK, width);
+ layout(" X X", new int[] {1, 2, 3}, width);
+ layout(" X", new int[] {2}, width);
+ }
+ }
+
+ public void testNarrowWidthZeroWidth() {
+ int[] widths = new int[] { 0, 4 };
+ for (int width: widths) {
+ layout("X.", new int[] {1}, width);
+ layout("X__", new int[] {1}, width);
+ layout("X__X", new int[] {1, 3}, width); // Could be {1}
+ layout("X__X_", new int[] {1, 3, 4}, width); // Could be {1, 4}
+
+ layout("_", NO_BREAK, width);
+ layout("__", NO_BREAK, width);
+ layout("_X", new int[] {1}, width); // Could be NO_BREAK
+ layout("_X_", new int[] {1, 2}, width); // Could be {2}
+ layout("_X__", new int[] {1, 2}, width); // Could be {2}
+ }
+ }
+
+ public void testMaxLines() {
+ layoutMaxLines("C", NO_BREAK, 1);
+ layoutMaxLines("C C", new int[] {2}, 1);
+ layoutMaxLines("C C", new int[] {2}, 2);
+ layoutMaxLines("CC", new int[] {1}, 1);
+ layoutMaxLines("CC", new int[] {1}, 2);
+ }
}
diff --git a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
index 1907ac7..25e6306 100644
--- a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
+++ b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
@@ -52,9 +52,9 @@
DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_LONG));
assertEquals("Sun",
DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_MEDIUM));
- assertEquals("Su",
+ assertEquals("Sun",
DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_SHORT));
- assertEquals("Su",
+ assertEquals("Sun",
DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_SHORTER));
assertEquals("S",
DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_SHORTEST));
@@ -83,8 +83,8 @@
if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) {
return;
}
- assertEquals("am", DateUtils.getAMPMString(Calendar.AM));
- assertEquals("pm", DateUtils.getAMPMString(Calendar.PM));
+ assertEquals("AM", DateUtils.getAMPMString(Calendar.AM));
+ assertEquals("PM", DateUtils.getAMPMString(Calendar.PM));
}
@@ -169,7 +169,7 @@
+ HOUR_DURATION, DateUtils.FORMAT_SHOW_WEEKDAY));
assertEquals("January 19", DateUtils.formatDateRange(mContext, timeWithCurrentYear,
timeWithCurrentYear + HOUR_DURATION, DateUtils.FORMAT_SHOW_DATE));
- assertEquals("3:30am", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
+ assertEquals("3:30AM", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
DateUtils.FORMAT_SHOW_TIME));
assertEquals("January 19, 2009", DateUtils.formatDateRange(mContext, fixedTime,
fixedTime + HOUR_DURATION, DateUtils.FORMAT_SHOW_YEAR));
@@ -177,7 +177,7 @@
timeWithCurrentYear + HOUR_DURATION, DateUtils.FORMAT_NO_YEAR));
assertEquals("January", DateUtils.formatDateRange(mContext, timeWithCurrentYear,
timeWithCurrentYear + HOUR_DURATION, DateUtils.FORMAT_NO_MONTH_DAY));
- assertEquals("3:30am", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
+ assertEquals("3:30AM", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
DateUtils.FORMAT_12HOUR | DateUtils.FORMAT_SHOW_TIME));
assertEquals("03:30", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
DateUtils.FORMAT_24HOUR | DateUtils.FORMAT_SHOW_TIME));
@@ -188,14 +188,14 @@
assertEquals("Noon", DateUtils.formatDateRange(mContext, fixedTime + noonDuration,
fixedTime + noonDuration,
DateUtils.FORMAT_12HOUR | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_CAP_NOON));
- assertEquals("12:00pm", DateUtils.formatDateRange(mContext, fixedTime + noonDuration,
+ assertEquals("12:00PM", DateUtils.formatDateRange(mContext, fixedTime + noonDuration,
fixedTime + noonDuration,
DateUtils.FORMAT_12HOUR | DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_SHOW_TIME));
- assertEquals("12:00am", DateUtils.formatDateRange(mContext, fixedTime - midnightDuration,
+ assertEquals("12:00AM", DateUtils.formatDateRange(mContext, fixedTime - midnightDuration,
fixedTime - midnightDuration,
DateUtils.FORMAT_12HOUR | DateUtils.FORMAT_SHOW_TIME
| DateUtils.FORMAT_NO_MIDNIGHT));
- assertEquals("3:30am", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
+ assertEquals("3:30AM", DateUtils.formatDateRange(mContext, fixedTime, fixedTime,
DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_UTC));
assertEquals("3am", DateUtils.formatDateRange(mContext, fixedTime - integralDuration,
fixedTime - integralDuration,
diff --git a/tests/tests/text/src/android/text/format/cts/TimeTest.java b/tests/tests/text/src/android/text/format/cts/TimeTest.java
index c1587ae..98ba55f 100644
--- a/tests/tests/text/src/android/text/format/cts/TimeTest.java
+++ b/tests/tests/text/src/android/text/format/cts/TimeTest.java
@@ -125,6 +125,49 @@
}
}
+ public void testParseNull() {
+ Time t = new Time();
+ try {
+ t.parse(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+
+ try {
+ t.parse3339(null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ // http://code.google.com/p/android/issues/detail?id=16002
+ // We'd leak one JNI global reference each time parsing failed.
+ // This would cause a crash when we filled the global reference table.
+ public void testBug16002() {
+ Time t = new Time();
+ for (int i = 0; i < 8192; ++i) {
+ try {
+ t.parse3339("xxx");
+ fail();
+ } catch (TimeFormatException expected) {
+ }
+ }
+ }
+
+ // http://code.google.com/p/android/issues/detail?id=22225
+ // We'd leak one JNI global reference each time parsing failed.
+ // This would cause a crash when we filled the global reference table.
+ public void testBug22225() {
+ Time t = new Time();
+ for (int i = 0; i < 8192; ++i) {
+ try {
+ t.parse("xxx");
+ fail();
+ } catch (TimeFormatException expected) {
+ }
+ }
+ }
+
public void testIsEpoch() {
Time time = new Time();
assertTrue(Time.isEpoch(time));
diff --git a/tests/tests/view/src/android/view/cts/GravityTest.java b/tests/tests/view/src/android/view/cts/GravityTest.java
index 86bbb2c..86b1283 100644
--- a/tests/tests/view/src/android/view/cts/GravityTest.java
+++ b/tests/tests/view/src/android/view/cts/GravityTest.java
@@ -16,6 +16,7 @@
package android.view.cts;
+import android.test.suitebuilder.annotation.SmallTest;
import android.view.View;
import android.graphics.Rect;
@@ -288,4 +289,55 @@
assertEquals(30, inoutRect.top);
assertEquals(50, inoutRect.bottom);
}
+
+ @SmallTest
+ public void testGetAbsoluteGravity() throws Exception {
+ assertOneGravity(Gravity.LEFT, Gravity.LEFT, false);
+ assertOneGravity(Gravity.LEFT, Gravity.LEFT, true);
+
+ assertOneGravity(Gravity.RIGHT, Gravity.RIGHT, false);
+ assertOneGravity(Gravity.RIGHT, Gravity.RIGHT, true);
+
+ assertOneGravity(Gravity.TOP, Gravity.TOP, false);
+ assertOneGravity(Gravity.TOP, Gravity.TOP, true);
+
+ assertOneGravity(Gravity.BOTTOM, Gravity.BOTTOM, false);
+ assertOneGravity(Gravity.BOTTOM, Gravity.BOTTOM, true);
+
+ assertOneGravity(Gravity.CENTER_VERTICAL, Gravity.CENTER_VERTICAL, false);
+ assertOneGravity(Gravity.CENTER_VERTICAL, Gravity.CENTER_VERTICAL, true);
+
+ assertOneGravity(Gravity.CENTER_HORIZONTAL, Gravity.CENTER_HORIZONTAL, false);
+ assertOneGravity(Gravity.CENTER_HORIZONTAL, Gravity.CENTER_HORIZONTAL, true);
+
+ assertOneGravity(Gravity.CENTER, Gravity.CENTER, false);
+ assertOneGravity(Gravity.CENTER, Gravity.CENTER, true);
+
+ assertOneGravity(Gravity.FILL_VERTICAL, Gravity.FILL_VERTICAL, false);
+ assertOneGravity(Gravity.FILL_VERTICAL, Gravity.FILL_VERTICAL, true);
+
+ assertOneGravity(Gravity.FILL_HORIZONTAL, Gravity.FILL_HORIZONTAL, false);
+ assertOneGravity(Gravity.FILL_HORIZONTAL, Gravity.FILL_HORIZONTAL, true);
+
+ assertOneGravity(Gravity.FILL, Gravity.FILL, false);
+ assertOneGravity(Gravity.FILL, Gravity.FILL, true);
+
+ assertOneGravity(Gravity.CLIP_HORIZONTAL, Gravity.CLIP_HORIZONTAL, false);
+ assertOneGravity(Gravity.CLIP_HORIZONTAL, Gravity.CLIP_HORIZONTAL, true);
+
+ assertOneGravity(Gravity.CLIP_VERTICAL, Gravity.CLIP_VERTICAL, false);
+ assertOneGravity(Gravity.CLIP_VERTICAL, Gravity.CLIP_VERTICAL, true);
+
+ assertOneGravity(Gravity.LEFT, Gravity.START, false);
+ assertOneGravity(Gravity.RIGHT, Gravity.START, true);
+
+ assertOneGravity(Gravity.RIGHT, Gravity.END, false);
+ assertOneGravity(Gravity.LEFT, Gravity.END, true);
+ }
+
+ private void assertOneGravity(int expected, int initial, boolean isRtl) {
+ final int layoutDirection = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
+
+ assertEquals(expected, Gravity.getAbsoluteGravity(initial, layoutDirection));
+ }
}
diff --git a/tests/tests/view/src/android/view/cts/LocaleUtilTest.java b/tests/tests/view/src/android/view/cts/LocaleUtilTest.java
new file mode 100644
index 0000000..d80ebbe
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/LocaleUtilTest.java
@@ -0,0 +1,204 @@
+/*
+ * 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.view.cts;
+
+import android.test.AndroidTestCase;
+import android.util.LocaleUtil;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+
+import java.util.Locale;
+
+import static android.view.View.LAYOUT_DIRECTION_LTR;
+import static android.view.View.LAYOUT_DIRECTION_RTL;
+
+/**
+ * Test {@link LocaleUtil}.
+ */
+public class LocaleUtilTest extends AndroidTestCase {
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "getLayoutDirectionFromLocale",
+ args = {Locale.class}
+ )
+ public void testGetLayoutDirectionFromLocale() {
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(null));
+
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.ENGLISH));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.FRANCE));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.FRENCH));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMAN));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMANY));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALIAN));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALY));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.UK));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.US));
+
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.ROOT));
+
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINA));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINESE));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPAN));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPANESE));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREA));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREAN));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.PRC));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.TAIWAN));
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE));
+
+ Locale locale = new Locale("ar");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "AE");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "BH");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "DZ");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "EG");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "IQ");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "JO");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "KW");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "LB");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "LY");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "MA");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "OM");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "QA");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "SA");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "SD");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "SY");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "TN");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ar", "YE");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+ locale = new Locale("fa");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("fa", "AF");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("fa", "IR");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+ locale = new Locale("iw");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("iw", "IL");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("he");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("he", "IL");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+ locale = new Locale("pa_Arab");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("pa_Arab", "PK");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+ locale = new Locale("ps");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ps", "AF");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+ locale = new Locale("ur");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ur", "IN");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("ur", "PK");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+ locale = new Locale("uz_Arab");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ locale = new Locale("uz_Arab", "AF");
+ assertEquals(LAYOUT_DIRECTION_RTL,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+
+ // Locale without a real language
+ locale = new Locale("zz");
+ assertEquals(LAYOUT_DIRECTION_LTR,
+ LocaleUtil.getLayoutDirectionFromLocale(locale));
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupTest.java b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
index e975a27..1fc9a88 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
@@ -1496,6 +1496,8 @@
assertEquals(0, vg.getPaddingTop());
assertEquals(0, vg.getPaddingLeft());
assertEquals(0, vg.getPaddingRight());
+ assertEquals(0, vg.getPaddingStart());
+ assertEquals(0, vg.getPaddingEnd());
vg.setPadding(left, top, right, bottom);
@@ -1503,6 +1505,83 @@
assertEquals(top, vg.getPaddingTop());
assertEquals(left, vg.getPaddingLeft());
assertEquals(right, vg.getPaddingRight());
+
+ assertEquals(left, vg.getPaddingStart());
+ assertEquals(right, vg.getPaddingEnd());
+ assertEquals(false, vg.isPaddingRelative());
+
+ // force RTL direction
+ vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+ assertEquals(bottom, vg.getPaddingBottom());
+ assertEquals(top, vg.getPaddingTop());
+ assertEquals(left, vg.getPaddingLeft());
+ assertEquals(right, vg.getPaddingRight());
+
+ assertEquals(right, vg.getPaddingStart());
+ assertEquals(left, vg.getPaddingEnd());
+ assertEquals(false, vg.isPaddingRelative());
+ }
+
+ public void testSetPaddingRelative() {
+ final int start = 1;
+ final int top = 2;
+ final int end = 3;
+ final int bottom = 4;
+
+ MockViewGroup vg = new MockViewGroup(mContext);
+
+ assertEquals(0, vg.getPaddingBottom());
+ assertEquals(0, vg.getPaddingTop());
+ assertEquals(0, vg.getPaddingLeft());
+ assertEquals(0, vg.getPaddingRight());
+ assertEquals(0, vg.getPaddingStart());
+ assertEquals(0, vg.getPaddingEnd());
+
+ vg.setPaddingRelative(start, top, end, bottom);
+
+ assertEquals(bottom, vg.getPaddingBottom());
+ assertEquals(top, vg.getPaddingTop());
+ assertEquals(start, vg.getPaddingLeft());
+ assertEquals(end, vg.getPaddingRight());
+
+ assertEquals(start, vg.getPaddingStart());
+ assertEquals(end, vg.getPaddingEnd());
+ assertEquals(true, vg.isPaddingRelative());
+
+ // force RTL direction after setting relative padding
+ vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+ assertEquals(bottom, vg.getPaddingBottom());
+ assertEquals(top, vg.getPaddingTop());
+ assertEquals(end, vg.getPaddingLeft());
+ assertEquals(start, vg.getPaddingRight());
+
+ assertEquals(start, vg.getPaddingStart());
+ assertEquals(end, vg.getPaddingEnd());
+ assertEquals(true, vg.isPaddingRelative());
+
+ // force RTL direction before setting relative padding
+ vg = new MockViewGroup(mContext);
+ vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+ assertEquals(0, vg.getPaddingBottom());
+ assertEquals(0, vg.getPaddingTop());
+ assertEquals(0, vg.getPaddingLeft());
+ assertEquals(0, vg.getPaddingRight());
+ assertEquals(0, vg.getPaddingStart());
+ assertEquals(0, vg.getPaddingEnd());
+
+ vg.setPaddingRelative(start, top, end, bottom);
+
+ assertEquals(bottom, vg.getPaddingBottom());
+ assertEquals(top, vg.getPaddingTop());
+ assertEquals(end, vg.getPaddingLeft());
+ assertEquals(start, vg.getPaddingRight());
+
+ assertEquals(start, vg.getPaddingStart());
+ assertEquals(end, vg.getPaddingEnd());
+ assertEquals(true, vg.isPaddingRelative());
}
public void testSetPersistentDrawingCache() {
diff --git a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
index d92fd9b..397735f 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
@@ -81,7 +81,92 @@
assertEquals(120, mMarginLayoutParams.rightMargin);
assertEquals(140, mMarginLayoutParams.bottomMargin);
- assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.startMargin);
- assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.endMargin);
+ assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.getMarginStart());
+ assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.getMarginEnd());
+
+ assertEquals(false, mMarginLayoutParams.isMarginRelative());
+ }
+
+ public void testSetMarginsRelative() {
+ // create a new MarginLayoutParams instance
+ mMarginLayoutParams = new ViewGroup.MarginLayoutParams(320, 480);
+ mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+ assertEquals(20, mMarginLayoutParams.getMarginStart());
+ assertEquals(30, mMarginLayoutParams.topMargin);
+ assertEquals(120, mMarginLayoutParams.getMarginEnd());
+ assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+ assertEquals(0, mMarginLayoutParams.leftMargin);
+ assertEquals(0, mMarginLayoutParams.rightMargin);
+
+ assertEquals(true, mMarginLayoutParams.isMarginRelative());
+ }
+
+ public void testResolveMarginsRelative() {
+ ViewGroup vg = new LinearLayout(mContext);
+
+ // LTR / normal margin case
+ mMarginLayoutParams = new ViewGroup.MarginLayoutParams(320, 480);
+ mMarginLayoutParams.setMargins(20, 30, 120, 140);
+ vg.setLayoutParams(mMarginLayoutParams);
+ vg.requestLayout();
+
+ assertEquals(20, mMarginLayoutParams.leftMargin);
+ assertEquals(30, mMarginLayoutParams.topMargin);
+ assertEquals(120, mMarginLayoutParams.rightMargin);
+ assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+ assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.getMarginStart());
+ assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.getMarginEnd());
+
+ assertEquals(false, mMarginLayoutParams.isMarginRelative());
+
+ // LTR / relative margin case
+ mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+ vg.setLayoutParams(mMarginLayoutParams);
+ vg.requestLayout();
+
+ assertEquals(20, mMarginLayoutParams.getMarginStart());
+ assertEquals(30, mMarginLayoutParams.topMargin);
+ assertEquals(120, mMarginLayoutParams.getMarginEnd());
+ assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+ assertEquals(20, mMarginLayoutParams.leftMargin);
+ assertEquals(120, mMarginLayoutParams.rightMargin);
+
+ assertEquals(true, mMarginLayoutParams.isMarginRelative());
+
+ // RTL / normal margin case
+ vg.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+ mMarginLayoutParams = new ViewGroup.MarginLayoutParams(320, 480);
+ mMarginLayoutParams.setMargins(20, 30, 120, 140);
+ vg.setLayoutParams(mMarginLayoutParams);
+ vg.requestLayout();
+
+ assertEquals(20, mMarginLayoutParams.leftMargin);
+ assertEquals(30, mMarginLayoutParams.topMargin);
+ assertEquals(120, mMarginLayoutParams.rightMargin);
+ assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+ assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.getMarginStart());
+ assertEquals(Integer.MIN_VALUE, mMarginLayoutParams.getMarginEnd());
+
+ assertEquals(false, mMarginLayoutParams.isMarginRelative());
+
+ // RTL / relative margin case
+ mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+ vg.setLayoutParams(mMarginLayoutParams);
+ vg.requestLayout();
+
+ assertEquals(20, mMarginLayoutParams.getMarginStart());
+ assertEquals(30, mMarginLayoutParams.topMargin);
+ assertEquals(120, mMarginLayoutParams.getMarginEnd());
+ assertEquals(140, mMarginLayoutParams.bottomMargin);
+
+ assertEquals(120, mMarginLayoutParams.leftMargin);
+ assertEquals(20, mMarginLayoutParams.rightMargin);
+
+ assertEquals(true, mMarginLayoutParams.isMarginRelative());
}
}
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 9065592..288552d 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -61,7 +61,7 @@
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
-import android.view.WindowManagerImpl;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
@@ -2730,7 +2730,8 @@
Rect outRect = new Rect();
View view = new View(mActivity);
// mAttachInfo is null
- Display d = WindowManagerImpl.getDefault().getDefaultDisplay();
+ WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
+ Display d = wm.getDefaultDisplay();
view.getWindowVisibleDisplayFrame(outRect);
assertEquals(0, outRect.left);
assertEquals(0, outRect.top);
@@ -3388,11 +3389,6 @@
public void childAccessibilityStateChanged(View child) {
}
-
- @Override
- public View findViewToTakeAccessibilityFocusFromHover(View child, View descendant) {
- return null;
- }
}
private final class OnCreateContextMenuListenerImpl implements OnCreateContextMenuListener {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 1bc8a4f..054217e 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -235,9 +235,6 @@
Thread.sleep(100); // Wait for open to be received on the icon db thread.
assertEquals(WebSettings.LOAD_DEFAULT, mSettings.getCacheMode());
- mSettings.setCacheMode(WebSettings.LOAD_NORMAL);
- assertEquals(WebSettings.LOAD_NORMAL, mSettings.getCacheMode());
-
mSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
assertEquals(WebSettings.LOAD_CACHE_ELSE_NETWORK, mSettings.getCacheMode());
final IconListenerClient iconListener = new IconListenerClient();
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 3f7ea78..6c66f52 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -45,6 +45,7 @@
import android.webkit.CacheManager.CacheResult;
import android.webkit.ConsoleMessage;
import android.webkit.DownloadListener;
+import android.webkit.JavascriptInterface;
import android.webkit.SslErrorHandler;
import android.webkit.WebBackForwardList;
import android.webkit.WebChromeClient;
@@ -411,6 +412,7 @@
return mWasProvideResultCalled;
}
+ @JavascriptInterface
public synchronized void provideResult(String result) {
mWasProvideResultCalled = true;
mResult = result;
@@ -483,9 +485,12 @@
public void testUseRemovedJavascriptInterface() throws Throwable {
class RemovedObject {
@Override
+ @JavascriptInterface
public String toString() {
return "removedObject";
}
+
+ @JavascriptInterface
public void remove() throws Throwable {
mOnUiThread.removeJavascriptInterface("removedObject");
System.gc();
@@ -494,6 +499,8 @@
class ResultObject {
private String mResult;
private boolean mIsResultAvailable;
+
+ @JavascriptInterface
public synchronized void setResult(String result) {
mResult = result;
mIsResultAvailable = true;
@@ -1170,6 +1177,7 @@
final class ImageLoaded {
public boolean mImageLoaded;
+ @JavascriptInterface
public void loaded() {
mImageLoaded = true;
}
@@ -1769,6 +1777,8 @@
public void testPauseResumeTimers() throws Throwable {
class Monitor {
private boolean mIsUpdated;
+
+ @JavascriptInterface
public synchronized void update() {
mIsUpdated = true;
notify();
diff --git a/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java b/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
index 760a160..0198b10 100755
--- a/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AutoCompleteTextViewTest.java
@@ -515,13 +515,11 @@
// re-set 'clicked' flag to false
listener.clearItemClickedStatus();
-
runTestOnUiThread(new Runnable() {
public void run() {
mAutoCompleteTextView.showDropDown();
}
});
- mInstrumentation.waitForIdleSync();
mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
assertTrue(listener.isOnItemClicked());
@@ -534,7 +532,6 @@
mAutoCompleteTextView.showDropDown();
}
});
- mInstrumentation.waitForIdleSync();
mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
// Test normal key code.
mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
@@ -550,7 +547,7 @@
mAutoCompleteTextView.dismissDropDown();
}
});
- mInstrumentation.waitForIdleSync();
+
mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_ENTER);
assertFalse(listener.isOnItemClicked());
diff --git a/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java b/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java
new file mode 100644
index 0000000..2c4c798
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/LayoutDirectionTest.java
@@ -0,0 +1,179 @@
+/*
+ * 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.widget.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.ViewGroup;
+import android.widget.*;
+import com.android.cts.stub.R;
+
+import static android.view.View.LAYOUT_DIRECTION_LTR;
+import static android.view.View.LAYOUT_DIRECTION_RTL;
+import static android.view.View.LAYOUT_DIRECTION_INHERIT;
+import static android.view.View.LAYOUT_DIRECTION_LOCALE;
+
+public class LayoutDirectionTest extends ActivityInstrumentationTestCase2<LayoutDirectionStubActivity> {
+
+ public LayoutDirectionTest() {
+ super(LayoutDirectionStubActivity.class);
+ }
+
+ private void checkDefaultDirectionForOneLayoutWithCode(ViewGroup vg) {
+ assertEquals(LAYOUT_DIRECTION_INHERIT, vg.getLayoutDirection());
+ assertEquals(LAYOUT_DIRECTION_LTR, vg.getResolvedLayoutDirection());
+ }
+
+ @UiThreadTest
+ public void testLayoutDirectionDefaults() {
+ checkDefaultDirectionForOneLayoutWithCode(new LinearLayout(getActivity()));
+ checkDefaultDirectionForOneLayoutWithCode(new FrameLayout(getActivity()));
+ checkDefaultDirectionForOneLayoutWithCode(new TableLayout(getActivity()));
+ checkDefaultDirectionForOneLayoutWithCode(new RelativeLayout(getActivity()));
+ checkDefaultDirectionForOneLayoutWithCode(new GridLayout(getActivity()));
+ }
+
+ private void checkDirectionForOneLayoutWithCode(ViewGroup vg) {
+ vg.setLayoutDirection(LAYOUT_DIRECTION_LTR);
+ assertEquals(LAYOUT_DIRECTION_LTR, vg.getLayoutDirection());
+ assertEquals(LAYOUT_DIRECTION_LTR, vg.getResolvedLayoutDirection());
+
+ vg.setLayoutDirection(LAYOUT_DIRECTION_RTL);
+ assertEquals(LAYOUT_DIRECTION_RTL, vg.getLayoutDirection());
+ assertEquals(LAYOUT_DIRECTION_RTL, vg.getResolvedLayoutDirection());
+
+ vg.setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
+ assertEquals(LAYOUT_DIRECTION_LOCALE, vg.getLayoutDirection());
+ // running with English locale
+ assertEquals(LAYOUT_DIRECTION_LTR, vg.getResolvedLayoutDirection());
+
+ vg.setLayoutDirection(LAYOUT_DIRECTION_INHERIT);
+ assertEquals(LAYOUT_DIRECTION_INHERIT, vg.getLayoutDirection());
+ // default is LTR
+ assertEquals(LAYOUT_DIRECTION_LTR, vg.getResolvedLayoutDirection());
+ }
+
+ @UiThreadTest
+ public void testDirectionForAllLayoutsWithCode() {
+ checkDirectionForOneLayoutWithCode(new LinearLayout(getActivity()));
+ checkDirectionForOneLayoutWithCode(new FrameLayout(getActivity()));
+ checkDirectionForOneLayoutWithCode(new TableLayout(getActivity()));
+ checkDirectionForOneLayoutWithCode(new RelativeLayout(getActivity()));
+ checkDirectionForOneLayoutWithCode(new GridLayout(getActivity()));
+ }
+
+ private void checkDirectionInheritanceForOneLayoutWithCode(ViewGroup parent) {
+ LinearLayout child = new LinearLayout(getActivity());
+ child.setLayoutDirection(LAYOUT_DIRECTION_INHERIT);
+ parent.addView(child);
+
+ // Parent is LTR
+ parent.setLayoutDirection(LAYOUT_DIRECTION_LTR);
+
+ assertEquals(LAYOUT_DIRECTION_LTR, parent.getLayoutDirection());
+ assertEquals(LAYOUT_DIRECTION_LTR, parent.getResolvedLayoutDirection());
+
+ assertEquals(LAYOUT_DIRECTION_INHERIT, child.getLayoutDirection());
+ assertEquals(LAYOUT_DIRECTION_LTR, child.getResolvedLayoutDirection());
+
+ // Parent is RTL
+ parent.setLayoutDirection(LAYOUT_DIRECTION_RTL);
+
+ assertEquals(LAYOUT_DIRECTION_RTL, parent.getLayoutDirection());
+ assertEquals(LAYOUT_DIRECTION_RTL, parent.getResolvedLayoutDirection());
+
+ assertEquals(LAYOUT_DIRECTION_INHERIT, child.getLayoutDirection());
+ assertEquals(LAYOUT_DIRECTION_RTL, child.getResolvedLayoutDirection());
+ }
+
+ @UiThreadTest
+ public void testDirectionInheritanceForAllLayoutsWithCode() {
+ checkDirectionInheritanceForOneLayoutWithCode(new LinearLayout(getActivity()));
+ checkDirectionInheritanceForOneLayoutWithCode(new FrameLayout(getActivity()));
+ checkDirectionInheritanceForOneLayoutWithCode(new TableLayout(getActivity()));
+ checkDirectionInheritanceForOneLayoutWithCode(new RelativeLayout(getActivity()));
+ checkDirectionInheritanceForOneLayoutWithCode(new GridLayout(getActivity()));
+ }
+
+ private void checkDirectionForOneLayoutFromXml(int parentId, int parentDir, int parentResDir,
+ int child1Id, int child1Dir, int child1ResDir,
+ int child2Id, int child2Dir, int child2ResDir,
+ int child3Id, int child3Dir, int child3ResDir,
+ int child4Id, int child4Dir, int child4ResDir) {
+ ViewGroup ll = (ViewGroup) getActivity().findViewById(parentId);
+ assertEquals(parentDir, ll.getLayoutDirection());
+ assertEquals(parentResDir, ll.getResolvedLayoutDirection());
+
+ ViewGroup child1 = (ViewGroup) getActivity().findViewById(child1Id);
+ assertEquals(child1Dir, child1.getLayoutDirection());
+ assertEquals(child1ResDir, child1.getResolvedLayoutDirection());
+
+ ViewGroup child2 = (ViewGroup) getActivity().findViewById(child2Id);
+ assertEquals(child2Dir, child2.getLayoutDirection());
+ assertEquals(child2ResDir, child2.getResolvedLayoutDirection());
+
+ ViewGroup child3 = (ViewGroup) getActivity().findViewById(child3Id);
+ assertEquals(child3Dir, child3.getLayoutDirection());
+ assertEquals(child3ResDir, child3.getResolvedLayoutDirection());
+
+ ViewGroup child4 = (ViewGroup) getActivity().findViewById(child4Id);
+ assertEquals(child4Dir, child4.getLayoutDirection());
+ assertEquals(child4ResDir, child4.getResolvedLayoutDirection());
+ }
+
+ @UiThreadTest
+ public void testDirectionFromXml() {
+ // We only test LinearLayout as the others would be the same (they extend ViewGroup / View)
+ checkDirectionForOneLayoutFromXml(
+ R.id.layout_linearlayout_ltr, LAYOUT_DIRECTION_LTR, LAYOUT_DIRECTION_LTR,
+ R.id.layout_linearlayout_ltr_child_1, LAYOUT_DIRECTION_LTR, LAYOUT_DIRECTION_LTR,
+ R.id.layout_linearlayout_ltr_child_2, LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_RTL,
+ // parent is LTR
+ R.id.layout_linearlayout_ltr_child_3, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LTR,
+ // running with English locale
+ R.id.layout_linearlayout_ltr_child_4, LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR);
+
+ checkDirectionForOneLayoutFromXml(
+ R.id.layout_linearlayout_rtl, LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_RTL,
+ R.id.layout_linearlayout_rtl_child_1, LAYOUT_DIRECTION_LTR, LAYOUT_DIRECTION_LTR,
+ R.id.layout_linearlayout_rtl_child_2, LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_RTL,
+ // parent is RTL
+ R.id.layout_linearlayout_rtl_child_3, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_RTL,
+ // running with English locale
+ R.id.layout_linearlayout_rtl_child_4, LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR);
+
+ checkDirectionForOneLayoutFromXml(
+ // default is LTR
+ R.id.layout_linearlayout_inherit, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LTR,
+ R.id.layout_linearlayout_inherit_child_1, LAYOUT_DIRECTION_LTR, LAYOUT_DIRECTION_LTR,
+ R.id.layout_linearlayout_inherit_child_2, LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_RTL,
+ // parent is LTR
+ R.id.layout_linearlayout_inherit_child_3, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LTR,
+ // running with English locale
+ R.id.layout_linearlayout_inherit_child_4, LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR);
+
+ checkDirectionForOneLayoutFromXml(
+ // running with English locale
+ R.id.layout_linearlayout_locale, LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR,
+ R.id.layout_linearlayout_locale_child_1, LAYOUT_DIRECTION_LTR, LAYOUT_DIRECTION_LTR,
+ R.id.layout_linearlayout_locale_child_2, LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_RTL,
+ // parent is LTR
+ R.id.layout_linearlayout_locale_child_3, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LTR,
+ // running with English locale
+ R.id.layout_linearlayout_locale_child_4, LAYOUT_DIRECTION_LOCALE, LAYOUT_DIRECTION_LTR);
+ }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java b/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java
index a7593c4..f7baab7 100644
--- a/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RadioGroupTest.java
@@ -102,9 +102,9 @@
assertEquals(View.NO_ID, newButton.getId());
mDefaultRadioGroup.addView(newButton, new RadioGroup.LayoutParams(
RadioGroup.LayoutParams.WRAP_CONTENT, RadioGroup.LayoutParams.WRAP_CONTENT));
- // set the id with hashCode
- // (PassThroughHierarchyChangeListener's behaviour when button is added)
- assertEquals(newButton.hashCode(), newButton.getId());
+ // aapt-generated IDs have a nonzero high byte; check that the ID generated by
+ // RadioGroup falls within a range that will not collide with aapt IDs.
+ assertEquals(0, newButton.getId() & 0xFF000000);
}
public void testInternalCheckedStateTracker() {
diff --git a/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java b/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
index 4c9d2ab..e034562 100644
--- a/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
@@ -160,6 +160,167 @@
assertEquals(R.id.relative_view3, rules[RelativeLayout.ALIGN_BOTTOM]);
}
+ public void testStartEnd() {
+ RelativeLayout.LayoutParams layoutParams;
+
+ // Test RelativeLayout.Params which generated from the xml file.
+ int rules[];
+ RelativeLayoutStubActivity activity = getActivity();
+
+ // test attributes used in RelativeLayout.
+ RelativeLayout relativeLayout = (RelativeLayout) activity.findViewById(
+ R.id.relative_sublayout_attrs_2);
+
+ // view1, centered within its parent.
+ // TEST: android:layout_centerInParent
+ View view1 = activity.findViewById(R.id.relative_view21);
+ ViewAsserts.assertHorizontalCenterAligned(relativeLayout, view1);
+ ViewAsserts.assertVerticalCenterAligned(relativeLayout, view1);
+ layoutParams = (RelativeLayout.LayoutParams) (view1.getLayoutParams());
+ rules = layoutParams.getRules();
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_IN_PARENT]);
+
+ // view2, below view1 and has same left position with view1.
+ // TEST: android:layout_below; android:layout_alignStart
+ View view2 = activity.findViewById(R.id.relative_view22);
+ ViewAsserts.assertLeftAligned(view1, view2);
+ assertEquals(view1.getBottom(), view2.getTop());
+ layoutParams = (RelativeLayout.LayoutParams) (view2.getLayoutParams());
+ rules = layoutParams.getRules();
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.BELOW]);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_START]);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_LEFT]);
+ assertEquals(0, rules[RelativeLayout.ALIGN_RIGHT]);
+ rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.BELOW]);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_START]);
+ assertEquals(0, rules[RelativeLayout.ALIGN_LEFT]);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_RIGHT]);
+
+ // view3, has same top position with view1 and same bottom position with view2,
+ // and on the right of view1.1.
+ // TEST: android:layout_alignTop; android:layout_alignBottom; android:layout_toEndOf
+ View view3 = activity.findViewById(R.id.relative_view23);
+ ViewAsserts.assertTopAligned(view1, view3);
+ ViewAsserts.assertBottomAligned(view2, view3);
+ assertEquals(view1.getRight(), view3.getLeft());
+ layoutParams = (RelativeLayout.LayoutParams) (view3.getLayoutParams());
+ rules = layoutParams.getRules();
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_TOP]);
+ assertEquals(R.id.relative_view22, rules[RelativeLayout.ALIGN_BOTTOM]);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.END_OF]);
+ assertEquals(0, rules[RelativeLayout.LEFT_OF]);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.RIGHT_OF]);
+ rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_TOP]);
+ assertEquals(R.id.relative_view22, rules[RelativeLayout.ALIGN_BOTTOM]);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.END_OF]);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.LEFT_OF]);
+ assertEquals(0, rules[RelativeLayout.RIGHT_OF]);
+
+ // view4, has same right position with view3 and above view3.
+ // TEST: android:layout_alignEnd; android:layout_above
+ View view4 = activity.findViewById(R.id.relative_view24);
+ ViewAsserts.assertRightAligned(view3, view4);
+ assertEquals(view3.getTop(), view4.getBottom());
+ layoutParams = (RelativeLayout.LayoutParams) (view4.getLayoutParams());
+ rules = layoutParams.getRules();
+ assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_END]);
+ assertEquals(0, rules[RelativeLayout.ALIGN_LEFT]);
+ assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_RIGHT]);
+ assertEquals(R.id.relative_view23, rules[RelativeLayout.ABOVE]);
+ rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+ assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_END]);
+ assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_LEFT]);
+ assertEquals(0, rules[RelativeLayout.ALIGN_RIGHT]);
+ assertEquals(R.id.relative_view23, rules[RelativeLayout.ABOVE]);
+
+ // view5 goes on the left-bottom.
+ // TEST: android:layout_alignParentBottom; android:layout_alignParentStart
+ View view5 = activity.findViewById(R.id.relative_view25);
+ ViewAsserts.assertLeftAligned(relativeLayout, view5);
+ ViewAsserts.assertBottomAligned(relativeLayout, view5);
+ layoutParams = (RelativeLayout.LayoutParams) (view5.getLayoutParams());
+ rules = layoutParams.getRules();
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_BOTTOM]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_START]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
+ assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
+ rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_BOTTOM]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_START]);
+ assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
+
+ // view6 goes on the top-right.
+ // TEST: android:layout_alignParentTop; android:layout_alignParentEnd
+ View view6 = activity.findViewById(R.id.relative_view26);
+ ViewAsserts.assertTopAligned(relativeLayout, view6);
+ ViewAsserts.assertRightAligned(relativeLayout, view6);
+ layoutParams = (RelativeLayout.LayoutParams) (view6.getLayoutParams());
+ rules = layoutParams.getRules();
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_TOP]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_END]);
+ assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
+ rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_TOP]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_END]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
+ assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
+
+ // view7, has same baseline with view6 and centered horizontally within its parent.
+ // TEST: android:layout_alignBaseline; android:layout_centerHorizontal
+ View view7 = activity.findViewById(R.id.relative_view27);
+ ViewAsserts.assertBaselineAligned(view6, view7);
+ ViewAsserts.assertHorizontalCenterAligned(relativeLayout, view7);
+ layoutParams = (RelativeLayout.LayoutParams) (view7.getLayoutParams());
+ rules = layoutParams.getRules();
+ assertEquals(R.id.relative_view26, rules[RelativeLayout.ALIGN_BASELINE]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_HORIZONTAL]);
+ rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+ assertEquals(R.id.relative_view26, rules[RelativeLayout.ALIGN_BASELINE]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_HORIZONTAL]);
+
+ // view8, centered vertically within its parent and on the left of view1.
+ // TEST: android:layout_toStartOf; android:layout_centerVertical
+ View view8 = activity.findViewById(R.id.relative_view28);
+ ViewAsserts.assertVerticalCenterAligned(relativeLayout, view8);
+ assertEquals(view1.getLeft(), view8.getRight());
+ layoutParams = (RelativeLayout.LayoutParams) (view8.getLayoutParams());
+ rules = layoutParams.getRules();
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.START_OF]);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.LEFT_OF]);
+ assertEquals(0, rules[RelativeLayout.RIGHT_OF]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_VERTICAL]);
+ rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.START_OF]);
+ assertEquals(0, rules[RelativeLayout.LEFT_OF]);
+ assertEquals(R.id.relative_view21, rules[RelativeLayout.RIGHT_OF]);
+ assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_VERTICAL]);
+
+ // view9, has same top and bottom position with view3 and same left position with its parent
+ // TEST: android:layout_alignStart; android:layout_alignTop; android:layout_alignBottom;
+ // android:layout_alignWithParentIfMissing
+ View view9 = activity.findViewById(R.id.relative_view29);
+ ViewAsserts.assertTopAligned(view3, view9);
+ ViewAsserts.assertBottomAligned(view3, view9);
+ ViewAsserts.assertLeftAligned(relativeLayout, view9);
+ layoutParams = (RelativeLayout.LayoutParams) (view9.getLayoutParams());
+ rules = layoutParams.getRules();
+ assertEquals(R.id.gravity_bottom, rules[RelativeLayout.ALIGN_START]);
+ assertEquals(R.id.gravity_bottom, rules[RelativeLayout.ALIGN_LEFT]);
+ assertEquals(0, rules[RelativeLayout.ALIGN_RIGHT]);
+ assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_TOP]);
+ assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_BOTTOM]);
+ rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+ assertEquals(R.id.gravity_bottom, rules[RelativeLayout.ALIGN_START]);
+ assertEquals(0, rules[RelativeLayout.ALIGN_LEFT]);
+ assertEquals(R.id.gravity_bottom, rules[RelativeLayout.ALIGN_RIGHT]);
+ assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_TOP]);
+ assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_BOTTOM]);
+ }
+
public void testAccessRule1() {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(200, 300);
int rules[]= layoutParams.getRules();
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index e295c40..24a8440 100755
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -2984,6 +2984,299 @@
outText.text.toString());
}
+ @UiThreadTest
+ public void testTextDirectionDefault() {
+ TextView tv = new TextView(mActivity);
+ assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getTextDirection());
+ }
+
+ @UiThreadTest
+ public void testSetGetTextDirection() {
+ TextView tv = new TextView(mActivity);
+
+ tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+ assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+ assertEquals(View.TEXT_DIRECTION_INHERIT, tv.getTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+ assertEquals(View.TEXT_DIRECTION_LTR, tv.getTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+ assertEquals(View.TEXT_DIRECTION_RTL, tv.getTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+ assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
+ }
+
+ @UiThreadTest
+ public void testGetResolvedTextDirectionLtr() {
+ TextView tv = new TextView(mActivity);
+ tv.setText("this is a test");
+
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+ assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+ assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+ assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+ assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getResolvedTextDirection());
+ }
+
+ @UiThreadTest
+ public void testGetResolvedTextDirectionLtrWithInheritance() {
+ LinearLayout ll = new LinearLayout(mActivity);
+ ll.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+
+ TextView tv = new TextView(mActivity);
+ tv.setText("this is a test");
+ ll.addView(tv);
+
+ tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+ assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+ assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+ assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+ assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+ assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getResolvedTextDirection());
+ }
+
+ @UiThreadTest
+ public void testGetResolvedTextDirectionRtl() {
+ TextView tv = new TextView(mActivity);
+ tv.setText("\u05DD\u05DE"); // hebrew
+
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+ assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+ assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+ assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+ assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getResolvedTextDirection());
+ }
+
+ @UiThreadTest
+ public void testGetResolvedTextDirectionRtlWithInheritance() {
+ LinearLayout ll = new LinearLayout(mActivity);
+ ll.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+
+ TextView tv = new TextView(mActivity);
+ tv.setText("\u05DD\u05DE"); // hebrew
+ ll.addView(tv);
+
+ tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+ assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+ assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+ assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+ assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getResolvedTextDirection());
+
+ // Force to RTL text direction on the layout
+ ll.setTextDirection(View.TEXT_DIRECTION_RTL);
+
+ tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG);
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_ANY_RTL);
+ assertEquals(View.TEXT_DIRECTION_ANY_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+ assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LTR);
+ assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_RTL);
+ assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+ tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
+ assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getResolvedTextDirection());
+ }
+
+ @UiThreadTest
+ public void testResetTextDirection() {
+ LinearLayout ll = (LinearLayout) mActivity.findViewById(R.id.layout_textviewtest);
+ TextView tv = (TextView) mActivity.findViewById(R.id.textview_rtl);
+
+ ll.setTextDirection(View.TEXT_DIRECTION_RTL);
+ tv.setTextDirection(View.TEXT_DIRECTION_INHERIT);
+ assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
+
+ ll.removeView(tv);
+ assertEquals(View.TEXT_DIRECTION_FIRST_STRONG, tv.getResolvedTextDirection());
+ }
+
+ @UiThreadTest
+ public void testTextAlignmentDefault() {
+ TextView tv = new TextView(getActivity());
+ assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
+ // resolved default text alignment is GRAVITY
+ assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getResolvedTextAlignment());
+ }
+
+ @UiThreadTest
+ public void testSetGetTextAlignment() {
+ TextView tv = new TextView(getActivity());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
+ assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+ assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+ assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+ assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+ assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+ assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getTextAlignment());
+ }
+
+ @UiThreadTest
+ public void testGetResolvedTextAlignment() {
+ TextView tv = new TextView(getActivity());
+
+ assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getResolvedTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
+ assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getResolvedTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+ assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+ assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getResolvedTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+ assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getResolvedTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+ assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getResolvedTextAlignment());
+
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+ assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getResolvedTextAlignment());
+ }
+
+ @UiThreadTest
+ public void testGetResolvedTextAlignmentWithInheritance() {
+ LinearLayout ll = new LinearLayout(getActivity());
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
+
+ TextView tv = new TextView(getActivity());
+ ll.addView(tv);
+
+ // check defaults
+ assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getTextAlignment());
+ assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getResolvedTextAlignment());
+
+ // set inherit and check that child is following parent
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
+ assertEquals(View.TEXT_ALIGNMENT_INHERIT, tv.getTextAlignment());
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+ assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+ assertEquals(View.TEXT_ALIGNMENT_TEXT_START, tv.getResolvedTextAlignment());
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+ assertEquals(View.TEXT_ALIGNMENT_TEXT_END, tv.getResolvedTextAlignment());
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+ assertEquals(View.TEXT_ALIGNMENT_VIEW_START, tv.getResolvedTextAlignment());
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+ assertEquals(View.TEXT_ALIGNMENT_VIEW_END, tv.getResolvedTextAlignment());
+
+ // now get rid of the inheritance but still change the parent
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+ assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
+ assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
+ assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
+ assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END);
+ assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+ }
+
+ @UiThreadTest
+ public void testResetTextAlignment() {
+ TextViewStubActivity activity = getActivity();
+
+ LinearLayout ll = (LinearLayout) activity.findViewById(R.id.layout_textviewtest);
+ TextView tv = (TextView) activity.findViewById(R.id.textview_rtl);
+
+ ll.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
+ tv.setTextAlignment(View.TEXT_ALIGNMENT_INHERIT);
+ assertEquals(View.TEXT_ALIGNMENT_CENTER, tv.getResolvedTextAlignment());
+
+ ll.removeView(tv);
+ // default text alignment is GRAVITY
+ assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getResolvedTextAlignment());
+ }
+
private static class MockOnEditorActionListener implements OnEditorActionListener {
private boolean isOnEditorActionCalled;
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 995408a..592b145 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
@@ -65,10 +65,12 @@
List<String> sourcePath = new ArrayList<String>();
sourcePath.add("./frameworks/base/core/java");
sourcePath.add("./frameworks/base/test-runner/src");
- sourcePath.add("./libcore/junit/src/main/java");
+ sourcePath.add("./external/junit/src");
sourcePath.add("./development/tools/hosttestlib/src");
sourcePath.add("./libcore/dalvik/src/main/java");
sourcePath.add("./cts/tests/src");
+ // PTS adds PtsAndroidTestCase
+ sourcePath.add("./cts/suite/pts/deviceTests/ptsutil/src");
sourcePath.add(sourceDir.toString());
return join(sourcePath, ":");
}
diff --git a/tools/device-setup/TestDeviceSetup/Android.mk b/tools/device-setup/TestDeviceSetup/Android.mk
index 413f50b..5642736 100644
--- a/tools/device-setup/TestDeviceSetup/Android.mk
+++ b/tools/device-setup/TestDeviceSetup/Android.mk
@@ -21,6 +21,8 @@
LOCAL_MODULE_TAGS := optional
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+# and because it is in data, do not strip classes.dex
+LOCAL_DEX_PREOPT := false
LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/tools/tradefed-host/res/report/cts_result.xsl b/tools/tradefed-host/res/report/cts_result.xsl
index fd2b732..3dfd893 100644
--- a/tools/tradefed-host/res/report/cts_result.xsl
+++ b/tools/tradefed-host/res/report/cts_result.xsl
@@ -461,7 +461,7 @@
<TR>
<TH width="30%">Test</TH>
<TH width="5%">Result</TH>
- <TH>Failure Details</TH>
+ <TH>Failure Details / Details</TH>
</TR>
<!-- test case -->
@@ -526,6 +526,11 @@
<xsl:value-of select="@result"/>
</div>
</TD>
+ <TD class="failuredetails">
+ <div class="details">
+ <xsl:value-of select="FailedScene/@message"/>
+ </div>
+ </TD>
<TD class="failuredetails"></TD>
</xsl:if>
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
index 8029b75..3c46d9b 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
@@ -30,11 +30,17 @@
public class CtsBuildHelper {
static final String CTS_DIR_NAME = "android-cts";
+ static final String PTS_DIR_NAME = "android-pts";
+ static private boolean mCtsMode = true;
/** The root location of the extracted CTS package */
private final File mRootDir;
/** the {@link CTS_DIR_NAME} directory */
private final File mCtsDir;
+ public static void changeToPtsMode() {
+ mCtsMode = false;
+ }
+
/**
* Creates a {@link CtsBuildHelper}.
*
@@ -43,7 +49,7 @@
*/
public CtsBuildHelper(File rootDir) {
mRootDir = rootDir;
- mCtsDir = new File(mRootDir, CTS_DIR_NAME);
+ mCtsDir = new File(mRootDir, mCtsMode ? CTS_DIR_NAME : PTS_DIR_NAME);
}
/**
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
index 5ad7e25..f53507d 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
@@ -31,7 +31,7 @@
@Option(name="cts-install-path", description="the path to the cts installation to use")
private String mCtsRootDirPath = System.getProperty("CTS_ROOT");
- public static final String CTS_BUILD_VERSION = "4.1_r1";
+ public static final String CTS_BUILD_VERSION = "4.0_r1";
/**
* {@inheritDoc}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
index a815a48..8e59cc5 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
@@ -246,6 +246,11 @@
}
public static void main(String[] args) throws InterruptedException {
+ // change to PTS mode before anything else
+ String ptsMode = System.getProperty("PTS");
+ if ((ptsMode != null) && ptsMode.equals("1")) {
+ CtsBuildHelper.changeToPtsMode();
+ }
Console console = new CtsConsole();
Console.startConsole(console, args);
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
index 686c90a..839b34d 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/CtsXmlResultReporter.java
@@ -44,6 +44,8 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Writes results to an XML files in the CTS format.
@@ -96,6 +98,9 @@
private File mLogDir;
+ private static final String PTS_PERFORMANCE_EXCEPTION = "com.android.pts.util.PtsException";
+ private static final Pattern mPtsLogPattern = Pattern.compile(
+ "com\\.android\\.pts\\.util\\.PtsException:\\s(.*)");
public void setReportDir(File reportDir) {
mReportDir = reportDir;
}
@@ -216,7 +221,20 @@
*/
@Override
public void testFailed(TestFailure status, TestIdentifier test, String trace) {
- mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
+ if (trace.startsWith(PTS_PERFORMANCE_EXCEPTION)) { //PTS result
+ Test tst = mCurrentPkgResult.findTest(test);
+ // this exception is always thrown as exception is thrown from tearDown.
+ // Just ignore it.
+ if (tst.getName().endsWith("testAndroidTestCaseSetupProperly")) {
+ return;
+ }
+ Matcher m = mPtsLogPattern.matcher(trace);
+ if (m.find()) {
+ mCurrentPkgResult.reportPerformanceResult(test, CtsTestStatus.PASS, m.group(1));
+ }
+ } else {
+ mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
+ }
}
/**
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java
index 3c78df7..df1d4f1 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/Test.java
@@ -84,6 +84,10 @@
return mMessage;
}
+ public void setMessage(String message) {
+ mMessage = message;
+ }
+
public String getStartTime() {
return mStartTime;
}
@@ -125,14 +129,20 @@
serializer.attribute(CtsXmlResultReporter.ns, ENDTIME_ATTR, mEndTime);
if (mMessage != null) {
- serializer.startTag(CtsXmlResultReporter.ns, SCENE_TAG);
- serializer.attribute(CtsXmlResultReporter.ns, MESSAGE_ATTR, mMessage);
- if (mStackTrace != null) {
- serializer.startTag(CtsXmlResultReporter.ns, STACK_TAG);
- serializer.text(mStackTrace);
- serializer.endTag(CtsXmlResultReporter.ns, STACK_TAG);
+ if (mResult == CtsTestStatus.PASS) { // PTS will add performance result
+ serializer.startTag(CtsXmlResultReporter.ns, SCENE_TAG);
+ serializer.attribute(CtsXmlResultReporter.ns, MESSAGE_ATTR, mMessage);
+ serializer.endTag(CtsXmlResultReporter.ns, SCENE_TAG);
+ } else {
+ serializer.startTag(CtsXmlResultReporter.ns, SCENE_TAG);
+ serializer.attribute(CtsXmlResultReporter.ns, MESSAGE_ATTR, mMessage);
+ if (mStackTrace != null) {
+ serializer.startTag(CtsXmlResultReporter.ns, STACK_TAG);
+ serializer.text(mStackTrace);
+ serializer.endTag(CtsXmlResultReporter.ns, STACK_TAG);
+ }
+ serializer.endTag(CtsXmlResultReporter.ns, SCENE_TAG);
}
- serializer.endTag(CtsXmlResultReporter.ns, SCENE_TAG);
}
serializer.endTag(CtsXmlResultReporter.ns, TAG);
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java
index 23590e7..5997ec8 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestPackageResult.java
@@ -275,6 +275,18 @@
}
/**
+ * report performance result
+ * @param test
+ * @param status
+ * @param perf
+ */
+ public void reportPerformanceResult(TestIdentifier test, CtsTestStatus status, String perf) {
+ Test result = findTest(test);
+ result.setResultStatus(status);
+ result.setMessage(perf);
+ }
+
+ /**
* Report that the given test has completed.
*
* @param test
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 60c9084..77e93b1 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -54,20 +54,24 @@
def __init__(self, argv):
"""Initialize the CtsBuilder from command line arguments."""
- if not len(argv) == 6:
- print 'Usage: %s <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath>' % argv[0]
+ if not (len(argv) == 6 or len(argv)==7):
+ print 'Usage: %s <testRoot> <ctsOutputDir> <tempDir> <androidRootDir> <docletPath> [-pts]' % argv[0]
print ''
print 'testRoot: Directory under which to search for CTS tests.'
print 'ctsOutputDir: Directory in which the CTS repository should be created.'
print 'tempDir: Directory to use for storing temporary files.'
print 'androidRootDir: Root directory of the Android source tree.'
print 'docletPath: Class path where the DescriptionGenerator doclet can be found.'
+ print '-pts: generate plan for PTS.'
sys.exit(1)
self.test_root = sys.argv[1]
self.out_dir = sys.argv[2]
self.temp_dir = sys.argv[3]
self.android_root = sys.argv[4]
self.doclet_path = sys.argv[5]
+ self.isCts = True
+ if len(argv) ==7 and sys.argv[6] == "-pts":
+ self.isCts = False
self.test_repository = os.path.join(self.out_dir, 'repository/testcases')
self.plan_repository = os.path.join(self.out_dir, 'repository/plans')
@@ -99,6 +103,13 @@
doc = tools.XmlFile(description)
packages.append(doc.GetAttr('TestPackage', 'appPackageName'))
+ if not self.isCts: # PTS
+ plan = tools.TestPlan(packages)
+ plan.Include('.*')
+ plan.Exclude(r'android\.tests\.sigtest')
+ self.__WritePlan(plan, 'PTS')
+ return
+
plan = tools.TestPlan(packages)
plan.Exclude('android\.performance.*')
self.__WritePlan(plan, 'CTS')
@@ -124,6 +135,19 @@
plan.Include(r'android\.tests\.appsecurity')
self.__WritePlan(plan, 'AppSecurity')
+ # hard-coded white list for PDK plan
+ plan.Exclude('.*')
+ plan.Include('android\.bluetooth')
+ plan.Include('android\.graphics.*')
+ plan.Include('android\.hardware')
+ plan.Include('android\.media.*')
+ plan.Include('android\.net')
+ plan.Include('android\.opengl.*')
+ plan.Include('android\.renderscript')
+ plan.Include('android\.telephony')
+ plan.Include('android\.nativemedia.*')
+ self.__WritePlan(plan, 'PDK')
+
def LogGenerateDescription(name):
print 'Generating test description for package %s' % name
@@ -145,3 +169,4 @@
if result != 0:
sys.exit(result)
builder.GenerateTestPlans()
+
diff --git a/tools/utils/rerun.py b/tools/utils/rerun.py
new file mode 100644
index 0000000..86853a1
--- /dev/null
+++ b/tools/utils/rerun.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+import os
+import sys
+from xml.dom import Node
+from xml.dom import minidom
+
+def getChildrenWithTag(parent, tagName):
+ children = []
+ for child in parent.childNodes:
+ if (child.nodeType == Node.ELEMENT_NODE) and (child.tagName == tagName):
+ #print "parent " + parent.getAttribute("name") + " " + tagName +\
+ # " " + child.getAttribute("name")
+ children.append(child)
+ return children
+
+def parseSuite(suite, parentName):
+ if parentName != "":
+ parentName += '.'
+ failedCases = []
+ childSuites = getChildrenWithTag(suite, "TestSuite")
+ for child in childSuites:
+ for failure in parseSuite(child, parentName + child.getAttribute("name")):
+ failedCases.append(failure)
+ childTestCases = getChildrenWithTag(suite, "TestCase")
+ for child in childTestCases:
+ className = parentName + child.getAttribute("name")
+ for test in getChildrenWithTag(child, "Test"):
+ if test.getAttribute("result") != "pass":
+ failureName = className + "#" + test.getAttribute("name")
+ failedCases.append(failureName)
+ #if len(failedCases) > 0:
+ # print failedCases
+ return failedCases
+
+def getFailedCases(resultXml):
+ failedCases = []
+ doc = minidom.parse(resultXml)
+ testResult = doc.getElementsByTagName("TestResult")[0]
+ packages = getChildrenWithTag(testResult, "TestPackage")
+ for package in packages:
+ casesFromChild = parseSuite(package, "")
+ for case in casesFromChild:
+ if case not in failedCases:
+ failedCases.append(case)
+
+ return failedCases
+
+def main(argv):
+ if len(argv) < 3:
+ print "rerun.py cts_path result_xml [-s serial]"
+ print " cts_path should end with android-cts"
+ sys.exit(1)
+ ctsPath = os.path.abspath(argv[1])
+ resultXml = os.path.abspath(argv[2])
+ deviceSerial = ""
+ if len(argv) > 3:
+ if argv[3] == "-s":
+ deviceSerial = argv[4]
+
+ failedCases = getFailedCases(resultXml)
+ print "Re-run follwong cases:"
+ for failure in failedCases:
+ print " " + failure
+ for failure in failedCases:
+ [className, methodName] = failure.split('#')
+ command = ctsPath + "/tools/cts-tradefed run singleCommand cts"
+ if deviceSerial != "":
+ command += " --serial " + deviceSerial
+ command += " --class " + className + " --method " + methodName
+ print command
+ os.system(command)
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/tools/vm-tests-tf/Android.mk b/tools/vm-tests-tf/Android.mk
index 44dac66..88f2a53 100644
--- a/tools/vm-tests-tf/Android.mk
+++ b/tools/vm-tests-tf/Android.mk
@@ -18,7 +18,9 @@
# ============================================================
include $(CLEAR_VARS)
+# custom variables used to generate test description. do not touch!
LOCAL_TEST_TYPE := vmHostTest
+LOCAL_JAR_PATH := android.core.vm-tests-tf.jar
LOCAL_SRC_FILES := $(call all-java-files-under, src)