am 1550005c: Merge "CameraITS: Allocate more buffers for ITS" into lmp-sprout-dev
* commit '1550005c52831c5077973a45228afec8c0c139e7':
CameraITS: Allocate more buffers for ITS
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 721b9d4..b3b826d 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -107,7 +107,6 @@
CtsAdminTestCases \
CtsAnimationTestCases \
CtsAppTestCases \
- CtsAppWidgetTestCases \
CtsBluetoothTestCases \
CtsCalendarcommon2TestCases \
CtsContentTestCases \
@@ -174,6 +173,7 @@
CtsDevicePolicyManagerTestCases \
CtsHostJank \
CtsHostUi \
+ CtsJdwpSecurityHostTestCases \
CtsMonkeyTestCases \
CtsThemeHostTestCases \
CtsSecurityHostTestCases \
@@ -196,6 +196,7 @@
cts_device_jars := \
CtsDeviceJank \
+ CtsJdwpApp \
CtsPrintInstrument
cts_device_executables := \
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index aa3641f..e370c81 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -61,17 +61,18 @@
verifier-zip-name := $(verifier-dir-name).zip
verifier-zip := $(cts-dir)/$(verifier-zip-name)
-$(PRODUCT_OUT)/data/app/CtsVerifier.apk $(verifier-zip): $(verifier-dir)/power/execute_power_tests.py
-$(PRODUCT_OUT)/data/app/CtsVerifier.apk $(verifier-zip): $(verifier-dir)/power/power_monitors/monsoon.py
+# turned off sensor power tests in initial L release
+#$(PRODUCT_OUT)/data/app/CtsVerifier.apk $(verifier-zip): $(verifier-dir)/power/execute_power_tests.py
+#$(PRODUCT_OUT)/data/app/CtsVerifier.apk $(verifier-zip): $(verifier-dir)/power/power_monitors/monsoon.py
# Copy the necessary host-side scripts to include in the zip file:
-$(verifier-dir)/power/power_monitors/monsoon.py: cts/apps/CtsVerifier/assets/scripts/power_monitors/monsoon.py | $(ACP)
- $(hide) mkdir -p $(verifier-dir)/power/power_monitors
- $(hide) $(ACP) -fp cts/apps/CtsVerifier/assets/scripts/power_monitors/*.py $(verifier-dir)/power/power_monitors/.
-
-$(verifier-dir)/power/execute_power_tests.py: cts/apps/CtsVerifier/assets/scripts/execute_power_tests.py | $(ACP)
- $(hide) mkdir -p $(verifier-dir)/power
- $(hide) $(ACP) -fp cts/apps/CtsVerifier/assets/scripts/execute_power_tests.py $@
+#$(verifier-dir)/power/power_monitors/monsoon.py: cts/apps/CtsVerifier/assets/scripts/power_monitors/monsoon.py | $(ACP)
+# $(hide) mkdir -p $(verifier-dir)/power/power_monitors
+# $(hide) $(ACP) -fp cts/apps/CtsVerifier/assets/scripts/power_monitors/*.py $(verifier-dir)/power/power_monitors/.
+#
+#$(verifier-dir)/power/execute_power_tests.py: cts/apps/CtsVerifier/assets/scripts/execute_power_tests.py | $(ACP)
+# $(hide) mkdir -p $(verifier-dir)/power
+# $(hide) $(ACP) -fp cts/apps/CtsVerifier/assets/scripts/execute_power_tests.py $@
cts : $(verifier-zip)
ifeq ($(HOST_OS),linux)
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 0dd3a14..18dd5b3 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -17,8 +17,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.verifier"
- android:versionCode="3"
- android:versionName="5.0_r0.5">
+ android:versionCode="4"
+ android:versionName="5.0_r2">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="21"/>
@@ -100,6 +100,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
+ <meta-data android:name="test_required_features"
+ android:value="android.software.device_admin" />
</activity>
<!-- A generic activity for intent based tests -->
@@ -114,7 +116,7 @@
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
<meta-data android:name="test_excluded_features"
- android:value="android.hardware.type.television:android.software.leanback" />
+ android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
</activity>
<receiver android:name=".admin.TestDeviceAdminReceiver"
@@ -131,6 +133,8 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
+ <meta-data android:name="test_required_features"
+ android:value="android.software.backup" />
</activity>
<activity android:name=".bluetooth.BluetoothTestActivity"
@@ -153,6 +157,7 @@
</intent-filter>
<meta-data android:name="test_category" android:value="@string/bt_control" />
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
+ <meta-data android:name="test_excluded_features" android:value="android.software.leanback" />
</activity>
<activity android:name=".bluetooth.SecureServerActivity"
@@ -235,7 +240,8 @@
<service android:name=".bluetooth.BleScannerService"
android:label="@string/ble_scanner_service_name" />
- <activity android:name=".bluetooth.BleClientTestActivity"
+ <!-- TODO: Enable when test quality issues listed in b/18283088 is resolved -->
+ <!-- activity android:name=".bluetooth.BleClientTestActivity"
android:label="@string/ble_client_test_name"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
@@ -244,7 +250,9 @@
</intent-filter>
<meta-data android:name="test_category" android:value="@string/bt_le" />
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
- </activity>
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.bluetooth_le"/>
+ </activity -->
<activity android:name=".bluetooth.BleClientConnectActivity"
android:label="@string/ble_client_connect_name"
@@ -334,7 +342,8 @@
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BleClientTestActivity" />
</activity>
- <activity android:name=".bluetooth.BleServerStartActivity"
+ <!-- TODO: Enable when test quality issues listed in b/18283088 is resolved -->
+ <!-- activity android:name=".bluetooth.BleServerStartActivity"
android:label="@string/ble_server_start_name"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
@@ -343,9 +352,12 @@
</intent-filter>
<meta-data android:name="test_category" android:value="@string/bt_le" />
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
- </activity>
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.bluetooth_le"/>
+ </activity -->
- <activity android:name=".bluetooth.BleScannerTestActivity"
+ <!-- TODO: Enable when test quality issues listed in b/18282549 is resolved -->
+ <!-- activity android:name=".bluetooth.BleScannerTestActivity"
android:label="@string/ble_scanner_test_name"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
@@ -354,7 +366,9 @@
</intent-filter>
<meta-data android:name="test_category" android:value="@string/bt_le" />
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
- </activity>
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.bluetooth_le"/>
+ </activity -->
<activity android:name=".bluetooth.BleScannerPowerLevelActivity"
android:label="@string/ble_power_level_name"
@@ -378,7 +392,8 @@
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BleScannerTestActivity" />
</activity>
- <activity android:name=".bluetooth.BleAdvertiserTestActivity"
+ <!-- TODO: Enable when test quality issues listed in b/18282549 is resolved -->
+ <!-- activity android:name=".bluetooth.BleAdvertiserTestActivity"
android:label="@string/ble_advertiser_test_name"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
@@ -387,7 +402,9 @@
</intent-filter>
<meta-data android:name="test_category" android:value="@string/bt_le" />
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
- </activity>
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.bluetooth_le"/>
+ </activity -->
<activity android:name=".bluetooth.BleAdvertiserPowerLevelActivity"
android:label="@string/ble_power_level_name"
@@ -430,7 +447,7 @@
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_security" />
<meta-data android:name="test_excluded_features"
- android:value="android.hardware.type.television:android.software.leanback" />
+ android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
</activity>
<activity android:name=".streamquality.StreamingVideoActivity"
@@ -441,6 +458,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_streaming" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.watch" />
</activity>
<activity android:name=".streamquality.PlayVideoActivity"
@@ -794,8 +813,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_sensors" />
- <meta-data android:name="test_required_features"
- android:value="android.hardware.sensor.accelerometer" />
+ <meta-data android:name="test_applicable_features"
+ android:value="android.hardware.sensor.stepcounter:android.hardware.sensor.stepdetector:android.hardware.sensor.proximity:android.hardware.sensor.light" />
</activity>
<!-- TODO: enable when a more reliable way to identify time synchronization is available -->
@@ -819,6 +838,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST"/>
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_sensors"/>
+ <meta-data android:name="test_applicable_features"
+ android:value="android.hardware.sensor.accelerometer:android.hardware.sensor.compass:android.hardware.sensor.gyroscope:android.hardware.sensor.barometer" />
</activity>
<activity android:name=".sensors.SensorBatchingTestsActivity"
@@ -829,8 +850,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST"/>
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_sensors"/>
- <meta-data android:name="test_excluded_features"
- android:value="android.hardware.type.television:android.software.leanback" />
+ <meta-data android:name="test_applicable_features"
+ android:value="android.hardware.sensor.accelerometer:android.hardware.sensor.compass:android.hardware.sensor.gyroscope:android.hardware.sensor.barometer" />
</activity>
<activity android:name=".sensors.SensorIntegrationTestsActivity"
@@ -841,6 +862,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST"/>
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_sensors"/>
+ <meta-data android:name="test_applicable_features"
+ android:value="android.hardware.sensor.accelerometer:android.hardware.sensor.compass:android.hardware.sensor.gyroscope" />
</activity>
<activity android:name=".sensors.SensorTestActivity"
@@ -851,6 +874,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST"/>
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_sensors"/>
+ <meta-data android:name="test_applicable_features"
+ android:value="android.hardware.sensor.accelerometer:android.hardware.sensor.stepcounter:android.hardware.sensor.stepdetector:android.hardware.sensor.heartrate:android.hardware.sensor.compass:android.hardware.sensor.ambient_temperature" />
</activity>
<!-- End sensor tests definitions -->
@@ -862,6 +887,10 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_location" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
<activity android:name=".location.LocationModeHighAccuracyTestActivity"
android:label="@string/location_mode_high_accuracy_test">
@@ -870,8 +899,12 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_location" />
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.location.network:android.hardware.location.gps" />
<meta-data android:name="test_excluded_features"
- android:value="android.hardware.type.television:android.software.leanback" />
+ android:value="android.hardware.type.television" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
<activity android:name=".location.LocationModeBatterySavingTestActivity"
android:label="@string/location_mode_battery_saving_test">
@@ -880,6 +913,11 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_location" />
+ <meta-data android:name="test_required_features" android:value="android.hardware.location.network" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
<activity android:name=".location.LocationModeDeviceOnlyTestActivity"
android:label="@string/location_mode_device_only_test">
@@ -888,8 +926,11 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_location" />
+ <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
<meta-data android:name="test_excluded_features"
- android:value="android.hardware.type.television:android.software.leanback" />
+ android:value="android.hardware.type.television" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
<activity android:name=".camera.formats.CameraFormatsActivity"
@@ -1002,8 +1043,10 @@
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_hardware" />
<meta-data android:name="test_required_features" android:value="android.hardware.usb.accessory" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.watch" />
</activity>
-
+<!-- Turned off Sensor Power Test in initial L release
<activity android:name=".sensors.SensorPowerTestActivity"
android:label="@string/sensor_power_test"
android:configChanges="keyboardHidden|orientation|screenSize">
@@ -1015,7 +1058,7 @@
<meta-data android:name="test_excluded_features"
android:value="android.hardware.type.television:android.software.leanback" />
</activity>
-
+-->
<activity android:name=".p2p.P2pTestListActivity"
android:label="@string/p2p_test"
android:configChanges="keyboardHidden|orientation|screenSize">
@@ -1062,6 +1105,12 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_notifications" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.watch" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
<activity android:name=".security.CANotifyOnBootActivity"
android:label="@string/caboot_test">
@@ -1070,6 +1119,12 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_notifications" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.watch" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
<activity android:name=".p2p.GoNegRequesterTestListActivity"
@@ -1117,14 +1172,15 @@
</intent-filter>
</activity-alias>
- <activity android:name=".sample.SampleTestActivity"
+ <!-- remove comment from the next activity to see the sample test surfacing in the app -->
+ <!-- activity android:name=".sample.SampleTestActivity"
android:label="@string/sample_framework_test">
<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_other" />
- </activity>
+ </activity -->
<activity android:name=".widget.WidgetTestActivity"
android:label="@string/widget_framework_test">
@@ -1133,6 +1189,10 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_other" />
+ <meta-data android:name="test_required_features"
+ android:value="android.software.app_widgets" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
<activity android:name=".deskclock.DeskClockTestsActivity"
@@ -1142,8 +1202,15 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_deskclock" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
+<!-- TODO: enable when not requiring to tap the screen and timeouts are tuned -->
+<!-- Removed from initial L release
+
<activity
android:name="com.android.cts.verifier.sensors.StepCounterTestActivity"
android:label="@string/snsr_step_counter_test"
@@ -1156,7 +1223,7 @@
<meta-data android:name="test_excluded_features"
android:value="android.hardware.type.television:android.software.leanback" />
</activity>
-
+-->
<activity
android:name="com.android.cts.verifier.sensors.SignificantMotionTestActivity"
android:label="@string/snsr_significant_motion_test"
@@ -1170,8 +1237,8 @@
<meta-data
android:name="test_category"
android:value="@string/test_category_sensors" />
- <meta-data android:name="test_excluded_features"
- android:value="android.hardware.type.television:android.software.leanback" />
+ <meta-data android:name="test_required_features"
+ android:value="android.hardware.sensor.accelerometer" />
</activity>
<receiver android:name=".widget.WidgetCtsProvider">
@@ -1226,6 +1293,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_projection" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.watch" />
</activity>
<activity android:name=".projection.touch.ProjectionTouchActivity"
@@ -1265,7 +1334,8 @@
</activity>
- <activity android:name=".managedprovisioning.ByodFlowTestActivity"
+ <!-- TODO: enable when the test can be executed without leaving marks -->
+ <!-- activity android:name=".managedprovisioning.ByodFlowTestActivity"
android:launchMode="singleTask"
android:label="@string/provisioning_byod">
<intent-filter>
@@ -1278,7 +1348,7 @@
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
<meta-data android:name="test_required_features" android:value="android.software.managed_users:android.software.device_admin" />
- </activity>
+ </activity-->
<activity android:name=".managedprovisioning.ByodHelperActivity">
<intent-filter>
@@ -1312,6 +1382,10 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_jobscheduler" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
<activity android:name=".jobscheduler.ChargingConstraintTestActivity" android:label="@string/js_charging_test">
@@ -1320,6 +1394,10 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_jobscheduler" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
<activity android:name=".jobscheduler.ConnectivityConstraintTestActivity" android:label="@string/js_connectivity_test">
@@ -1328,6 +1406,10 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_jobscheduler" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.hardware.type.television" />
+ <meta-data android:name="test_excluded_features"
+ android:value="android.software.leanback" />
</activity>
<service android:name=".jobscheduler.MockJobService"
diff --git a/apps/CtsVerifier/res/values-television/strings.xml b/apps/CtsVerifier/res/values-television/strings.xml
new file mode 100644
index 0000000..1042fa8
--- /dev/null
+++ b/apps/CtsVerifier/res/values-television/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- Don't test these features on televisions. -->
+ <string-array name="disabled_tests">
+ <item>com.android.cts.verifier.notifications.NotificationAttentionManagementVerifierActivity</item>
+ <item>com.android.cts.verifier.notifications.NotificationListenerVerifierActivity</item>
+ </string-array>
+</resources>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/values-watch/strings.xml b/apps/CtsVerifier/res/values-watch/strings.xml
new file mode 100644
index 0000000..1f25b04
--- /dev/null
+++ b/apps/CtsVerifier/res/values-watch/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- Don't test these features on watches. -->
+ <string-array name="disabled_tests">
+ <item>com.android.cts.verifier.notifications.NotificationAttentionManagementVerifierActivity</item>
+ <item>com.android.cts.verifier.notifications.NotificationListenerVerifierActivity</item>
+ </string-array>
+</resources>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 5cc910f..ec3f8d0 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -67,7 +67,10 @@
\n\nFollow the instructions below to check that the data backup and restore works:
\n\n1. Make sure backup and automatic restore are enabled in settings. Depending on the
backup transport supported by the device you may need to do additional steps. For instance
- you may need to set a Google account as the backup account for the device.
+ you may need to set a Google account as the backup account for the device. If you cannot
+ find the corresponding setting options on your device, run \"adb shell bmgr enable true\"
+ to enable the backup manager. You can check its status by executing \"adb shell bmgr
+ enabled\".
\n\n2. Run the backup manager: adb shell bmgr run
\n\n3. Uninstall the program: adb uninstall com.android.cts.verifier
\n\n4. Reinstall the CTS Verifier and verify that the values are still the same.
@@ -260,7 +263,7 @@
<string name="ble_scanner_power_level_instruction">Count: Ultra low < low < medium < high\nRssi: Ultra low < low < medium < high\nDistance to see count freezing: Ultra low < low < medium < high\nA common error is ultra low, low and medium behave similarly, with similar rssi, freeze at similar distance.\n\n All power level receive a different mac address. After 15 mins, a green text "Get a new Mac address" will show up.</string>
<string name="ble_scanner_scan_filter_name">BLE Hardware Scan Filter</string>
<string name="ble_scanner_scan_filter_info">Lock the screen of scanner, and connect to monsoon. It will not wake up when advertiser is advertising unscannable, and scanner is scanning with filter.</string>
- <string name="ble_scanner_scan_filter_instruction">For monsoon test:\n\tClick scan with filter, lock the screen, connect to monsoon. It will not wake up when advertiser is advertising unscannable data packets, but will show a peak in power usage when advertiser is advertising scannable data.\nFor logcat test:\n\tClick scan with filter, logcat the scanner. No data will be received by GattService when advertiser is advertising unscannable data.</string>
+ <string name="ble_scanner_scan_filter_instruction">Scan filter is to scan data with service UUID = 0x6666 only. If you scan without scan filter, data with service UUID = 0x5555 and 0x6666 will show up on screen.\nFor monsoon test:\n\tClick scan with filter, lock the screen, connect to monsoon. It will not wake up when advertiser is advertising unscannable data packets, but will show a peak in power usage when advertiser is advertising scannable data.\nFor logcat test:\n\tClick scan with filter, logcat the scanner. No data will be received by GattService when advertiser is advertising unscannable data.</string>
<string name="ble_scan_with_filter">Scan with filter</string>
<string name="ble_scan_without_filter">Scan without filter</string>
@@ -1288,7 +1291,7 @@
<string name="device_owner_provisioning_tests_info">The device owner provisioning tests verify that setting up a corporate owned device can only be done on a factory reset device.</string>
<string name="device_owner_provisioning_category">Device Owner Provisioning</string>
<string name="device_owner_negative_test">Device owner negative test</string>
- <string name="device_owner_negative_test_info">Device owner provisioning should only work on new or factory reset devices. Please click on the "Start provisioning" button and verify that you get a warning dialog telling you that the device is already set up. If that is the case, this test has passed.</string>
+ <string name="device_owner_negative_test_info">Please click the "Start provisioning" button, and when you see a warning dialog telling the device is already set up, select "pass". Otherwise, select "fail".</string>
<string name="start_device_owner_provisioning_button">Start provisioning</string>
<!-- Strings for JobScheduler Tests -->
@@ -1314,4 +1317,8 @@
<string name="js_unmetered_connectivity_test">Device with no connectivity will not execute a job with an unmetered connectivity constraint.</string>
<string name="js_any_connectivity_test">Device with no connectivity will not execute a job with an unmetered connectivity constraint.</string>
<string name="js_no_connectivity_test">Device with no connectivity will still execute a job with no connectivity constraints.</string>
+
+ <!-- A list of fully-qualified test classes that should not be run. -->
+ <string-array name="disabled_tests" />
+
</resources>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java
index 2f42e81..ebddf4f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java
@@ -22,12 +22,14 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
+import android.util.Log;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -75,6 +77,13 @@
* <meta-data android:name="test_excluded_features" android:value="android.hardware.type.television" />
* </pre>
* </li>
+ * <li>OPTIONAL: Add a meta data attribute to indicate features such that, if any present,
+ * the test is applicable to run. If the device has any of the applicable features then
+ * the test will appear in the test list. Use a colon (:) to specify multiple features
+ * <pre>
+ * <meta-data android:name="test_applicable_features" android:value="android.hardware.sensor.compass" />
+ * </pre>
+ * </li>
*
* </ol>
*/
@@ -88,6 +97,10 @@
private static final String TEST_EXCLUDED_FEATURES_META_DATA = "test_excluded_features";
+ private static final String TEST_APPLICABLE_FEATURES_META_DATA = "test_applicable_features";
+
+ private final HashSet<String> mDisabledTests;
+
private Context mContext;
private String mTestParent;
@@ -96,6 +109,12 @@
super(context);
mContext = context;
mTestParent = testParent;
+
+ String[] disabledTestArray = context.getResources().getStringArray(R.array.disabled_tests);
+ mDisabledTests = new HashSet<>(disabledTestArray.length);
+ for (int i = 0; i < disabledTestArray.length; i++) {
+ mDisabledTests.add(disabledTestArray[i]);
+ }
}
@Override
@@ -158,13 +177,18 @@
int size = list.size();
for (int i = 0; i < size; i++) {
ResolveInfo info = list.get(i);
+ if (info.activityInfo == null || mDisabledTests.contains(info.activityInfo.name)) {
+ Log.w("CtsVerifier", "ignoring disabled test: " + info.activityInfo.name);
+ continue;
+ }
String title = getTitle(mContext, info.activityInfo);
String testName = info.activityInfo.name;
Intent intent = getActivityIntent(info.activityInfo);
String[] requiredFeatures = getRequiredFeatures(info.activityInfo.metaData);
String[] excludedFeatures = getExcludedFeatures(info.activityInfo.metaData);
- TestListItem item = TestListItem.newTest(title, testName, intent,
- requiredFeatures, excludedFeatures);
+ String[] applicableFeatures = getApplicableFeatures(info.activityInfo.metaData);
+ TestListItem item = TestListItem.newTest(title, testName, intent, requiredFeatures,
+ excludedFeatures, applicableFeatures);
String testCategory = getTestCategory(mContext, info.activityInfo.metaData);
addTestToCategory(testsByCategory, testCategory, item);
@@ -215,6 +239,19 @@
}
}
+ static String[] getApplicableFeatures(Bundle metaData) {
+ if (metaData == null) {
+ return null;
+ } else {
+ String value = metaData.getString(TEST_APPLICABLE_FEATURES_META_DATA);
+ if (value == null) {
+ return null;
+ } else {
+ return value.split(":");
+ }
+ }
+ }
+
static String getTitle(Context context, ActivityInfo activityInfo) {
if (activityInfo.labelRes != 0) {
return context.getString(activityInfo.labelRes);
@@ -268,10 +305,10 @@
List<TestListItem> filterTests(List<TestListItem> tests) {
List<TestListItem> filteredTests = new ArrayList<TestListItem>();
for (TestListItem test : tests) {
- String[] excludedFeatures = test.excludedFeatures;
- String[] requiredFeatures = test.requiredFeatures;
- if (!hasAnyFeature(excludedFeatures) && hasAllFeatures(requiredFeatures)) {
- filteredTests.add(test);
+ if (!hasAnyFeature(test.excludedFeatures) && hasAllFeatures(test.requiredFeatures)) {
+ if (test.applicableFeatures == null || hasAnyFeature(test.applicableFeatures)) {
+ filteredTests.add(test);
+ }
}
}
return filteredTests;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
index 0d9985c..afe3a73 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
@@ -86,26 +86,43 @@
/** Features such that, if any present, the test gets excluded from being shown. */
final String[] excludedFeatures;
+ /** If any of of the features are present the test is meaningful to run. */
+ final String[] applicableFeatures;
+
+ public static TestListItem newTest(Context context, int titleResId, String testName,
+ Intent intent, String[] requiredFeatures, String[] excludedFeatures,
+ String[] applicableFeatures) {
+ return newTest(context.getString(titleResId), testName, intent, requiredFeatures,
+ excludedFeatures, applicableFeatures);
+ }
+
public static TestListItem newTest(Context context, int titleResId, String testName,
Intent intent, String[] requiredFeatures, String[] excludedFeatures) {
- return newTest(context.getString(titleResId), testName, intent,
- requiredFeatures, excludedFeatures);
+ return newTest(context.getString(titleResId), testName, intent, requiredFeatures,
+ excludedFeatures, null);
}
public static TestListItem newTest(Context context, int titleResId, String testName,
Intent intent, String[] requiredFeatures) {
- return newTest(context.getString(titleResId), testName, intent,
- requiredFeatures, null);
+ return newTest(context.getString(titleResId), testName, intent, requiredFeatures, null,
+ null);
+ }
+
+ public static TestListItem newTest(String title, String testName, Intent intent,
+ String[] requiredFeatures, String[] excludedFeatures, String[] applicableFeatures) {
+ return new TestListItem(title, testName, intent, requiredFeatures, excludedFeatures,
+ applicableFeatures);
}
public static TestListItem newTest(String title, String testName, Intent intent,
String[] requiredFeatures, String[] excludedFeatures) {
- return new TestListItem(title, testName, intent, requiredFeatures, excludedFeatures);
+ return new TestListItem(title, testName, intent, requiredFeatures, excludedFeatures,
+ null);
}
public static TestListItem newTest(String title, String testName, Intent intent,
String[] requiredFeatures) {
- return new TestListItem(title, testName, intent, requiredFeatures, null);
+ return new TestListItem(title, testName, intent, requiredFeatures, null, null);
}
public static TestListItem newCategory(Context context, int titleResId) {
@@ -113,16 +130,17 @@
}
public static TestListItem newCategory(String title) {
- return new TestListItem(title, null, null, null, null);
+ return new TestListItem(title, null, null, null, null, null);
}
private TestListItem(String title, String testName, Intent intent,
- String[] requiredFeatures, String[] excludedFeatures) {
+ String[] requiredFeatures, String[] excludedFeatures, String[] applicableFeatures) {
this.title = title;
this.testName = testName;
this.intent = intent;
this.requiredFeatures = requiredFeatures;
this.excludedFeatures = excludedFeatures;
+ this.applicableFeatures = applicableFeatures;
}
boolean isTest() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserHardwareScanFilterActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserHardwareScanFilterActivity.java
index 242bb08..be2fef9 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserHardwareScanFilterActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserHardwareScanFilterActivity.java
@@ -83,6 +83,7 @@
public void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
+ filter.addAction(BleAdvertiserService.BLE_ADV_NOT_SUPPORT);
filter.addAction(BleAdvertiserService.BLE_START_SCANNABLE);
filter.addAction(BleAdvertiserService.BLE_START_UNSCANNABLE);
filter.addAction(BleAdvertiserService.BLE_STOP_SCANNABLE);
@@ -106,6 +107,10 @@
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
+ private void pass() {
+ this.setTestResultAndFinish(true);
+ }
+
private void stopAdvertising() {
Intent intent = new Intent(BleAdvertiserHardwareScanFilterActivity.this,
BleAdvertiserService.class);
@@ -130,6 +135,9 @@
case BleAdvertiserService.BLE_STOP_UNSCANNABLE:
showMessage("Stop advertising");
break;
+ case BleAdvertiserService.BLE_ADV_NOT_SUPPORT:
+ pass();
+ break;
}
}
};
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserPowerLevelActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserPowerLevelActivity.java
index 3568002..1cc9206 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserPowerLevelActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserPowerLevelActivity.java
@@ -67,6 +67,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(BleAdvertiserService.BLE_START_POWER_LEVEL);
filter.addAction(BleAdvertiserService.BLE_STOP_POWER_LEVEL);
+ filter.addAction(BleAdvertiserService.BLE_ADV_NOT_SUPPORT);
registerReceiver(onBroadcast, filter);
}
@@ -94,6 +95,10 @@
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
+ private void pass() {
+ this.setTestResultAndFinish(true);
+ }
+
private BroadcastReceiver onBroadcast = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -104,6 +109,9 @@
case BleAdvertiserService.BLE_STOP_POWER_LEVEL:
showMessage("Stop advertising");
break;
+ case BleAdvertiserService.BLE_ADV_NOT_SUPPORT:
+ pass();
+ break;
}
}
};
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserService.java
index 7b4235b..281b2e8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserService.java
@@ -53,6 +53,8 @@
public static final int COMMAND_START_UNSCANNABLE = 6;
public static final int COMMAND_STOP_UNSCANNABLE = 7;
+ public static final String BLE_ADV_NOT_SUPPORT =
+ "com.android.cts.verifier.bluetooth.BLE_ADV_NOT_SUPPORT";
public static final String BLE_START_ADVERTISE =
"com.android.cts.verifier.bluetooth.BLE_START_ADVERTISE";
public static final String BLE_STOP_ADVERTISE =
@@ -147,11 +149,15 @@
public void onDestroy() {
super.onDestroy();
if (mAdvertiser != null) {
- mAdvertiser.stopAdvertising(mCallback);
+ stopAdvertiser();
}
}
private void stopAdvertiser() {
+ if (mAdvertiser == null) {
+ mAdvertiserStatus = 0;
+ return;
+ }
if ((mAdvertiserStatus & (1 << COMMAND_START_ADVERTISE)) > 0) {
mAdvertiser.stopAdvertising(mCallback);
}
@@ -186,8 +192,12 @@
}
private void handleIntent(Intent intent) {
- if (mAdvertiser == null) {
- showMessage("Multi advertising not supported on this device");
+ if (mBluetoothAdapter != null && !mBluetoothAdapter.isMultipleAdvertisementSupported()) {
+ showMessage("Multiple advertisement is not supported.");
+ sendBroadcast(new Intent(BLE_ADV_NOT_SUPPORT));
+ return;
+ } else if (mAdvertiser == null) {
+ showMessage("Cannot start advertising on this device.");
return;
}
int command = intent.getIntExtra(EXTRA_COMMAND, -1);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientConnectActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientConnectActivity.java
old mode 100644
new mode 100755
index a3a9830..fb351b1
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientConnectActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientConnectActivity.java
@@ -63,19 +63,15 @@
}
}
});
- }
- @Override
- public void onResume() {
- super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(BleClientService.BLE_BLUETOOTH_CONNECTED);
registerReceiver(onBroadcast, filter);
}
@Override
- public void onPause() {
- super.onPause();
+ protected void onDestroy(){
+ super.onDestroy();
unregisterReceiver(onBroadcast);
}
@@ -90,4 +86,4 @@
getPassButton().setEnabled(true);
}
};
-}
\ No newline at end of file
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
index 178a811..e5af6ba 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/fov/PhotoCaptureActivity.java
@@ -77,6 +77,8 @@
private int mResolutionSpinnerIndex = -1;
private WakeLock mWakeLock;
private long shutterStartTime;
+ private int mPreviewOrientation;
+ private int mJpegOrientation;
private ArrayList<Integer> mPreviewSizeCamerasToProcess = new ArrayList<Integer>();
@@ -171,7 +173,7 @@
mReportedFovPrePictureTaken = mCamera.getParameters().getHorizontalViewAngle();
mResolutionSpinnerIndex = position;
- initializeCamera();
+ startPreview();
}
}
@@ -395,6 +397,10 @@
}
private void initializeCamera() {
+ initializeCamera(true);
+ }
+
+ private void initializeCamera(boolean startPreviewAfterInit) {
if (mCamera == null || mSurfaceHolder.getSurface() == null) {
return;
}
@@ -406,6 +412,8 @@
Toast.makeText(this, t.getMessage(), Toast.LENGTH_LONG).show();
return;
}
+
+ calculateOrientations(this, mSelectedResolution.cameraId, mCamera);
Camera.Parameters params = setCameraParams(mCamera);
// Either use chosen preview size for current camera or automatically
@@ -417,18 +425,21 @@
mCamera.setParameters(params);
mCameraInitialized = true;
}
- startPreview();
+
+ if (startPreviewAfterInit) {
+ startPreview();
+ }
}
private void startPreview() {
if (mCameraInitialized && mCamera != null) {
- setCameraDisplayOrientation(this, mSelectedResolution.cameraId, mCamera);
+ mCamera.setDisplayOrientation(mPreviewOrientation);
mCamera.startPreview();
mPreviewActive = true;
}
}
- private void switchToCamera(SelectableResolution resolution, boolean initializeCamera) {
+ private void switchToCamera(SelectableResolution resolution, boolean startPreview) {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
@@ -437,9 +448,7 @@
mSelectedResolution = resolution;
mCamera = Camera.open(mSelectedResolution.cameraId);
- if (initializeCamera){
- initializeCamera();
- }
+ initializeCamera(startPreview);
}
/**
@@ -474,6 +483,7 @@
Camera.Parameters params = camera.getParameters();
params.setJpegThumbnailSize(0, 0);
params.setJpegQuality(100);
+ params.setRotation(mJpegOrientation);
params.setFocusMode(getFocusMode(camera));
params.setZoom(0);
params.setPictureSize(mSelectedResolution.width, mSelectedResolution.height);
@@ -501,7 +511,7 @@
return result;
}
- public static void setCameraDisplayOrientation(Activity activity,
+ private void calculateOrientations(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
@@ -516,13 +526,12 @@
case Surface.ROTATION_270: degrees = 270; break;
}
- int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
- result = (info.orientation + degrees) % 360;
- result = (360 - result) % 360; // compensate the mirror
+ mJpegOrientation = (info.orientation + degrees) % 360;
+ mPreviewOrientation = (360 - mJpegOrientation) % 360; // compensate the mirror
} else { // back-facing
- result = (info.orientation - degrees + 360) % 360;
+ mJpegOrientation = (info.orientation - degrees + 360) % 360;
+ mPreviewOrientation = mJpegOrientation;
}
- camera.setDisplayOrientation(result);
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
index 97c0521..0a0e830 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/video/CameraVideoActivity.java
@@ -70,6 +70,7 @@
private int mPreviewTexWidth;
private int mPreviewTexHeight;
private int mPreviewRotation;
+ private int mVideoRotation;
private VideoView mPlaybackView;
@@ -162,7 +163,10 @@
// Step 5: set preview output
// This is not necessary since preview has been taken care of
- // Step 6: prepare configured MediaRecorder
+ // Step 6: set orientation hint
+ mMediaRecorder.setOrientationHint(mVideoRotation);
+
+ // Step 7: prepare configured MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IOException e) {
@@ -644,10 +648,11 @@
}
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
- mPreviewRotation = (info.orientation + degrees) % 360;
- mPreviewRotation = (360 - mPreviewRotation) % 360; // compensate the mirror
+ mVideoRotation = (info.orientation + degrees) % 360;
+ mPreviewRotation = (360 - mVideoRotation) % 360; // compensate the mirror
} else { // back-facing
- mPreviewRotation = (info.orientation - degrees + 360) % 360;
+ mVideoRotation = (info.orientation - degrees + 360) % 360;
+ mPreviewRotation = mVideoRotation;
}
if (mPreviewRotation != 0 && mPreviewRotation != 180) {
Log.w(TAG,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
index 032442b..74a5317 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
@@ -169,6 +169,10 @@
};
public static final Feature[] ALL_JELLY_BEAN_FEATURES = {
+ // Required features in prior releases that became optional
+ new Feature(PackageManager.FEATURE_FAKETOUCH, false),
+
+ //new feature in JB
new Feature(PackageManager.FEATURE_TELEVISION, false),
};
@@ -190,13 +194,37 @@
public static final Feature[] ALL_KITKAT_WATCH_FEATURES = {
new Feature(PackageManager.FEATURE_SENSOR_HEART_RATE, false),
+ new Feature(PackageManager.FEATURE_BACKUP, false),
+ new Feature(PackageManager.FEATURE_PRINTING, false),
+ new Feature(PackageManager.FEATURE_WATCH, false),
+ new Feature(PackageManager.FEATURE_WEBVIEW, false),
+ new Feature(PackageManager.FEATURE_CAMERA_EXTERNAL, false),
};
- public static final Feature[] ALL_LMP_FEATURES = {
+ public static final Feature[] ALL_LOLLIPOP_FEATURES = {
+ // New features in L
+ new Feature(PackageManager.FEATURE_AUDIO_OUTPUT, false),
+ new Feature(PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_POST_PROCESSING, false),
+ new Feature(PackageManager.FEATURE_CAMERA_CAPABILITY_MANUAL_SENSOR, false),
+ new Feature(PackageManager.FEATURE_CAMERA_CAPABILITY_RAW, false),
+ new Feature(PackageManager.FEATURE_CAMERA_LEVEL_FULL, false),
+ new Feature(PackageManager.FEATURE_CONNECTION_SERVICE, false),
+ new Feature(PackageManager.FEATURE_GAMEPAD, false),
+ new Feature(PackageManager.FEATURE_LEANBACK, false),
+ new Feature(PackageManager.FEATURE_LIVE_TV, false),
+ new Feature(PackageManager.FEATURE_MANAGED_USERS, false),
+ new Feature(PackageManager.FEATURE_OPENGLES_EXTENSION_PACK, false),
+ new Feature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, false),
+ new Feature(PackageManager.FEATURE_SENSOR_AMBIENT_TEMPERATURE, false),
new Feature(PackageManager.FEATURE_SENSOR_HEART_RATE_ECG, false),
+ new Feature(PackageManager.FEATURE_SENSOR_RELATIVE_HUMIDITY, false),
+ new Feature(PackageManager.FEATURE_VERIFIED_BOOT, false),
+
+ // New hidden features in L
new Feature("android.hardware.ethernet", false),
- new Feature("android.software.backup", false),
- new Feature("android.software.print", false),
+ new Feature("android.hardware.hdmi.cec", false),
+ new Feature("android.software.leanback_only", false),
+ new Feature("android.software.voice_recognizers", false),
};
@Override
@@ -230,7 +258,7 @@
// add features from latest to last so that the latest requirements are put in the set first
int apiVersion = Build.VERSION.SDK_INT;
if (apiVersion >= Build.VERSION_CODES.LOLLIPOP) {
- Collections.addAll(features, ALL_LMP_FEATURES);
+ Collections.addAll(features, ALL_LOLLIPOP_FEATURES);
}
if (apiVersion >= Build.VERSION_CODES.KITKAT_WATCH) {
Collections.addAll(features, ALL_KITKAT_WATCH_FEATURES);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java
index 3d0e0d7..b4863fa 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/MockListener.java
@@ -31,7 +31,9 @@
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
public class MockListener extends NotificationListenerService {
static final String TAG = "MockListener";
@@ -67,8 +69,10 @@
private ArrayList<String> mPosted = new ArrayList<String>();
private ArrayMap<String, JSONObject> mNotifications = new ArrayMap<>();
+ private ArrayMap<String, String> mNotificationKeys = new ArrayMap<>();
private ArrayList<String> mRemoved = new ArrayList<String>();
private ArrayList<String> mOrder = new ArrayList<>();
+ private Set<String> mTestPackages = new HashSet<>();
private BroadcastReceiver mReceiver;
private int mDND = -1;
@@ -77,6 +81,8 @@
super.onCreate();
Log.d(TAG, "created");
+ mTestPackages.add("com.android.cts.verifier");
+
mPosted = new ArrayList<String>();
mRemoved = new ArrayList<String>();
@@ -123,10 +129,13 @@
setResultCode(Activity.RESULT_OK);
} else if (SERVICE_CLEAR_ONE.equals(action)) {
Log.d(TAG, "SERVICE_CLEAR_ONE");
- MockListener.this.cancelNotification(
- context.getApplicationInfo().packageName,
- intent.getStringExtra(EXTRA_TAG),
- intent.getIntExtra(EXTRA_CODE, 0));
+ String tag = intent.getStringExtra(EXTRA_TAG);
+ String key = mNotificationKeys.get(tag);
+ if (key != null) {
+ MockListener.this.cancelNotification(key);
+ } else {
+ Log.w(TAG, "Notification does not exist: " + tag);
+ }
} else if (SERVICE_CLEAR_ALL.equals(action)) {
Log.d(TAG, "SERVICE_CLEAR_ALL");
MockListener.this.cancelAllNotifications();
@@ -205,6 +214,7 @@
@Override
public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
+ if (!mTestPackages.contains(sbn.getPackageName())) { return; }
Log.d(TAG, "posted: " + sbn.getTag());
mPosted.add(sbn.getTag());
JSONObject notification = new JSONObject();
@@ -216,6 +226,7 @@
notification.put(JSON_ICON, sbn.getNotification().icon);
notification.put(JSON_FLAGS, sbn.getNotification().flags);
mNotifications.put(sbn.getKey(), notification);
+ mNotificationKeys.put(sbn.getTag(), sbn.getKey());
} catch (JSONException e) {
Log.e(TAG, "failed to pack up notification payload", e);
}
@@ -228,6 +239,7 @@
mRemoved.add(sbn.getTag());
mNotifications.remove(sbn.getKey());
onNotificationRankingUpdate(rankingMap);
+ mNotificationKeys.remove(sbn.getTag());
}
public static void resetListenerData(Context context) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationAttentionManagementVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationAttentionManagementVerifierActivity.java
index e355b07..b4e348f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationAttentionManagementVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/NotificationAttentionManagementVerifierActivity.java
@@ -82,6 +82,7 @@
createAutoItem(R.string.nls_service_started);
createAutoItem(R.string.attention_create_contacts);
createRetryItem(R.string.attention_filter_none);
+ createAutoItem(R.string.attention_all_are_filtered);
createRetryItem(R.string.attention_filter_all);
createAutoItem(R.string.attention_none_are_filtered);
createAutoItem(R.string.attention_default_order);
@@ -114,42 +115,45 @@
testModeNone(mState);
break;
case 4:
- testModeAll(mState);
+ testNoneInterceptsAll(mState);
break;
case 5:
- testALLInterceptsNothing(mState);
+ testModeAll(mState);
break;
case 6:
- testDefaultOrder(mState);
+ testAllInterceptsNothing(mState);
break;
case 7:
- testInterruptionOrder(mState);
+ testDefaultOrder(mState);
break;
case 8:
- testPrioritytOrder(mState);
+ testInterruptionOrder(mState);
break;
case 9:
- testAmbientBits(mState);
+ testPrioritytOrder(mState);
break;
case 10:
- testLookupUriOrder(mState);
+ testAmbientBits(mState);
break;
case 11:
- testEmailOrder(mState);
+ testLookupUriOrder(mState);
break;
case 12:
- testPhoneOrder(mState);
+ testEmailOrder(mState);
break;
case 13:
- testModePriority(mState);
+ testPhoneOrder(mState);
break;
case 14:
- testPriorityInterceptsSome(mState);
+ testModePriority(mState);
break;
case 15:
- testDeleteContacts(mState);
+ testPriorityInterceptsSome(mState);
break;
case 16:
+ testDeleteContacts(mState);
+ break;
+ case 17:
getPassButton().setEnabled(true);
mNm.cancelAll();
break;
@@ -678,7 +682,7 @@
}
// Nothing should be filtered when mode is ALL
- private void testALLInterceptsNothing(final int i) {
+ private void testAllInterceptsNothing(final int i) {
if (mStatus[i] == SETUP) {
mNm.cancelAll();
MockListener.resetListenerData(this);
@@ -783,6 +787,59 @@
}
}
+ // Nothing should get through when mode is None.
+ private void testNoneInterceptsAll(final int i) {
+ if (mStatus[i] == SETUP) {
+ mNm.cancelAll();
+ MockListener.resetListenerData(this);
+ mStatus[i] = CLEARED;
+ // wait for intent to move through the system
+ delay();
+ } else if (mStatus[i] == CLEARED) {
+ sendNotifications(MODE_URI, false, false);
+ mStatus[i] = READY;
+ // wait for notifications to move through the system
+ delay();
+ } else {
+ MockListener.probeListenerPayloads(mContext,
+ new MockListener.StringListResultCatcher() {
+ @Override
+ public void accept(List<String> result) {
+ boolean pass = false;
+ Set<String> found = new HashSet<String>();
+ if (result != null && result.size() > 0) {
+ pass = true;
+ for (String payloadData : result) {
+ try {
+ JSONObject payload = new JSONObject(payloadData);
+ String tag = payload.getString(JSON_TAG);
+ if (found.contains(tag)) {
+ // multiple entries for same notification!
+ pass = false;
+ } else if (ALICE.equals(tag)) {
+ found.add(ALICE);
+ pass &= !payload.getBoolean(JSON_MATCHES_ZEN_FILTER);
+ } else if (BOB.equals(tag)) {
+ found.add(BOB);
+ pass &= !payload.getBoolean(JSON_MATCHES_ZEN_FILTER);
+ } else if (CHARLIE.equals(tag)) {
+ found.add(CHARLIE);
+ pass &= !payload.getBoolean(JSON_MATCHES_ZEN_FILTER);
+ }
+ } catch (JSONException e) {
+ pass = false;
+ Log.e(TAG, "failed to unpack data from mocklistener", e);
+ }
+ }
+ }
+ pass &= found.size() == 3;
+ mStatus[i] = pass ? PASS : FAIL;
+ next();
+ }
+ });
+ }
+ }
+
/** Search a list of notification keys for a givcen tag. */
private int findTagInKeys(String tag, List<String> orderedKeys) {
for (int i = 0; i < orderedKeys.size(); i++) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/projection/list/ListPresentation.java b/apps/CtsVerifier/src/com/android/cts/verifier/projection/list/ListPresentation.java
index dad4945..5dddf5c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/projection/list/ListPresentation.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/projection/list/ListPresentation.java
@@ -50,7 +50,7 @@
setContentView(view);
for (int i = 0; i < NUM_ITEMS; ++i) {
- mItemList.add("Item #" + i);
+ mItemList.add("Item #" + 1 + i);
}
ListView listView = (ListView) view.findViewById(R.id.pla_list);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
index fa233e8..9684d97 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
@@ -119,30 +119,30 @@
new Stream("H263 Video, AMR Audio", "http_h263_amr",
"http://redirector.c.play.google.com/"
+ "videoplayback?id=271de9756065677e"
- + "&itag=13&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
- + "&sparams=ip,ipbits,expire,ip,ipbits,expire,id,itag"
- + "&signature=372FA4C532AA49D14EAF049BCDA66460EEE161E9"
- + ".6D8BF096B73B7A68A7032CA8685053CFB498D30A"
+ + "&itag=13&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ + "&sparams=ip,ipbits,expire,id,itag"
+ + "&signature=073A731E2BDF1E05206AC7B9B895C922ABCBA01D"
+ + ".1DDA3F999541D2136E6755F16FC44CA972767169"
+ "&source=youtube"
- + "&key=test_key1&user=android-device-test"),
+ + "&key=ik0&user=android-device-test"),
new Stream("MPEG4 SP Video, AAC Audio", "http_mpeg4_aac",
"http://redirector.c.play.google.com/"
+ "videoplayback?id=271de9756065677e"
- + "&itag=17&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
- + "&sparams=ip,ipbits,expire,ip,ipbits,expire,id,itag"
- + "&signature=3DCD3F79E045F95B6AF661765F046FB0440FF016"
- + ".06A42661B3AF6BAF046F012549CC9BA34EBC80A9"
+ + "&itag=17&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ + "&sparams=ip,ipbits,expire,id,itag"
+ + "&signature=6B0F8B8A6A7FD9E4CDF123349C2E061ED2020D74"
+ + ".3460FC81D6C8894BA2D241597D2E1D059845F5F0"
+ "&source=youtube"
- + "&key=test_key1&user=android-device-test"),
+ + "&key=ik0&user=android-device-test"),
new Stream("H264 Base Video, AAC Audio", "http_h264_aac",
"http://redirector.c.play.google.com/"
+ "videoplayback?id=271de9756065677e"
- + "&itag=18&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
- + "&sparams=ip,ipbits,expire,ip,ipbits,expire,id,itag"
- + "&signature=1219C2B07AF0638C27916307A6093C0E43CB894E"
- + ".126B6B916BD57157782738AA7C03E59F21DBC168"
+ + "&itag=18&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ + "&sparams=ip,ipbits,expire,id,itag"
+ + "&signature=75627CD4CEA73D7868CBDE3CE5C4011955164107"
+ + ".1DCFB0EF1372B48DDCFBE69645FE137AC02AF561"
+ "&source=youtube"
- + "&key=test_key1&user=android-device-test"),
+ + "&key=ik0&user=android-device-test"),
};
@Override
diff --git a/hostsidetests/jdwpsecurity/Android.mk b/hostsidetests/jdwpsecurity/Android.mk
new file mode 100644
index 0000000..561d346
--- /dev/null
+++ b/hostsidetests/jdwpsecurity/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_MODULE := CtsJdwpSecurityHostTestCases
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+
+LOCAL_CTS_TEST_PACKAGE := android.host.jdwpsecurity
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/jdwpsecurity/app/Android.mk b/hostsidetests/jdwpsecurity/app/Android.mk
new file mode 100644
index 0000000..13b5be4
--- /dev/null
+++ b/hostsidetests/jdwpsecurity/app/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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_MODULE := CtsJdwpApp
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+include $(BUILD_JAVA_LIBRARY)
+
+# Copy the built module to the cts dir
+cts_library_jar := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar
+$(cts_library_jar): $(LOCAL_BUILT_MODULE)
+ $(copy-file-to-target)
+
+# Have the module name depend on the cts files; so the cts files get generated when you run mm/mmm/mma/mmma.
+$(my_register_name) : $(cts_library_jar)
+
diff --git a/hostsidetests/jdwpsecurity/app/src/com/android/cts/jdwpsecurity/JdwpTest.java b/hostsidetests/jdwpsecurity/app/src/com/android/cts/jdwpsecurity/JdwpTest.java
new file mode 100644
index 0000000..f2e5980
--- /dev/null
+++ b/hostsidetests/jdwpsecurity/app/src/com/android/cts/jdwpsecurity/JdwpTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.jdwpsecurity;
+
+public class JdwpTest {
+ private static final long LOOP_TIMEOUT_MS = 60 * 1000;
+
+ public static void main(String[] args) throws Exception {
+ // Print pid so the test knows who we are.
+ int pid = android.os.Process.myPid();
+ System.out.println(pid);
+
+ // Loop to keep alive so the host test has the time to check whether we have a JDWP
+ // connection.
+ // Note: we use a timeout to avoid indefinite loop in case something wrong happens
+ // with the test harness.
+ long start = System.currentTimeMillis();
+ while(getElapsedTime(start) < LOOP_TIMEOUT_MS) {
+ Thread.sleep(100);
+ }
+ }
+
+ private static long getElapsedTime(long start) {
+ return System.currentTimeMillis() - start;
+ }
+}
diff --git a/hostsidetests/jdwpsecurity/src/android/jdwpsecurity/cts/JdwpSecurityHostTest.java b/hostsidetests/jdwpsecurity/src/android/jdwpsecurity/cts/JdwpSecurityHostTest.java
new file mode 100644
index 0000000..8e276ed
--- /dev/null
+++ b/hostsidetests/jdwpsecurity/src/android/jdwpsecurity/cts/JdwpSecurityHostTest.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.jdwpsecurity.cts;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.util.ArrayUtil;
+import com.android.tradefed.util.RunUtil;
+
+import java.io.BufferedReader;
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test to check non-zygote apps do not have an active JDWP connection.
+ */
+public class JdwpSecurityHostTest extends DeviceTestCase implements IBuildReceiver {
+
+ private static final String DEVICE_LOCATION = "/data/local/tmp/jdwpsecurity";
+ private static final String DEVICE_SCRIPT_FILENAME = "jdwptest";
+ private static final String DEVICE_JAR_FILENAME = "CtsJdwpApp.jar";
+ private static final String JAR_MAIN_CLASS_NAME = "com.android.cts.jdwpsecurity.JdwpTest";
+
+ private CtsBuildHelper mCtsBuild;
+
+ private static String getDeviceScriptFilepath() {
+ return DEVICE_LOCATION + File.separator + DEVICE_SCRIPT_FILENAME;
+ }
+
+ private static String getDeviceJarFilepath() {
+ return DEVICE_LOCATION + File.separator + DEVICE_JAR_FILENAME;
+ }
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Create test directory on the device.
+ createRemoteDir(DEVICE_LOCATION);
+
+ // Also create the dalvik-cache directory. It needs to exist before the runtime starts.
+ createRemoteDir(DEVICE_LOCATION + File.separator + "dalvik-cache");
+
+ // Create and push script on the device.
+ File tempFile = createScriptTempFile();
+ try {
+ boolean success = getDevice().pushFile(tempFile, getDeviceScriptFilepath());
+ assertTrue("Failed to push script to " + getDeviceScriptFilepath(), success);
+ } finally {
+ if (tempFile != null) {
+ tempFile.delete();
+ }
+ }
+
+ // Make the script executable.
+ getDevice().executeShellCommand("chmod 755 " + getDeviceScriptFilepath());
+
+ // Push jar file.
+ File jarFile = mCtsBuild.getTestApp(DEVICE_JAR_FILENAME);
+ boolean success = getDevice().pushFile(jarFile, getDeviceJarFilepath());
+ assertTrue("Failed to push jar file to " + getDeviceScriptFilepath(), success);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // Delete the whole test directory on the device.
+ getDevice().executeShellCommand(String.format("rm -r %s", DEVICE_LOCATION));
+
+ super.tearDown();
+ }
+
+ /**
+ * Tests a non-zygote app does not have a JDWP connection, thus not being
+ * debuggable.
+ *
+ * Runs a script executing a Java app (jar file) with app_process,
+ * without forking from zygote. Then checks its pid is not returned
+ * by 'adb jdwp', meaning it has no JDWP connection and cannot be
+ * debugged.
+ *
+ * @throws Exception
+ */
+ public void testNonZygoteProgramIsNotDebuggable() throws Exception {
+ String scriptFilepath = getDeviceScriptFilepath();
+ Process scriptProcess = null;
+ String scriptPid = null;
+ List<String> activeJdwpPids = null;
+ try {
+ // Run the script on the background so it's running when we collect the list of
+ // pids with a JDWP connection using 'adb jdwp'.
+ // command.
+ scriptProcess = runScriptInBackground(scriptFilepath);
+
+ // On startup, the script will print its pid on its output.
+ scriptPid = readScriptPid(scriptProcess);
+
+ // Collect the list of pids with a JDWP connection.
+ activeJdwpPids = getJdwpPids();
+ } finally {
+ // Stop the script.
+ if (scriptProcess != null) {
+ scriptProcess.destroy();
+ }
+ }
+
+ assertNotNull("Failed to get script pid", scriptPid);
+ assertNotNull("Failed to get active JDWP pids", activeJdwpPids);
+ assertFalse("Test app should not have an active JDWP connection" +
+ " (pid " + scriptPid + " is returned by 'adb jdwp')",
+ activeJdwpPids.contains(scriptPid));
+ }
+
+ private Process runScriptInBackground(String scriptFilepath) throws IOException {
+ String[] shellScriptCommand = buildAdbCommand("shell", scriptFilepath);
+ return RunUtil.getDefault().runCmdInBackground(shellScriptCommand);
+ }
+
+ private String readScriptPid(Process scriptProcess) throws IOException {
+ BufferedReader br = null;
+ try {
+ br = new BufferedReader(new InputStreamReader(scriptProcess.getInputStream()));
+ // We only expect to read one line containing the pid.
+ return br.readLine();
+ } finally {
+ if (br != null) {
+ br.close();
+ }
+ }
+ }
+
+ private List<String> getJdwpPids() throws Exception {
+ return new AdbJdwpOutputReader().listPidsWithAdbJdwp();
+ }
+
+ /**
+ * Creates the script file on the host so it can be pushed onto the device.
+ *
+ * @return the script file
+ * @throws IOException
+ */
+ private static File createScriptTempFile() throws IOException {
+ File tempFile = File.createTempFile("jdwptest", ".tmp");
+
+ PrintWriter pw = null;
+ try {
+ pw = new PrintWriter(tempFile);
+
+ // We need a dalvik-cache in /data/local/tmp so we have read-write access.
+ // Note: this will cause the runtime to optimize the DEX file (contained in
+ // the jar file) before executing it.
+ pw.println(String.format("export ANDROID_DATA=%s", DEVICE_LOCATION));
+ pw.println(String.format("export CLASSPATH=%s", getDeviceJarFilepath()));
+ pw.println(String.format("exec app_process /system/bin %s \"$@\"",
+ JAR_MAIN_CLASS_NAME));
+ } finally {
+ if (pw != null) {
+ pw.close();
+ }
+ }
+
+ return tempFile;
+ }
+
+ /**
+ * Helper class collecting all pids returned by 'adb jdwp' command.
+ */
+ private class AdbJdwpOutputReader implements Runnable {
+ /**
+ * A list of all pids with a JDWP connection returned by 'adb jdwp'.
+ */
+ private final List<String> lines = new ArrayList<String>();
+
+ /**
+ * The input stream of the process running 'adb jdwp'.
+ */
+ private InputStream in;
+
+ public List<String> listPidsWithAdbJdwp() throws Exception {
+ // The 'adb jdwp' command does not return normally, it only terminates with Ctrl^C.
+ // Therefore we cannot use ITestDevice.executeAdbCommand but need to run that command
+ // in the background. Since we know the tested app is already running, we only need to
+ // capture the output for a short amount of time before stopping the 'adb jdwp'
+ // command.
+ String[] adbJdwpCommand = buildAdbCommand("jdwp");
+ Process adbProcess = RunUtil.getDefault().runCmdInBackground(adbJdwpCommand);
+ in = adbProcess.getInputStream();
+
+ // Read the output for 5s in a separate thread before stopping the command.
+ Thread t = new Thread(this);
+ t.start();
+ Thread.sleep(5000);
+
+ // Kill the 'adb jdwp' process and wait for the thread to stop.
+ adbProcess.destroy();
+ t.join();
+
+ return lines;
+ }
+
+ @Override
+ public void run() {
+ BufferedReader br = null;
+ try {
+ br = new BufferedReader(new InputStreamReader(in));
+ String line;
+ while ((line = readLineIgnoreException(br)) != null) {
+ lines.add(line);
+ }
+ } catch (IOException e) {
+ CLog.e(e);
+ } finally {
+ if (br != null) {
+ try {
+ br.close();
+ } catch (IOException e) {
+ // Ignore it.
+ }
+ }
+ }
+ }
+
+ private String readLineIgnoreException(BufferedReader reader) throws IOException {
+ try {
+ return reader.readLine();
+ } catch (IOException e) {
+ if (e instanceof EOFException) {
+ // This is expected when the process's input stream is closed.
+ return null;
+ } else {
+ throw e;
+ }
+ }
+ }
+ }
+
+ private String[] buildAdbCommand(String... args) {
+ return ArrayUtil.buildArray(new String[] {"adb", "-s", getDevice().getSerialNumber()},
+ args);
+ }
+
+ private boolean createRemoteDir(String remoteFilePath) throws DeviceNotAvailableException {
+ if (getDevice().doesFileExist(remoteFilePath)) {
+ return true;
+ }
+ File remoteFile = new File(remoteFilePath);
+ String parentPath = remoteFile.getParent();
+ if (parentPath != null) {
+ if (!createRemoteDir(parentPath)) {
+ return false;
+ }
+ }
+ getDevice().executeShellCommand(String.format("mkdir %s", remoteFilePath));
+ return getDevice().doesFileExist(remoteFilePath);
+ }
+}
diff --git a/libs/commonutil/src/com/android/cts/util/AbiUtils.java b/libs/commonutil/src/com/android/cts/util/AbiUtils.java
index 6f47d52..42336f3 100644
--- a/libs/commonutil/src/com/android/cts/util/AbiUtils.java
+++ b/libs/commonutil/src/com/android/cts/util/AbiUtils.java
@@ -157,6 +157,22 @@
}
/**
+ * @return the test name portion of the test id.
+ * e.g. armeabi-v7a android.mytest = android.mytest
+ */
+ public static String parseTestName(String id) {
+ return parseId(id)[1];
+ }
+
+ /**
+ * @return the abi portion of the test id.
+ * e.g. armeabi-v7a android.mytest = armeabi-v7a
+ */
+ public static String parseAbi(String id) {
+ return parseId(id)[0];
+ }
+
+ /**
* @param name The name of the ABI.
* @return The bitness of the ABI with the given name
*/
diff --git a/tests/app/src/android/app/cts/MockAlarmReceiver.java b/tests/app/src/android/app/cts/MockAlarmReceiver.java
index 5060cef..8745db6 100644
--- a/tests/app/src/android/app/cts/MockAlarmReceiver.java
+++ b/tests/app/src/android/app/cts/MockAlarmReceiver.java
@@ -25,17 +25,21 @@
* this class receive alarm from AlarmManagerTest
*/
public class MockAlarmReceiver extends BroadcastReceiver {
- public boolean alarmed = false;
- private Object mSync = new Object();
- public static final String MOCKACTION = "android.app.AlarmManagerTest.TEST_ALARMRECEIVER";
+ private final Object mSync = new Object();
+ public final String mTargetAction;
- public long elapsedTime;
- public long rtcTime;
+ public volatile boolean alarmed = false;
+ public volatile long elapsedTime;
+ public volatile long rtcTime;
+
+ public MockAlarmReceiver(String targetAction) {
+ mTargetAction = targetAction;
+ }
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
- if (action.equals(MOCKACTION)) {
+ if (action.equals(mTargetAction)) {
synchronized (mSync) {
alarmed = true;
elapsedTime = SystemClock.elapsedRealtime();
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index 2d2d460..dd8660f 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -1,5 +1,19 @@
[
{
+ description: "the UsageStats is not yet stable enough",
+ names: [
+ "android.app.usage.cts.UsageStatsTest"
+ ],
+ bug: 17536113
+},
+{
+ description: "the ConnectivityConstraintTest are not yet stable",
+ names: [
+ "android.jobscheduler.cts.ConnectivityConstraintTest"
+ ],
+ bug: 18117279
+},
+{
description: "tests a fragile by nature as they rely on hardcoded behavior",
names: [
"android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverText",
@@ -38,26 +52,6 @@
bug: 16720689
},
{
- description: "test can only run properly on a user build device when the bug is resolved",
- names: [
- "android.appwidget.cts.AppWidgetTest#testAppWidgetProviderCallbacks",
- "android.appwidget.cts.AppWidgetTest#testBindAppWidget",
- "android.appwidget.cts.AppWidgetTest#testCollectionWidgets",
- "android.appwidget.cts.AppWidgetTest#testDeleteHost",
- "android.appwidget.cts.AppWidgetTest#testDeleteHosts",
- "android.appwidget.cts.AppWidgetTest#testGetAppWidgetIds",
- "android.appwidget.cts.AppWidgetTest#testGetAppWidgetInfo",
- "android.appwidget.cts.AppWidgetTest#testGetAppWidgetOptions",
- "android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetId",
- "android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetIds",
- "android.appwidget.cts.AppWidgetTest#testTwoAppWidgetProviderCallbacks",
- "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaComponentName",
- "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetId",
- "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetIds"
- ],
- bug: 17993121
-},
-{
description: "A few WebGL tests are known to fail in WebView",
names: [
"android.webgl.cts.WebGLTest#test_conformance_extensions_oes_texture_float_with_video_html",
diff --git a/tests/expectations/unsupportedabis.txt b/tests/expectations/unsupportedabis.txt
index 817179b..7ad3682 100644
--- a/tests/expectations/unsupportedabis.txt
+++ b/tests/expectations/unsupportedabis.txt
@@ -9,11 +9,7 @@
"android.renderscriptlegacy.cts.LeakTest",
"android.renderscriptlegacy.cts.RSBase",
"android.renderscriptlegacy.cts.RSBaseCompute",
- "android.renderscriptlegacy.cts.VersionTest",
- "android.sample.cts.SampleDeviceResultTest",
- "android.sample.cts.SampleDeviceTest",
- "android.sample.cts.SampleHostResultTest",
- "android.sample.cts.SampleHostTest"
+ "android.renderscriptlegacy.cts.VersionTest"
]
}
]
diff --git a/tests/signature/src/android/signature/cts/JDiffClassDescription.java b/tests/signature/src/android/signature/cts/JDiffClassDescription.java
index 7e36c1c..afcaa15 100644
--- a/tests/signature/src/android/signature/cts/JDiffClassDescription.java
+++ b/tests/signature/src/android/signature/cts/JDiffClassDescription.java
@@ -731,7 +731,7 @@
Type type = f.getGenericType();
if (type != null) {
genericTypeName = type instanceof Class ? ((Class) type).getName() :
- type.toString();
+ type.toString().replace('$', '.');
}
if (genericTypeName == null || !genericTypeName.equals(field.mFieldType)) {
mResultObserver.notifyFailure(
diff --git a/tests/tests/app/src/android/app/cts/AlarmManagerTest.java b/tests/tests/app/src/android/app/cts/AlarmManagerTest.java
index 0780101..bfc3e1d 100644
--- a/tests/tests/app/src/android/app/cts/AlarmManagerTest.java
+++ b/tests/tests/app/src/android/app/cts/AlarmManagerTest.java
@@ -25,45 +25,86 @@
import android.cts.util.PollingCheck;
import android.os.SystemClock;
import android.test.AndroidTestCase;
+import android.util.Log;
public class AlarmManagerTest extends AndroidTestCase {
- private AlarmManager mAlarmManager;
+ public static final String MOCKACTION = "android.app.AlarmManagerTest.TEST_ALARMRECEIVER";
+ public static final String MOCKACTION2 = "android.app.AlarmManagerTest.TEST_ALARMRECEIVER2";
+
+ private AlarmManager mAm;
private Intent mIntent;
private PendingIntent mSender;
- private Intent mServiceIntent;
+ private Intent mIntent2;
+ private PendingIntent mSender2;
/*
* The default snooze delay: 5 seconds
*/
- private final long SNOOZE_DELAY = 5 * 1000L;
+ private static final long SNOOZE_DELAY = 5 * 1000L;
private long mWakeupTime;
private MockAlarmReceiver mMockAlarmReceiver;
+ private MockAlarmReceiver mMockAlarmReceiver2;
- private final int TIME_DELTA = 1000;
- private final int TIME_DELAY = 5000;
+ private static final int TIME_DELTA = 1000;
+ private static final int TIME_DELAY = 10000;
- class Sync {
- public boolean mIsConnected;
- public boolean mIsDisConnected;
- }
+ // Receiver registration/unregistration between tests races with the system process, so
+ // we add a little buffer time here to allow the system to process before we proceed.
+ // This value is in milliseconds.
+ private static final long REGISTER_PAUSE = 250;
+
+ // Constants used for validating exact vs inexact alarm batching immunity. We run a few
+ // trials of an exact alarm that is placed within an inexact alarm's window of opportunity,
+ // and mandate that the average observed delivery skew between the two be statistically
+ // significant -- i.e. that the two alarms are not being coalesced. We also place an
+ // additional exact alarm only a short time after the inexact alarm's nominal trigger time.
+ // If exact alarms are allowed to batch with inexact ones this will tend to have no effect,
+ // but in the correct behavior -- inexact alarms not permitted to batch with exact ones --
+ // this additional exact alarm will have the effect of guaranteeing that the inexact alarm
+ // must fire no later than it -- i.e. a considerable time before the significant, later
+ // exact alarm.
+ //
+ // The test essentially amounts to requiring that the inexact MOCKACTION alarm and
+ // the much later exact MOCKACTION2 alarm fire far apart, always; with an implicit
+ // insistence that alarm batches are delivered at the head of their window.
+ private static final long TEST_WINDOW_LENGTH = 5 * 1000L;
+ private static final long TEST_ALARM_FUTURITY = 6 * 1000L;
+ private static final long FAIL_DELTA = 50;
+ private static final long NUM_TRIALS = 5;
+ private static final long MAX_NEAR_DELIVERIES = 2;
@Override
protected void setUp() throws Exception {
super.setUp();
- mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
- mIntent = new Intent(MockAlarmReceiver.MOCKACTION);
+
+ mAm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+
+ mIntent = new Intent(MOCKACTION)
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mSender = PendingIntent.getBroadcast(mContext, 0, mIntent, 0);
- mMockAlarmReceiver = new MockAlarmReceiver();
- IntentFilter filter = new IntentFilter(MockAlarmReceiver.MOCKACTION);
+ mMockAlarmReceiver = new MockAlarmReceiver(mIntent.getAction());
+
+ mIntent2 = new Intent(MOCKACTION2)
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ mSender2 = PendingIntent.getBroadcast(mContext, 0, mIntent2, 0);
+ mMockAlarmReceiver2 = new MockAlarmReceiver(mIntent2.getAction());
+
+ IntentFilter filter = new IntentFilter(mIntent.getAction());
mContext.registerReceiver(mMockAlarmReceiver, filter);
+
+ IntentFilter filter2 = new IntentFilter(mIntent2.getAction());
+ mContext.registerReceiver(mMockAlarmReceiver2, filter2);
+
+ Thread.sleep(REGISTER_PAUSE);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
- if (mServiceIntent != null) {
- mContext.stopService(mServiceIntent);
- }
+ mContext.unregisterReceiver(mMockAlarmReceiver);
+ mContext.unregisterReceiver(mMockAlarmReceiver2);
+
+ Thread.sleep(REGISTER_PAUSE);
}
public void testSetTypes() throws Exception {
@@ -73,7 +114,7 @@
// test parameter type is RTC_WAKEUP
mMockAlarmReceiver.setAlarmedFalse();
mWakeupTime = System.currentTimeMillis() + SNOOZE_DELAY;
- mAlarmManager.set(AlarmManager.RTC_WAKEUP, mWakeupTime, mSender);
+ mAm.setExact(AlarmManager.RTC_WAKEUP, mWakeupTime, mSender);
new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
@Override
protected boolean check() {
@@ -85,7 +126,7 @@
// test parameter type is RTC
mMockAlarmReceiver.setAlarmedFalse();
mWakeupTime = System.currentTimeMillis() + SNOOZE_DELAY;
- mAlarmManager.set(AlarmManager.RTC, mWakeupTime, mSender);
+ mAm.setExact(AlarmManager.RTC, mWakeupTime, mSender);
new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
@Override
protected boolean check() {
@@ -97,7 +138,7 @@
// test parameter type is ELAPSED_REALTIME
mMockAlarmReceiver.setAlarmedFalse();
mWakeupTime = SystemClock.elapsedRealtime() + SNOOZE_DELAY;
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, mWakeupTime, mSender);
+ mAm.setExact(AlarmManager.ELAPSED_REALTIME, mWakeupTime, mSender);
new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
@Override
protected boolean check() {
@@ -109,7 +150,7 @@
// test parameter type is ELAPSED_REALTIME_WAKEUP
mMockAlarmReceiver.setAlarmedFalse();
mWakeupTime = SystemClock.elapsedRealtime() + SNOOZE_DELAY;
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mWakeupTime, mSender);
+ mAm.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, mWakeupTime, mSender);
new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
@Override
protected boolean check() {
@@ -125,7 +166,7 @@
// that would instead cause such alarms to never be triggered.
mMockAlarmReceiver.setAlarmedFalse();
mWakeupTime = -1000;
- mAlarmManager.set(AlarmManager.RTC, mWakeupTime, mSender);
+ mAm.set(AlarmManager.RTC, mWakeupTime, mSender);
new PollingCheck(TIME_DELAY) {
@Override
protected boolean check() {
@@ -134,10 +175,54 @@
}.run();
}
+ public void testExactAlarmBatching() throws Exception {
+ int deliveriesTogether = 0;
+ for (int i = 0; i < NUM_TRIALS; i++) {
+ final long now = System.currentTimeMillis();
+ final long windowStart = now + TEST_ALARM_FUTURITY;
+ final long exactStart = windowStart + TEST_WINDOW_LENGTH - 1;
+
+ mMockAlarmReceiver.setAlarmedFalse();
+ mMockAlarmReceiver2.setAlarmedFalse();
+ mAm.setWindow(AlarmManager.RTC_WAKEUP, windowStart, TEST_WINDOW_LENGTH, mSender);
+ mAm.setExact(AlarmManager.RTC_WAKEUP, exactStart, mSender2);
+
+ // Wait until a half-second beyond its target window, just to provide a
+ // little safety slop.
+ new PollingCheck(TEST_WINDOW_LENGTH + (windowStart - now) + 500) {
+ @Override
+ protected boolean check() {
+ return mMockAlarmReceiver.alarmed;
+ }
+ }.run();
+
+ // Now wait until 1 sec beyond the expected exact alarm fire time, or for at
+ // least one second if we're already past the nominal exact alarm fire time
+ long timeToExact = Math.max(exactStart - System.currentTimeMillis() + 1000, 1000);
+ new PollingCheck(timeToExact) {
+ @Override
+ protected boolean check() {
+ return mMockAlarmReceiver2.alarmed;
+ }
+ }.run();
+
+ // Success when we observe that the exact and windowed alarm are not being often
+ // delivered close together -- that is, when we can be confident that they are not
+ // being coalesced.
+ final long delta = Math.abs(mMockAlarmReceiver2.rtcTime - mMockAlarmReceiver.rtcTime);
+ Log.i("TEST", "[" + i + "] delta = " + delta);
+ if (delta < FAIL_DELTA) {
+ deliveriesTogether++;
+ assertTrue("Exact alarms appear to be coalescing with inexact alarms",
+ deliveriesTogether <= MAX_NEAR_DELIVERIES);
+ }
+ }
+ }
+
public void testSetRepeating() throws Exception {
mMockAlarmReceiver.setAlarmedFalse();
mWakeupTime = System.currentTimeMillis() + SNOOZE_DELAY;
- mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, mWakeupTime, TIME_DELAY / 2, mSender);
+ mAm.setRepeating(AlarmManager.RTC_WAKEUP, mWakeupTime, TIME_DELAY / 2, mSender);
new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
@Override
protected boolean check() {
@@ -151,13 +236,13 @@
return mMockAlarmReceiver.alarmed;
}
}.run();
- mAlarmManager.cancel(mSender);
+ mAm.cancel(mSender);
}
public void testCancel() throws Exception {
mMockAlarmReceiver.setAlarmedFalse();
mWakeupTime = System.currentTimeMillis() + SNOOZE_DELAY;
- mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, mWakeupTime, 1000, mSender);
+ mAm.setRepeating(AlarmManager.RTC_WAKEUP, mWakeupTime, 1000, mSender);
new PollingCheck(SNOOZE_DELAY + TIME_DELAY) {
@Override
protected boolean check() {
@@ -171,7 +256,7 @@
return mMockAlarmReceiver.alarmed;
}
}.run();
- mAlarmManager.cancel(mSender);
+ mAm.cancel(mSender);
Thread.sleep(TIME_DELAY);
mMockAlarmReceiver.setAlarmedFalse();
Thread.sleep(TIME_DELAY * 5);
@@ -179,8 +264,7 @@
}
public void testSetInexactRepeating() throws Exception {
-
- mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
+ mAm.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
AlarmManager.INTERVAL_FIFTEEN_MINUTES, mSender);
SystemClock.setCurrentTimeMillis(System.currentTimeMillis()
+ AlarmManager.INTERVAL_FIFTEEN_MINUTES);
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index 669de2d..90cb18a 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -78,7 +78,6 @@
private static final int MAX_VIDEO_SNAPSHOT_IMAGES = 5;
private static final int BURST_VIDEO_SNAPSHOT_NUM = 3;
private static final int SLOWMO_SLOW_FACTOR = 4;
- private static final int MAX_NUM_FRAME_DROP_ALLOWED = 4;
private List<Size> mSupportedVideoSizes;
private Surface mRecordingSurface;
private MediaRecorder mMediaRecorder;
@@ -910,15 +909,6 @@
// Snapshots in legacy mode pause the preview briefly. Skip the duration
// requirements for legacy mode unless this is fixed.
if (!mStaticInfo.isHardwareLevelLegacy()) {
- mCollector.expectTrue(
- String.format(
- "Video %dx%d Frame drop detected before video snapshot: " +
- "duration %dms (expected %dms)",
- mVideoSize.getWidth(), mVideoSize.getHeight(),
- durationMs, expectedDurationMs
- ),
- durationMs <= (expectedDurationMs * MAX_NUM_FRAME_DROP_ALLOWED)
- );
// Log a warning is there is any frame drop detected.
if (durationMs >= expectedDurationMs * 2) {
Log.w(TAG, String.format(
@@ -930,15 +920,6 @@
}
durationMs = (int) (nextTS - currentTS) / 1000000;
- mCollector.expectTrue(
- String.format(
- "Video %dx%d Frame drop detected after video snapshot: " +
- "duration %dms (expected %dms)",
- mVideoSize.getWidth(), mVideoSize.getHeight(),
- durationMs, expectedDurationMs
- ),
- durationMs <= (expectedDurationMs * MAX_NUM_FRAME_DROP_ALLOWED)
- );
// Log a warning is there is any frame drop detected.
if (durationMs >= expectedDurationMs * 2) {
Log.w(TAG, String.format(
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index fb2001f..a5c7083 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -57,7 +57,7 @@
private static final long SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST = 100000L; // 100us
private static final long SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST = 100000000; // 100ms
private static final int SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST = 100;
- private static final int SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST = 1600;
+ private static final int SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST = 800;
private static final int STATISTICS_INFO_MAX_FACE_COUNT_MIN_AT_LEAST = 4;
private static final int TONEMAP_MAX_CURVE_POINTS_AT_LEAST = 64;
private static final int CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MIN = -2;
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
index 3476895..019bd21 100644
--- a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
@@ -1859,6 +1859,7 @@
initializeMessageLooper(cameraId);
// Test if the parameters exists and minimum fps <= maximum fps.
+ final int INTERVAL_ERROR_THRESHOLD = 10;
int[] defaultFps = new int[2];
Parameters parameters = mCamera.getParameters();
parameters.getPreviewFpsRange(defaultFps);
@@ -1919,6 +1920,13 @@
// See if any frame duration violations occurred during preview run
AssertionFailedError e = callback.getDurationException();
if (e != null) throw(e);
+ int numIntervalError = callback.getNumIntervalError();
+ if (numIntervalError > INTERVAL_ERROR_THRESHOLD) {
+ fail(String.format(
+ "Too many preview callback frame intervals out of bounds: " +
+ "Count is %d, limit is %d",
+ numIntervalError, INTERVAL_ERROR_THRESHOLD));
+ }
}
// Test the invalid fps cases.
@@ -1948,6 +1956,7 @@
private ArrayList<Long> mFrames = new ArrayList<Long>();
private long firstFrameArrivalTime;
private AssertionFailedError mDurationException = null;
+ private int numIntervalError;
public void reset(double minFps, double maxFps) {
this.mMinFps = minFps;
@@ -1960,6 +1969,7 @@
mFrames.clear();
firstFrameArrivalTime = 0;
mDurationException = null;
+ numIntervalError = 0;
}
// This method tests if the actual fps is between minimum and maximum.
@@ -1997,18 +2007,15 @@
long lastArrivalTime = mFrames.get(mFrames.size() - 1);
double interval = arrivalTime - lastArrivalTime;
if (VERBOSE) Log.v(TAG, "Frame interval=" + interval);
- try {
- assertTrue("Frame interval (" + interval + "ms) is too " +
- "large. mMaxFrameInterval=" +
- mMaxFrameInterval + "ms",
- interval < mMaxFrameInterval *
- (1.0 + intervalMargin));
- assertTrue("Frame interval (" + interval + "ms) is too " +
- "small. mMinFrameInterval=" +
- mMinFrameInterval + "ms",
- interval > mMinFrameInterval *
- (1.0 - intervalMargin));
+ try {
+ if (interval > mMaxFrameInterval * (1.0 + intervalMargin) ||
+ interval < mMinFrameInterval * (1.0 - intervalMargin)) {
+ Log.i(TAG, "Bad frame interval=" + interval + "ms. Out out range " +
+ mMinFrameInterval * (1.0 - intervalMargin) + "/" +
+ mMaxFrameInterval * (1.0 + intervalMargin));
+ numIntervalError++;
+ }
// Check if the fps is within range.
double fpsMargin = 0.5; // x100 = percent
double avgInterval = (double)(arrivalTime - mFrames.get(0))
@@ -2035,6 +2042,9 @@
public AssertionFailedError getDurationException() {
return mDurationException;
}
+ public int getNumIntervalError() {
+ return numIntervalError;
+ }
}
private void assertEquals(Size expected, Size actual) {
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyChainTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyChainTest.java
index db6d6ba..7aa6a9d 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyChainTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyChainTest.java
@@ -16,10 +16,11 @@
package android.keystore.cts;
+import android.content.pm.PackageManager;
import android.security.KeyChain;
-import junit.framework.TestCase;
+import android.test.AndroidTestCase;
-public class KeyChainTest extends TestCase {
+public class KeyChainTest extends AndroidTestCase {
public void testIsKeyAlgorithmSupported_RequiredAlgorithmsSupported() throws Exception {
assertTrue("DSA must be supported", KeyChain.isKeyAlgorithmSupported("DSA"));
assertTrue("EC must be supported", KeyChain.isKeyAlgorithmSupported("EC"));
@@ -34,11 +35,21 @@
* tests in hardware/libhardware/tests/keymaster/
*/
public void testIsBoundKeyAlgorithm_RequiredAlgorithmsSupported() throws Exception {
- assertTrue("RSA must be hardware-backed by a hardware-specific Keymaster HAL",
- KeyChain.isBoundKeyAlgorithm("RSA"));
+ if (isLeanbackOnly()) {
+ KeyChain.isBoundKeyAlgorithm("RSA");
+ }
+ else {
+ assertTrue("RSA must be hardware-backed by a hardware-specific Keymaster HAL",
+ KeyChain.isBoundKeyAlgorithm("RSA"));
+ }
// These are not required, but must not throw an exception
KeyChain.isBoundKeyAlgorithm("DSA");
KeyChain.isBoundKeyAlgorithm("EC");
}
+
+ private boolean isLeanbackOnly() {
+ PackageManager pm = getContext().getPackageManager();
+ return (pm != null && pm.hasSystemFeature("android.software.leanback_only"));
+ }
}
diff --git a/tests/tests/media/libmediandkjni/native-media-jni.cpp b/tests/tests/media/libmediandkjni/native-media-jni.cpp
index 51d2cf2..850932f1 100644
--- a/tests/tests/media/libmediandkjni/native-media-jni.cpp
+++ b/tests/tests/media/libmediandkjni/native-media-jni.cpp
@@ -590,14 +590,14 @@
return false;
}
- ALOGI("pssh has %u entries", info->numentries);
+ ALOGI("pssh has %zd entries", info->numentries);
if (info->numentries != 2) {
return false;
}
for (size_t i = 0; i < info->numentries; i++) {
PsshEntry *entry = &info->entries[i];
- ALOGI("entry uuid %02x%02x..%02x%02x, data size %u",
+ ALOGI("entry uuid %02x%02x..%02x%02x, data size %zd",
entry->uuid[0],
entry->uuid[1],
entry->uuid[14],
diff --git a/tests/tests/media/res/raw/heap_oob_flac.mp3 b/tests/tests/media/res/raw/heap_oob_flac.mp3
new file mode 100644
index 0000000..ae542d0
--- /dev/null
+++ b/tests/tests/media/res/raw/heap_oob_flac.mp3
Binary files differ
diff --git a/tests/tests/media/res/raw/midi8sec.mid b/tests/tests/media/res/raw/midi8sec.mid
new file mode 100644
index 0000000..746aca1
--- /dev/null
+++ b/tests/tests/media/res/raw/midi8sec.mid
Binary files differ
diff --git a/tests/tests/media/res/raw/midi_a.mid b/tests/tests/media/res/raw/midi_a.mid
new file mode 100644
index 0000000..941885f
--- /dev/null
+++ b/tests/tests/media/res/raw/midi_a.mid
Binary files differ
diff --git a/tests/tests/media/res/raw/midi_b.mid b/tests/tests/media/res/raw/midi_b.mid
new file mode 100644
index 0000000..424c960
--- /dev/null
+++ b/tests/tests/media/res/raw/midi_b.mid
Binary files differ
diff --git a/tests/tests/media/res/raw/midi_cs.mid b/tests/tests/media/res/raw/midi_cs.mid
new file mode 100644
index 0000000..ee9cb23
--- /dev/null
+++ b/tests/tests/media/res/raw/midi_cs.mid
Binary files differ
diff --git a/tests/tests/media/res/raw/midi_e.mid b/tests/tests/media/res/raw/midi_e.mid
new file mode 100644
index 0000000..dac820d
--- /dev/null
+++ b/tests/tests/media/res/raw/midi_e.mid
Binary files differ
diff --git a/tests/tests/media/res/raw/midi_gs.mid b/tests/tests/media/res/raw/midi_gs.mid
new file mode 100644
index 0000000..1d43841
--- /dev/null
+++ b/tests/tests/media/res/raw/midi_gs.mid
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
index 50f1575..7b21997 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
@@ -78,11 +78,11 @@
*/
public class EncodeVirtualDisplayWithCompositionTest extends AndroidTestCase {
private static final String TAG = "EncodeVirtualDisplayWithCompositionTest";
- private static final boolean DBG = false;
+ private static final boolean DBG = true;
private static final String MIME_TYPE = "video/avc";
- private static final long DEFAULT_WAIT_TIMEOUT_MS = 5000;
- private static final long DEFAULT_WAIT_TIMEOUT_US = 5000000;
+ private static final long DEFAULT_WAIT_TIMEOUT_MS = 3000;
+ private static final long DEFAULT_WAIT_TIMEOUT_US = 3000000;
private static final int COLOR_RED = makeColor(100, 0, 0);
private static final int COLOR_BLUE = makeColor(0, 100, 0);
@@ -229,7 +229,7 @@
}
});
renderingThread.start();
- renderingThread.join(20000);
+ renderingThread.join(60000);
assertTrue(!renderingThread.isAlive());
if (mTestException != null) {
throw mTestException;
@@ -568,7 +568,7 @@
while (!mStopEncoding) {
int index = mEncoder.dequeueOutputBuffer(info, TIMEOUT_USEC_NORMAL);
if (DBG) {
- Log.i(TAG, "dequeOutputBuffer returned " + index);
+ Log.i(TAG, "encoder dequeOutputBuffer returned " + index);
}
if (index >= 0) {
if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
index 08e6212..67c0591 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
@@ -56,13 +56,14 @@
Log.i(TAG, "AvcBaseline12 not supported");
return; // TODO: Can we make this mandatory?
}
+
playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ "&itag=160&source=youtube&user=android-device-test"
+ "&sparams=ip,ipbits,expire,id,itag,source,user"
- + "&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
- + "&signature=341692D20FACCAE25B90EA2C131EA6ADCD8E2384."
- + "9EB08C174BE401AAD20FB85EE4DBA51A2882BB60"
- + "&key=test_key1", 256, 144, PLAY_TIME_MS);
+ + "&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ + "&signature=9EDCA0B395B8A949C511FD5E59B9F805CFF797FD."
+ + "702DE9BA7AF96785FD6930AD2DD693A0486C880E"
+ + "&key=ik0", 256, 144, PLAY_TIME_MS);
}
public void testAvcBaseline30() throws Exception {
@@ -77,10 +78,10 @@
playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ "&itag=18&source=youtube&user=android-device-test"
+ "&sparams=ip,ipbits,expire,id,itag,source,user"
- + "&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
- + "&signature=8701A45F6422229D46ABB25A22E2C00C94024606."
- + "08BCDF16C3F744C49D4C8A8AD1C38B3DC1810918"
- + "&key=test_key1", 640, 360, PLAY_TIME_MS);
+ + "&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ + "&signature=7DCDE3A6594D0B91A27676A3CDC3A87B149F82EA."
+ + "7A83031734CB1EDCE06766B6228842F954927960"
+ + "&key=ik0", 640, 360, PLAY_TIME_MS);
}
public void testAvcHigh31() throws Exception {
@@ -95,11 +96,10 @@
playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ "&itag=22&source=youtube&user=android-device-test"
+ "&sparams=ip,ipbits,expire,id,itag,source,user"
- + "&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
- + "&signature=42969CA8F7FFAE432B7135BC811F96F7C4172C3F."
- + "1A8A92EA714C1B7C98A05DDF2DE90854CDD7638B"
- + "&key=test_key1", 1280, 720, PLAY_TIME_MS);
-
+ + "&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ + "&signature=179525311196616BD8E1381759B0E5F81A9E91B5."
+ + "C4A50E44059FEBCC6BBC78E3B3A4E0E0065777"
+ + "&key=ik0", 1280, 720, PLAY_TIME_MS);
}
public void testAvcHigh40() throws Exception {
@@ -118,10 +118,10 @@
playVideoWithRetries("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ "&itag=137&source=youtube&user=android-device-test"
+ "&sparams=ip,ipbits,expire,id,itag,source,user"
- + "&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
- + "&signature=2C836E04C4DDC98649CD44C8B91813D98342D1D1."
- + "870A848D54CA08C197E5FDC34ED45E6ED7DB5CDA"
- + "&key=test_key1", 1920, 1080, PLAY_TIME_MS);
+ + "&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ + "&signature=B0976085596DD42DEA3F08307F76587241CB132B."
+ + "043B719C039E8B92F45391ADC0BE3665E2332930"
+ + "&key=ik0", 1920, 1080, PLAY_TIME_MS);
}
public void testHevcMain1() throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 78ba149..799fd59 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -85,6 +85,37 @@
}
}
+ public void testFlacHeapOverflow() throws Exception {
+ testIfMediaServerDied(R.raw.heap_oob_flac);
+ }
+
+ private void testIfMediaServerDied(int res) throws Exception {
+ mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+ @Override
+ public boolean onError(MediaPlayer mp, int what, int extra) {
+ assertTrue(mp == mMediaPlayer);
+ assertTrue("mediaserver process died", what != MediaPlayer.MEDIA_ERROR_SERVER_DIED);
+ return false;
+ }
+ });
+
+ mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ @Override
+ public void onCompletion(MediaPlayer mp) {
+ assertTrue(mp == mMediaPlayer);
+ mOnCompletionCalled.signal();
+ }
+ });
+
+ AssetFileDescriptor afd = mResources.openRawResourceFd(res);
+ mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+ afd.close();
+ mMediaPlayer.prepare();
+ mMediaPlayer.start();
+ mOnCompletionCalled.waitForSignal();
+ mMediaPlayer.release();
+ }
+
// Bug 13652927
public void testVorbisCrash() throws Exception {
MediaPlayer mp = mMediaPlayer;
@@ -239,6 +270,46 @@
}
}
+ public void testPlayMidi() throws Exception {
+ final int resid = R.raw.midi8sec;
+ final int midiDuration = 8000;
+ final int tolerance = 70;
+ final int seekDuration = 1000;
+
+ MediaPlayer mp = MediaPlayer.create(mContext, resid);
+ try {
+ mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
+ mp.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+
+ mp.start();
+
+ assertFalse(mp.isLooping());
+ mp.setLooping(true);
+ assertTrue(mp.isLooping());
+
+ assertEquals(midiDuration, mp.getDuration(), tolerance);
+ int pos = mp.getCurrentPosition();
+ assertTrue(pos >= 0);
+ assertTrue(pos < midiDuration - seekDuration);
+
+ mp.seekTo(pos + seekDuration);
+ assertEquals(pos + seekDuration, mp.getCurrentPosition(), tolerance);
+
+ // test stop and restart
+ mp.stop();
+ mp.reset();
+ AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
+ mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+ afd.close();
+ mp.prepare();
+ mp.start();
+
+ Thread.sleep(SLEEP_TIME);
+ } finally {
+ mp.release();
+ }
+ }
+
static class OutputListener {
int mSession;
AudioEffect mVc;
diff --git a/tests/tests/media/src/android/media/cts/SoundPoolMidiTest.java b/tests/tests/media/src/android/media/cts/SoundPoolMidiTest.java
new file mode 100644
index 0000000..a8c640e
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/SoundPoolMidiTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+
+public class SoundPoolMidiTest extends SoundPoolTest {
+
+ @Override
+ protected int getSoundA() {
+ return R.raw.midi_a;
+ }
+
+ @Override
+ protected int getSoundCs() {
+ return R.raw.midi_cs;
+ }
+
+ @Override
+ protected int getSoundE() {
+ return R.raw.midi_e;
+ }
+
+ @Override
+ protected int getSoundB() {
+ return R.raw.midi_b;
+ }
+
+ @Override
+ protected int getSoundGs() {
+ return R.raw.midi_gs;
+ }
+
+ @Override
+ protected String getFileName() {
+ return "midi_a.mid";
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
index 2b93064..419f3e0 100644
--- a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
@@ -65,51 +65,51 @@
playVideoTest("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ "&itag=13&source=youtube&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ "&sparams=ip,ipbits,expire,id,itag,source"
- + "&signature=6F5AEC448AAF88466D7A10EBB76020745405D33F."
- + "5050D35AE997E1535FE828B0DE99EF31A699D9D0"
- + "&key=test_key1&user=android-device-test", 176, 144);
+ + "&signature=5729247E22691EBB3E804DDD523EC42DC17DD8CE"
+ + ".443B81C1E8E6D64E4E1555F568BA46C206507D78"
+ + "&key=ik0&user=android-device-test", 176, 144);
}
public void testHTTP_H263_AMR_Video2() throws Exception {
playVideoTest("http://redirector.c.youtube.com/videoplayback?id=c80658495af60617"
+ "&itag=13&source=youtube&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ "&sparams=ip,ipbits,expire,id,itag,source"
- + "&signature=71749754E28115FD1C233E3BE96CDDC3F430CB74."
- + "49D1506DE694CC8FCEE63CB4F3AD41EB76C198CE"
- + "&key=test_key1&user=android-device-test", 176, 144);
+ + "&signature=508D82AB36939345BF6B8D0623CB6CABDD9C64C3"
+ + ".9B3336A96846DF38E5343C46AA57F6CF2956E427"
+ + "&key=ik0&user=android-device-test", 176, 144);
}
public void testHTTP_MPEG4SP_AAC_Video1() throws Exception {
playVideoTest("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ "&itag=17&source=youtube&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ "&sparams=ip,ipbits,expire,id,itag,source"
- + "&signature=197A9742C1EFCA95725F2F26DFFD512FC48C149F."
- + "A59B42FD490F6B591B292F3B2659A9723B980351"
- + "&key=test_key1&user=android-device-test", 176, 144);
+ + "&signature=837198AAADF6F36BA6B2D324F690A7C5B7AFE3FF"
+ + ".7138CE5E36D718220726C1FC305497FF2D082249"
+ + "&key=ik0&user=android-device-test", 176, 144);
}
public void testHTTP_MPEG4SP_AAC_Video2() throws Exception {
playVideoTest("http://redirector.c.youtube.com/videoplayback?id=c80658495af60617"
+ "&itag=17&source=youtube&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ "&sparams=ip,ipbits,expire,id,itag,source"
- + "&signature=0F84740A7E06F884127E78A6D7DE6DEA8F4B8BFD."
- + "248DF1E90B8137C30769C79BF23147F6BB3DFCDF"
- + "&key=test_key1&user=android-device-test", 176, 144);
+ + "&signature=70E979A621001201BC18622BDBF914FA870BDA40"
+ + ".6E78890B80F4A33A18835F775B1FF64F0A4D0003"
+ + "&key=ik0&user=android-device-test", 176, 144);
}
public void testHTTP_H264Base_AAC_Video1() throws Exception {
playVideoTest("http://redirector.c.youtube.com/videoplayback?id=271de9756065677e"
+ "&itag=18&source=youtube&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ "&sparams=ip,ipbits,expire,id,itag,source"
- + "&signature=3CFCAFB87EB9FC943FACDC54FEC8C725A801642C."
- + "7D77ACBC4CAF40349BF093E302B635757E45F345"
- + "&key=test_key1&user=android-device-test", 640, 360);
+ + "&signature=667AEEF54639926662CE62361400B8F8C1753B3F"
+ + ".15F46C382C68A9F121BA17BF1F56BEDEB4B06091"
+ + "&key=ik0&user=android-device-test", 640, 360);
}
public void testHTTP_H264Base_AAC_Video2() throws Exception {
playVideoTest("http://redirector.c.youtube.com/videoplayback?id=c80658495af60617"
+ "&itag=18&source=youtube&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ "&sparams=ip,ipbits,expire,id,itag,source"
- + "&signature=A11D8BA0AA67A27F1409BE0C0B96B756625DB88B."
- + "9BF4C93A130583ADBDF2B953AD5A8A58F518B012"
- + "&key=test_key1&user=android-device-test", 640, 360);
+ + "&signature=46A04ED550CA83B79B60060BA80C79FDA5853D26"
+ + ".49582D382B4A9AFAA163DED38D2AE531D85603C0"
+ + "&key=ik0&user=android-device-test", 640, 360);
}
// Streaming HLS video from YouTube
diff --git a/tests/tests/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/NsdManagerTest.java
index d1e4c44..d434728 100644
--- a/tests/tests/net/src/android/net/wifi/cts/NsdManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/NsdManagerTest.java
@@ -356,7 +356,7 @@
assertTrue(lastEvent.mInfo.getPort() == localPort);
assertTrue(eventCacheSize() == 1);
- assertTrue(checkForAdditionalEvents());
+ checkForAdditionalEvents();
clearEventCache();
// Unregister the service
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 d8df064..152789c 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -213,8 +213,9 @@
private void assertDisableOthers(WifiConfiguration wifiConfiguration, boolean disableOthers) {
for (WifiConfiguration w : mWifiManager.getConfiguredNetworks()) {
if ((!w.SSID.equals(wifiConfiguration.SSID)) && w.status != Status.CURRENT) {
- if (disableOthers)
+ if (disableOthers) {
assertEquals(Status.DISABLED, w.status);
+ }
}
}
}
@@ -321,6 +322,7 @@
// skip the test if WiFi is not supported
return;
}
+
// store the list of enabled networks, so they can be re-enabled after test completes
Set<String> enabledSsids = getEnabledNetworks(mWifiManager.getConfiguredNetworks());
try {
@@ -353,11 +355,6 @@
wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos);
assertDisableOthers(wifiConfiguration, disableOthers);
assertEquals(Status.ENABLED, wifiConfiguration.status);
- disableOthers = true;
-
- assertTrue(mWifiManager.enableNetwork(netId, disableOthers));
- wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos);
- assertDisableOthers(wifiConfiguration, disableOthers);
assertTrue(mWifiManager.disableNetwork(netId));
wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos);
diff --git a/tests/tests/os/jni/Android.mk b/tests/tests/os/jni/Android.mk
index 3d3bc33..32a5a9c 100644
--- a/tests/tests/os/jni/Android.mk
+++ b/tests/tests/os/jni/Android.mk
@@ -25,7 +25,8 @@
CtsOsJniOnLoad.cpp \
android_os_cts_CpuInstructions.cpp.arm \
android_os_cts_TaggedPointer.cpp \
- android_os_cts_OSFeatures.cpp
+ android_os_cts_OSFeatures.cpp \
+ android_os_cts_NoExecutePermissionTest.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
diff --git a/tests/tests/os/jni/CtsOsJniOnLoad.cpp b/tests/tests/os/jni/CtsOsJniOnLoad.cpp
index c6b88f5..3920915 100644
--- a/tests/tests/os/jni/CtsOsJniOnLoad.cpp
+++ b/tests/tests/os/jni/CtsOsJniOnLoad.cpp
@@ -25,6 +25,8 @@
extern int register_android_os_cts_OSFeatures(JNIEnv*);
+extern int register_android_os_cts_NoExecutePermissionTest(JNIEnv*);
+
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
@@ -48,5 +50,9 @@
return JNI_ERR;
}
+ if (register_android_os_cts_NoExecutePermissionTest(env)) {
+ return JNI_ERR;
+ }
+
return JNI_VERSION_1_4;
}
diff --git a/tests/tests/os/jni/android_os_cts_NoExecutePermissionTest.cpp b/tests/tests/os/jni/android_os_cts_NoExecutePermissionTest.cpp
new file mode 100644
index 0000000..e30599c
--- /dev/null
+++ b/tests/tests/os/jni/android_os_cts_NoExecutePermissionTest.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <jni.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <cutils/log.h>
+#include <inttypes.h>
+
+static jboolean isAddressExecutable(uintptr_t address) {
+ char line[1024];
+ jboolean retval = false;
+ FILE *fp = fopen("/proc/self/maps", "re");
+ if (fp == NULL) {
+ ALOGE("Unable to open /proc/self/maps: %s", strerror(errno));
+ return false;
+ }
+ while(fgets(line, sizeof(line), fp) != NULL) {
+ uintptr_t start;
+ uintptr_t end;
+ char permissions[10];
+ int scan = sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %9s ", &start, &end, permissions);
+ if ((scan == 3) && (start <= address) && (address < end)) {
+ retval = (permissions[2] == 'x');
+ break;
+ }
+ }
+ fclose(fp);
+ return retval;
+}
+
+static jboolean android_os_cts_NoExecutePermissionTest_isMyCodeExecutable(JNIEnv*, jobject)
+{
+ return isAddressExecutable((uintptr_t) __builtin_return_address(0));
+}
+
+static jboolean android_os_cts_NoExecutePermissionTest_isStackExecutable(JNIEnv*, jobject)
+{
+ unsigned int foo;
+ return isAddressExecutable((uintptr_t) &foo);
+}
+
+
+static jboolean android_os_cts_NoExecutePermissionTest_isHeapExecutable(JNIEnv*, jobject)
+{
+ unsigned int* foo = (unsigned int *) malloc(sizeof(unsigned int));
+ if (foo == NULL) {
+ ALOGE("Unable to allocate memory");
+ return false;
+ }
+ jboolean result = isAddressExecutable((uintptr_t) foo);
+ free(foo);
+ return result;
+}
+
+static JNINativeMethod gMethods[] = {
+ { "isMyCodeExecutable", "()Z",
+ (void *) android_os_cts_NoExecutePermissionTest_isMyCodeExecutable },
+ { "isStackExecutable", "()Z",
+ (void *) android_os_cts_NoExecutePermissionTest_isStackExecutable },
+ { "isHeapExecutable", "()Z",
+ (void *) android_os_cts_NoExecutePermissionTest_isHeapExecutable }
+};
+
+int register_android_os_cts_NoExecutePermissionTest(JNIEnv* env)
+{
+ jclass clazz = env->FindClass("android/os/cts/NoExecutePermissionTest");
+
+ return env->RegisterNatives(clazz, gMethods,
+ sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/os/src/android/os/cts/BuildVersionTest.java b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
index 6069ee6..e335901 100644
--- a/tests/tests/os/src/android/os/cts/BuildVersionTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
@@ -28,7 +28,8 @@
public class BuildVersionTest extends TestCase {
private static final String LOG_TAG = "BuildVersionTest";
- private static final Set<String> EXPECTED_RELEASES = new HashSet<String>(Arrays.asList("5.0"));
+ private static final Set<String> EXPECTED_RELEASES =
+ new HashSet<String>(Arrays.asList("5.0", "5.0.1", "5.0.2"));
private static final int EXPECTED_SDK = 21;
private static final String EXPECTED_BUILD_VARIANT = "user";
private static final String EXPECTED_TAG = "release-keys";
diff --git a/tests/tests/os/src/android/os/cts/NoExecutePermissionTest.java b/tests/tests/os/src/android/os/cts/NoExecutePermissionTest.java
index 43afb53..224ab46 100644
--- a/tests/tests/os/src/android/os/cts/NoExecutePermissionTest.java
+++ b/tests/tests/os/src/android/os/cts/NoExecutePermissionTest.java
@@ -28,45 +28,26 @@
*/
public class NoExecutePermissionTest extends TestCase {
- public void testNoExecutePermission() throws FileNotFoundException {
+ static {
+ System.loadLibrary("ctsos_jni");
+ }
+
+ public void testNoExecuteStack() {
if (!cpuHasNxSupport()) {
return;
}
+ assertFalse(isStackExecutable());
+ }
- String heapPermissions = null;
- String stackPermissions = null;
-
- Scanner scanner = null;
- try {
- scanner = new Scanner(new File("/proc/self/maps"));
- while (scanner.hasNextLine()) {
- String line = scanner.nextLine().trim();
- String[] fields = line.split("\\s+");
-
- // Sample line:
- // 0001d000-00024000 rw-p 00000000 00:00 0 [heap]
- if (fields != null && fields.length >= 1) {
- String permissions = fields[1];
- if (fields.length >= 6) {
- String tag = fields[5];
- if ("[heap]".equals(tag)) {
- heapPermissions = permissions;
- } else if ("[stack]".equals(tag)) {
- stackPermissions = permissions;
- }
- }
- }
- }
- } finally {
- if (scanner != null) {
- scanner.close();
- }
+ public void testNoExecuteHeap() {
+ if (!cpuHasNxSupport()) {
+ return;
}
+ assertFalse(isHeapExecutable());
+ }
- if (heapPermissions != null) {
- assertEquals("NX (No Execute) not enabled for heap", "rw-p", heapPermissions);
- }
- assertEquals("NX (No Execute) not enabled for stack", "rw-p", stackPermissions);
+ public void testExecuteCode() {
+ assertTrue(isMyCodeExecutable());
}
private static boolean cpuHasNxSupport() {
@@ -84,4 +65,8 @@
// have NX support.
return true;
}
+
+ private static native boolean isStackExecutable();
+ private static native boolean isHeapExecutable();
+ private static native boolean isMyCodeExecutable();
}
diff --git a/tests/tests/rscpp/Android.mk b/tests/tests/rscpp/Android.mk
index 60adc05..0eb32b5 100644
--- a/tests/tests/rscpp/Android.mk
+++ b/tests/tests/rscpp/Android.mk
@@ -31,7 +31,7 @@
LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
LOCAL_JNI_SHARED_LIBRARIES := librscpptest_jni
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
LOCAL_SDK_VERSION := current
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RS3DLUTTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RS3DLUTTest.java
index 470593c..f278835 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RS3DLUTTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RS3DLUTTest.java
@@ -39,7 +39,6 @@
RSUtils.genRandom(0x419144, 255, 1, -128, baseAlloc);
int[] colorCube = new int[lutSize * lutSize * lutSize * 4];
RSUtils.genRandom(0x555007, 255, 1, -128, colorCube);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y * 4];
byte[] byteColorCube = new byte[lutSize * lutSize * lutSize * 4];
for (int i = 0; i < X * Y * 4; i++) {
@@ -49,7 +48,6 @@
byteColorCube[i] = (byte)colorCube[i];
}
-
Type.Builder build = new Type.Builder(mRS, Element.RGBA_8888(mRS));
build.setX(X);
build.setY(Y);
@@ -58,10 +56,10 @@
rsInput.copyFromUnchecked(byteAlloc);
Type.Builder buildCube = new Type.Builder(mRS, Element.RGBA_8888(mRS));
- build.setX(lutSize);
- build.setY(lutSize);
- build.setZ(lutSize);
- Allocation cube = Allocation.createTyped(mRS, build.create());
+ buildCube.setX(lutSize);
+ buildCube.setY(lutSize);
+ buildCube.setZ(lutSize);
+ Allocation cube = Allocation.createTyped(mRS, buildCube.create());
cube.copyFromUnchecked(byteColorCube);
ScriptIntrinsic3DLUT lut = ScriptIntrinsic3DLUT.create(mRS, Element.RGBA_8888(mRS));
@@ -70,12 +68,12 @@
byte[] nativeByteAlloc = new byte[X * Y * 4];
lutTest(this.getContext().getCacheDir().toString(), X, Y, lutSize, byteAlloc, byteColorCube, nativeByteAlloc);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y * 4; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSBlendTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSBlendTest.java
index 025d470..1c6dc51 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSBlendTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSBlendTest.java
@@ -36,7 +36,6 @@
for (int iter = 0; iter < 15; iter++) {
int[] baseAlloc = new int[X * Y * 4];
RSUtils.genRandom(0x789321, 255, 1, -128, baseAlloc);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y * 4];
for (int i = 0; i < X * Y * 4; i++) {
byteAlloc[i] = (byte)baseAlloc[i];
@@ -110,12 +109,11 @@
}
blendTest(this.getContext().getCacheDir().toString(), X, Y, byteAlloc, byteAlloc2, iter);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y * 4; i++) {
- assertTrue(byteAlloc[i] == byteAlloc2[i]);
- }
- mRS.destroy();
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(byteAlloc2);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSBlurTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSBlurTest.java
index 70f15fc..34bb7ad 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSBlurTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSBlurTest.java
@@ -35,7 +35,6 @@
public void testRSBlurOneChannel() {
int[] baseAlloc = new int[X * Y];
RSUtils.genRandom(0x1DEFF, 255, 1, -128, baseAlloc);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y];
for (int i = 0; i < X * Y; i++) {
byteAlloc[i] = (byte)baseAlloc[i];
@@ -54,19 +53,17 @@
byte[] nativeByteAlloc = new byte[X * Y];
blurTest(this.getContext().getCacheDir().toString(), X, Y, byteAlloc, nativeByteAlloc, true);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
-
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
public void testRSBlurFourChannels() {
int[] baseAlloc = new int[X * Y * 4];
RSUtils.genRandom(0xFAFADE10, 255, 1, -128, baseAlloc);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y * 4];
for (int i = 0; i < X * Y * 4; i++) {
byteAlloc[i] = (byte)baseAlloc[i];
@@ -85,13 +82,12 @@
byte[] nativeByteAlloc = new byte[X * Y * 4];
blurTest(this.getContext().getCacheDir().toString(), X, Y, byteAlloc, nativeByteAlloc, false);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y * 4; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
-
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSColorMatrixTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSColorMatrixTest.java
index efa28bb..5260ed9 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSColorMatrixTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSColorMatrixTest.java
@@ -35,7 +35,6 @@
public void testRSColorMatrix0() {
int[] baseAlloc = new int[X * Y * 4];
RSUtils.genRandom(0x251107, 255, 1, -128, baseAlloc);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y * 4];
for (int i = 0; i < X * Y * 4; i++) {
byteAlloc[i] = (byte)baseAlloc[i];
@@ -66,18 +65,16 @@
byte[] nativeByteAlloc = new byte[X * Y * 4];
colorMatrixTest(this.getContext().getCacheDir().toString(), X, Y, byteAlloc, nativeByteAlloc, coeffs, 0);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y * 4; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
-
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
public void testRSColorMatrix1() {
int[] baseAlloc = new int[X * Y * 4];
RSUtils.genRandom(0x251106, 255, 1, -128, baseAlloc);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y * 4];
for (int i = 0; i < X * Y * 4; i++) {
byteAlloc[i] = (byte)baseAlloc[i];
@@ -98,18 +95,17 @@
byte[] nativeByteAlloc = new byte[X * Y * 4];
colorMatrixTest(this.getContext().getCacheDir().toString(), X, Y, byteAlloc, nativeByteAlloc, coeffs, 1);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y * 4; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
public void testRSColorMatrix2() {
int[] baseAlloc = new int[X * Y * 4];
RSUtils.genRandom(0x251105, 255, 1, -128, baseAlloc);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y * 4];
for (int i = 0; i < X * Y * 4; i++) {
byteAlloc[i] = (byte)baseAlloc[i];
@@ -134,18 +130,17 @@
byte[] nativeByteAlloc = new byte[X * Y * 4];
colorMatrixTest(this.getContext().getCacheDir().toString(), X, Y, byteAlloc, nativeByteAlloc, coeffs, 2);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y * 4; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
public void testRSColorMatrix3() {
int[] baseAlloc = new int[X * Y * 4];
RSUtils.genRandom(0x251104, 255, 1, -128, baseAlloc);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y * 4];
for (int i = 0; i < X * Y * 4; i++) {
byteAlloc[i] = (byte)baseAlloc[i];
@@ -166,18 +161,17 @@
byte[] nativeByteAlloc = new byte[X * Y * 4];
colorMatrixTest(this.getContext().getCacheDir().toString(), X, Y, byteAlloc, nativeByteAlloc, coeffs, 3);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y * 4; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
public void testRSColorMatrix4() {
int[] baseAlloc = new int[X * Y * 4];
RSUtils.genRandom(0x251103, 255, 1, -128, baseAlloc);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y * 4];
for (int i = 0; i < X * Y * 4; i++) {
byteAlloc[i] = (byte)baseAlloc[i];
@@ -198,12 +192,12 @@
byte[] nativeByteAlloc = new byte[X * Y * 4];
colorMatrixTest(this.getContext().getCacheDir().toString(), X, Y, byteAlloc, nativeByteAlloc, coeffs, 4);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y * 4; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSConvolveTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSConvolveTest.java
index 0cd5c79..2a3579e 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSConvolveTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSConvolveTest.java
@@ -46,7 +46,6 @@
coeffs[8] = .5f;
RSUtils.genRandom(0x1DEFFD0, 255, 1, -128, baseAlloc);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y];
for (int i = 0; i < X * Y; i++) {
byteAlloc[i] = (byte)baseAlloc[i];
@@ -65,12 +64,11 @@
byte[] nativeByteAlloc = new byte[X * Y];
convolveTest(this.getContext().getCacheDir().toString(), X, Y, byteAlloc, nativeByteAlloc, coeffs, true);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
-
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
public void testConvolve5x5() {
@@ -123,13 +121,13 @@
byte[] nativeByteAlloc = new byte[X * Y];
convolveTest(this.getContext().getCacheDir().toString(), X, Y, byteAlloc, nativeByteAlloc, coeffs, false);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSCppTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSCppTest.java
index b2bf33e..9b09cc7 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSCppTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSCppTest.java
@@ -19,23 +19,91 @@
import android.content.Context;
import android.content.res.Resources;
import android.test.AndroidTestCase;
-import android.renderscript.*;
+import android.renderscript.RenderScript.RSErrorHandler;
+import android.renderscript.RenderScript.RSMessageHandler;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.RenderScript;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
import android.util.Log;
public class RSCppTest extends AndroidTestCase {
Context mCtx;
Resources mRes;
+ RenderScript mRS;
+ protected ScriptC_verify mVerify;
+
+ private int result;
+ private boolean msgHandled;
+
+ private static final int RS_MSG_TEST_PASSED = 100;
+ private static final int RS_MSG_TEST_FAILED = 101;
+
+ RSMessageHandler mRsMessage = new RSMessageHandler() {
+ public void run() {
+ if (result == 0) {
+ switch (mID) {
+ case RS_MSG_TEST_PASSED:
+ case RS_MSG_TEST_FAILED:
+ result = mID;
+ break;
+ default:
+ fail("Got unexpected RS message");
+ return;
+ }
+ }
+ msgHandled = true;
+ }
+ };
+
+ protected void waitForMessage() {
+ while (!msgHandled) {
+ Thread.yield();
+ }
+ }
+
+ protected boolean FoundError = false;
+ protected RSErrorHandler mRsError = new RSErrorHandler() {
+ public void run() {
+ FoundError = true;
+ Log.e("RSCppCTS", mErrorMessage);
+ throw new RSRuntimeException("Received error " + mErrorNum +
+ " message " + mErrorMessage);
+ }
+ };
+
+ protected void checkForErrors() {
+ mRS.finish();
+ mVerify.invoke_checkError();
+ waitForMessage();
+ assertFalse(FoundError);
+ assertTrue(result != RS_MSG_TEST_FAILED);
+ }
@Override
protected void setUp() throws Exception {
super.setUp();
+ result = 0;
+ msgHandled = false;
mCtx = getContext();
mRes = mCtx.getResources();
+ mRS = RenderScript.create(mCtx);
+ mRS.setMessageHandler(mRsMessage);
+ mVerify = new ScriptC_verify(mRS);
+ mVerify.set_gAllowedIntError(3);
}
@Override
protected void tearDown() throws Exception {
+ if (mVerify != null) {
+ mVerify.destroy();
+ mVerify = null;
+ }
+ if (mRS != null) {
+ mRS.destroy();
+ mRS = null;
+ }
super.tearDown();
}
}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSInitTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSInitTest.java
index ca6be9c..f6b4251 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSInitTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSInitTest.java
@@ -30,10 +30,10 @@
native boolean initTest(String path);
public void testRSInit() {
for (int i = 0; i < 1000; i++) {
- RenderScript mRS = RenderScript.create(getContext());
- mRS.destroy();
+ RenderScript mRSt = RenderScript.create(getContext());
+ mRSt.destroy();
Log.d("rscpptest", "Java iteration " + i);
}
assertTrue(initTest(this.getContext().getCacheDir().toString()));
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSLUTTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSLUTTest.java
index f1ea040..aa24209 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSLUTTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSLUTTest.java
@@ -35,7 +35,6 @@
public void testRSLUT() {
int[] baseAlloc = new int[X * Y * 4];
RSUtils.genRandom(0x72727272, 255, 1, -128, baseAlloc);
- RenderScript mRS = RenderScript.create(getContext());
byte[] byteAlloc = new byte[X * Y * 4];
for (int i = 0; i < X * Y * 4; i++) {
byteAlloc[i] = (byte)baseAlloc[i];
@@ -58,12 +57,12 @@
byte[] nativeByteAlloc = new byte[X * Y * 4];
lutTest(this.getContext().getCacheDir().toString().toString(), X, Y, byteAlloc, nativeByteAlloc);
- rsOutput.copyTo(byteAlloc);
- for (int i = 0; i < X * Y * 4; i++) {
- assertTrue(byteAlloc[i] == nativeByteAlloc[i]);
- }
+ Allocation rsCppOutput = Allocation.createTyped(mRS, build.create());
+ rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+ mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+ checkForErrors();
}
-}
\ No newline at end of file
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/verify.rs b/tests/tests/rscpp/src/android/cts/rscpp/verify.rs
new file mode 100644
index 0000000..7fd44d3
--- /dev/null
+++ b/tests/tests/rscpp/src/android/cts/rscpp/verify.rs
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.cts.rscpp)
+
+/* These constants must match those in RSCppTest.java */
+static const int RS_MSG_TEST_PASSED = 100;
+static const int RS_MSG_TEST_FAILED = 101;
+
+int gAllowedIntError = 0;
+static bool hadError = false;
+static int2 errorLoc = {0,0};
+
+
+static bool compare_float(float f1, float f2) {
+ if (fabs(f1-f2) > 0.0001f) {
+ hadError = true;
+ return false;
+ }
+ return true;
+}
+
+static bool verify_float4(rs_allocation in1, rs_allocation in2)
+{
+ uint32_t w = rsAllocationGetDimX(in1);
+ uint32_t h = rsAllocationGetDimY(in1);
+ for (uint32_t y=0; y < h; y++) {
+ for (uint32_t x=0; x < w; x++) {
+ float4 pref = rsGetElementAt_float4(in1, x, y);
+ float4 ptst = rsGetElementAt_float4(in2, x, y);
+ bool e = !compare_float(pref.x, ptst.x);
+ e |= !compare_float(pref.y, ptst.y);
+ e |= !compare_float(pref.z, ptst.z);
+ e |= !compare_float(pref.w, ptst.w);
+ if (e) {
+ errorLoc.x = x;
+ errorLoc.y = y;
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static bool verify_float3(rs_allocation in1, rs_allocation in2)
+{
+ uint32_t w = rsAllocationGetDimX(in1);
+ uint32_t h = rsAllocationGetDimY(in1);
+ for (uint32_t y=0; y < h; y++) {
+ for (uint32_t x=0; x < w; x++) {
+ float3 pref = rsGetElementAt_float3(in1, x, y);
+ float3 ptst = rsGetElementAt_float3(in2, x, y);
+ bool e = !compare_float(pref.x, ptst.x);
+ e |= !compare_float(pref.y, ptst.y);
+ e |= !compare_float(pref.z, ptst.z);
+ if (e) {
+ errorLoc.x = x;
+ errorLoc.y = y;
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static bool verify_float2(rs_allocation in1, rs_allocation in2)
+{
+ uint32_t w = rsAllocationGetDimX(in1);
+ uint32_t h = rsAllocationGetDimY(in1);
+ for (uint32_t y=0; y < h; y++) {
+ for (uint32_t x=0; x < w; x++) {
+ float2 pref = rsGetElementAt_float2(in1, x, y);
+ float2 ptst = rsGetElementAt_float2(in2, x, y);
+ bool e = !compare_float(pref.x, ptst.x);
+ e |= !compare_float(pref.y, ptst.y);
+ if (e) {
+ errorLoc.x = x;
+ errorLoc.y = y;
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static bool verify_float(rs_allocation in1, rs_allocation in2)
+{
+ uint32_t w = rsAllocationGetDimX(in1);
+ uint32_t h = rsAllocationGetDimY(in1);
+ for (uint32_t y=0; y < h; y++) {
+ for (uint32_t x=0; x < w; x++) {
+ float pref = rsGetElementAt_float(in1, x, y);
+ float ptst = rsGetElementAt_float(in2, x, y);
+ bool e = !compare_float(pref, ptst);
+ if (e) {
+ errorLoc.x = x;
+ errorLoc.y = y;
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static bool verify_uchar4(rs_allocation in1, rs_allocation in2)
+{
+ int merr = 0;
+ uint32_t w = rsAllocationGetDimX(in1);
+ uint32_t h = rsAllocationGetDimY(in1);
+ for (uint32_t y=0; y < h; y++) {
+ for (uint32_t x=0; x < w; x++) {
+ int4 pref = convert_int4(rsGetElementAt_uchar4(in1, x, y));
+ int4 ptst = convert_int4(rsGetElementAt_uchar4(in2, x, y));
+ int4 d = convert_int4(abs(pref - ptst));
+ int e = 0;
+ e = max(e, d.x);
+ e = max(e, d.y);
+ e = max(e, d.z);
+ e = max(e, d.w);
+ if (e > gAllowedIntError) {
+ errorLoc.x = x;
+ errorLoc.y = y;
+ hadError = true;
+ return false;
+ }
+ merr = max(e, merr);
+ }
+ }
+ return true;
+}
+
+static bool verify_uchar3(rs_allocation in1, rs_allocation in2)
+{
+ int merr = 0;
+ uint32_t w = rsAllocationGetDimX(in1);
+ uint32_t h = rsAllocationGetDimY(in1);
+ for (uint32_t y=0; y < h; y++) {
+ for (uint32_t x=0; x < w; x++) {
+ int3 pref = convert_int3(rsGetElementAt_uchar3(in1, x, y));
+ int3 ptst = convert_int3(rsGetElementAt_uchar3(in2, x, y));
+ int3 d = convert_int3(abs(pref - ptst));
+ int e = 0;
+ e = max(e, d.x);
+ e = max(e, d.y);
+ e = max(e, d.z);
+ if (e > gAllowedIntError) {
+ errorLoc.x = x;
+ errorLoc.y = y;
+ hadError = true;
+ return false;
+ }
+ merr = max(e, merr);
+ }
+ }
+ return true;
+}
+
+static bool verify_uchar2(rs_allocation in1, rs_allocation in2)
+{
+ int merr = 0;
+ uint32_t w = rsAllocationGetDimX(in1);
+ uint32_t h = rsAllocationGetDimY(in1);
+ for (uint32_t y=0; y < h; y++) {
+ for (uint32_t x=0; x < w; x++) {
+ int2 pref = convert_int2(rsGetElementAt_uchar2(in1, x, y));
+ int2 ptst = convert_int2(rsGetElementAt_uchar2(in2, x, y));
+ int2 d = convert_int2(abs(pref - ptst));
+ int e = 0;
+ e = max(e, d.x);
+ e = max(e, d.y);
+ if (e > gAllowedIntError) {
+ errorLoc.x = x;
+ errorLoc.y = y;
+ hadError = true;
+ return false;
+ }
+ merr = max(e, merr);
+ }
+ }
+ return true;
+}
+
+static bool verify_uchar(rs_allocation in1, rs_allocation in2)
+{
+ int merr = 0;
+ uint32_t w = rsAllocationGetDimX(in1);
+ uint32_t h = rsAllocationGetDimY(in1);
+ for (uint32_t y=0; y < h; y++) {
+ for (uint32_t x=0; x < w; x++) {
+ int pref = rsGetElementAt_uchar(in1, x, y);
+ int ptst = rsGetElementAt_uchar(in2, x, y);
+ int e = abs(pref - ptst);
+ if (e > gAllowedIntError) {
+ errorLoc.x = x;
+ errorLoc.y = y;
+ hadError = true;
+ return false;
+ }
+ merr = max(e, merr);
+ }
+ }
+ return true;
+}
+
+#define printCell(txt, a, xy) \
+{ \
+ rs_element e = rsAllocationGetElement(a); \
+ rs_data_type dt = rsElementGetDataType(e); \
+ uint32_t vs = rsElementGetVectorSize(e); \
+ \
+ if (dt == RS_TYPE_UNSIGNED_8) { \
+ switch(vs) { \
+ case 4: \
+ rsDebug(txt, rsGetElementAt_uchar4(a, xy.x, xy.y)); \
+ break; \
+ case 3: \
+ rsDebug(txt, rsGetElementAt_uchar3(a, xy.x, xy.y)); \
+ break; \
+ case 2: \
+ rsDebug(txt, rsGetElementAt_uchar2(a, xy.x, xy.y)); \
+ break; \
+ case 1: \
+ rsDebug(txt, rsGetElementAt_uchar(a, xy.x, xy.y)); \
+ break; \
+ } \
+ } else { \
+ switch(vs) { \
+ case 4: \
+ rsDebug(txt, rsGetElementAt_float4(a, xy.x, xy.y)); \
+ break; \
+ case 3: \
+ rsDebug(txt, rsGetElementAt_float3(a, xy.x, xy.y)); \
+ break; \
+ case 2: \
+ rsDebug(txt, rsGetElementAt_float2(a, xy.x, xy.y)); \
+ break; \
+ case 1: \
+ rsDebug(txt, rsGetElementAt_float(a, xy.x, xy.y)); \
+ break; \
+ } \
+ } \
+}
+
+void verify(rs_allocation ref_in, rs_allocation tst_in, rs_allocation src_in)
+{
+ rs_element e = rsAllocationGetElement(ref_in);
+ rs_data_type dt = rsElementGetDataType(e);
+ uint32_t vs = rsElementGetVectorSize(e);
+ bool valid = false;
+
+ if (dt == RS_TYPE_UNSIGNED_8) {
+ switch(vs) {
+ case 4:
+ valid = verify_uchar4(ref_in, tst_in);
+ break;
+ case 3:
+ valid = verify_uchar3(ref_in, tst_in);
+ break;
+ case 2:
+ valid = verify_uchar2(ref_in, tst_in);
+ break;
+ case 1:
+ valid = verify_uchar(ref_in, tst_in);
+ break;
+ }
+ } else {
+ switch(vs) {
+ case 4:
+ valid = verify_float4(ref_in, tst_in);
+ break;
+ case 3:
+ valid = verify_float3(ref_in, tst_in);
+ break;
+ case 2:
+ valid = verify_float2(ref_in, tst_in);
+ break;
+ case 1:
+ valid = verify_float(ref_in, tst_in);
+ break;
+ }
+ }
+ if (!valid) {
+ rsDebug("verify failure at xy", errorLoc);
+ printCell("start value ", src_in, errorLoc);
+ printCell("reference value ", ref_in, errorLoc);
+ printCell("test value ", tst_in, errorLoc);
+ }
+}
+
+void checkError()
+{
+ if (hadError) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ } else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index fa862c1..46d0868 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -31,7 +31,8 @@
android_security_cts_SeccompDeathTestService.cpp \
android_security_cts_SELinuxTest.cpp \
android_security_cts_MMapExecutableTest.cpp \
- android_security_cts_NetlinkSocket.cpp
+ android_security_cts_NetlinkSocket.cpp \
+ android_security_cts_AudioPolicyBinderTest.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index 0e91b4e..ca8e841 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -26,6 +26,7 @@
extern int register_android_security_cts_SeccompDeathTestService(JNIEnv*);
extern int register_android_security_cts_SELinuxTest(JNIEnv*);
extern int register_android_security_cts_MMapExecutableTest(JNIEnv* env);
+extern int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env);
jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
@@ -70,5 +71,9 @@
return JNI_ERR;
}
+ if (register_android_security_cts_AudioPolicyBinderTest(env)) {
+ return JNI_ERR;
+ }
+
return JNI_VERSION_1_4;
}
diff --git a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
new file mode 100644
index 0000000..9daa2cb
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioPolicyBinderTest-JNI"
+
+#include <jni.h>
+#include <binder/IServiceManager.h>
+#include <media/IAudioPolicyService.h>
+#include <media/AudioSystem.h>
+#include <system/audio.h>
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+
+using namespace android;
+
+/*
+ * Native methods used by
+ * cts/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
+ */
+
+static bool init(sp<IAudioPolicyService>& aps, audio_io_handle_t *output, int *session)
+{
+ aps = 0;
+ if (output != NULL) {
+ *output = 0;
+ }
+ if (session != NULL) {
+ *session = 0;
+ }
+
+ int64_t startTime = 0;
+ sp<IServiceManager> sm = defaultServiceManager();
+ while (aps == 0) {
+ sp<IBinder> binder = defaultServiceManager()->checkService(String16("media.audio_policy"));
+ if (binder == 0) {
+ if (startTime == 0) {
+ startTime = uptimeMillis();
+ } else if ((uptimeMillis()-startTime) > 10000) {
+ ALOGE("timeout while getting audio policy service");
+ return false;
+ }
+ sleep(1);
+ } else {
+ aps = interface_cast<IAudioPolicyService>(binder);
+ }
+ }
+
+ if (output != NULL) {
+ // get a valid output. Any use case will do.
+ for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
+ *output = AudioSystem::getOutput((audio_stream_type_t)stream);
+ if (*output != 0) {
+ break;
+ }
+ }
+ if (*output == 0) {
+ ALOGE("cannot get valid audio output");
+ return false;
+ }
+ }
+ if (session != NULL) {
+ *session = 10000;
+ }
+ return true;
+}
+
+/*
+ * Checks that IAudioPolicyService::startOutput() cannot be called with an
+ * invalid stream type.
+ */
+jboolean android_security_cts_AudioPolicy_test_startOutput(JNIEnv* env __unused,
+ jobject thiz __unused)
+{
+ sp<IAudioPolicyService> aps;
+ audio_io_handle_t output;
+ int session;
+
+ if (!init(aps, &output, &session)) {
+ return false;
+ }
+
+ status_t status = aps->startOutput(output, (audio_stream_type_t)(-1), session);
+ if (status == NO_ERROR) {
+ return false;
+ }
+ status = aps->startOutput(output, (audio_stream_type_t)AUDIO_STREAM_CNT, session);
+ if (status == NO_ERROR) {
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Checks that IAudioPolicyService::stopOutput() cannot be called with an
+ * invalid stream type.
+ */
+jboolean android_security_cts_AudioPolicy_test_stopOutput(JNIEnv* env __unused,
+ jobject thiz __unused)
+{
+ sp<IAudioPolicyService> aps;
+ audio_io_handle_t output;
+ int session;
+
+ if (!init(aps, &output, &session)) {
+ return false;
+ }
+
+ status_t status = aps->stopOutput(output, (audio_stream_type_t)(-1), session);
+ if (status == NO_ERROR) {
+ return false;
+ }
+ status = aps->stopOutput(output, (audio_stream_type_t)AUDIO_STREAM_CNT, session);
+ if (status == NO_ERROR) {
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Checks that IAudioPolicyService::isStreamActive() cannot be called with an
+ * invalid stream type.
+ */
+jboolean android_security_cts_AudioPolicy_test_isStreamActive(JNIEnv* env __unused,
+ jobject thiz __unused)
+{
+ sp<IAudioPolicyService> aps;
+
+ if (!init(aps, NULL, NULL)) {
+ return false;
+ }
+
+ status_t status = aps->isStreamActive((audio_stream_type_t)(-1), 0);
+ if (status == NO_ERROR) {
+ return false;
+ }
+ status = aps->isStreamActive((audio_stream_type_t)AUDIO_STREAM_CNT, 0);
+ if (status == NO_ERROR) {
+ return false;
+ }
+ return true;
+}
+
+static JNINativeMethod gMethods[] = {
+ { "native_test_startOutput", "()Z",
+ (void *) android_security_cts_AudioPolicy_test_startOutput },
+ { "native_test_stopOutput", "()Z",
+ (void *) android_security_cts_AudioPolicy_test_stopOutput },
+ { "native_test_isStreamActive", "()Z",
+ (void *) android_security_cts_AudioPolicy_test_isStreamActive },
+};
+
+int register_android_security_cts_AudioPolicyBinderTest(JNIEnv* env)
+{
+ jclass clazz = env->FindClass("android/security/cts/AudioPolicyBinderTest");
+ return env->RegisterNatives(clazz, gMethods,
+ sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java b/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
new file mode 100644
index 0000000..399d8bb
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import junit.framework.TestCase;
+
+public class AudioPolicyBinderTest extends TestCase {
+
+ static {
+ System.loadLibrary("ctssecurity_jni");
+ }
+
+ /**
+ * Checks that IAudioPolicyService::startOutput() cannot be called with an
+ * invalid stream type.
+ */
+ public void test_startOutput() throws Exception {
+ assertTrue(native_test_startOutput());
+ }
+
+ /**
+ * Checks that IAudioPolicyService::stopOutput() cannot be called with an
+ * invalid stream type.
+ */
+ public void test_stopOutput() throws Exception {
+ assertTrue(native_test_stopOutput());
+ }
+
+ /**
+ * Checks that IAudioPolicyService::isStreamActive() cannot be called with an
+ * invalid stream type.
+ */
+ public void test_isStreamActive() throws Exception {
+ assertTrue(native_test_isStreamActive());
+ }
+
+ private static native boolean native_test_startOutput();
+ private static native boolean native_test_stopOutput();
+ private static native boolean native_test_isStreamActive();
+}
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
index 6e30421..f0ee277 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
@@ -44,6 +44,10 @@
public class TvInputServiceTest extends ActivityInstrumentationTestCase2<TvViewStubActivity> {
/** The maximum time to wait for an operation. */
private static final long TIME_OUT = 15000L;
+ private static final String mDummyTrackId = "dummyTrackId";
+ private static final TvTrackInfo mDummyTrack =
+ new TvTrackInfo.Builder(TvTrackInfo.TYPE_SUBTITLE, mDummyTrackId)
+ .setLanguage("und").build();
private TvView mTvView;
private Activity mActivity;
@@ -250,7 +254,9 @@
public void verifyCallbackTracksChanged() {
CountingSession session = CountingTvInputService.sSession;
assertNotNull(session);
- session.notifyTracksChanged(new ArrayList<TvTrackInfo>());
+ ArrayList<TvTrackInfo> tracks = new ArrayList<>();
+ tracks.add(mDummyTrack);
+ session.notifyTracksChanged(tracks);
new PollingCheck(TIME_OUT) {
@Override
protected boolean check() {
@@ -262,7 +268,7 @@
public void verifyCallbackTrackSelected() {
CountingSession session = CountingTvInputService.sSession;
assertNotNull(session);
- session.notifyTrackSelected(TvTrackInfo.TYPE_SUBTITLE, null);
+ session.notifyTrackSelected(mDummyTrack.getType(), mDummyTrack.getId());
new PollingCheck(TIME_OUT) {
@Override
protected boolean check() {
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java b/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
index 8c95194..930dd6a 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
@@ -224,17 +224,24 @@
private void selectTrackAndVerify(final int type, final TvTrackInfo track,
List<TvTrackInfo> tracks) {
+ String selectedTrackId = mTvView.getSelectedTrack(type);
final int previousGeneration = mCallback.getSelectedTrackGeneration(
mStubInfo.getId(), type);
mTvView.selectTrack(type, track == null ? null : track.getId());
- new PollingCheck(TIME_OUT) {
- @Override
- protected boolean check() {
- return mCallback.getSelectedTrackGeneration(
- mStubInfo.getId(), type) > previousGeneration;
- }
- }.run();
- String selectedTrackId = mTvView.getSelectedTrack(type);
+
+ if ((track == null && selectedTrackId != null)
+ || (track != null && !track.getId().equals(selectedTrackId))) {
+ // Check generation change only if we're actually changing track.
+ new PollingCheck(TIME_OUT) {
+ @Override
+ protected boolean check() {
+ return mCallback.getSelectedTrackGeneration(
+ mStubInfo.getId(), type) > previousGeneration;
+ }
+ }.run();
+ }
+
+ selectedTrackId = mTvView.getSelectedTrack(type);
assertEquals(selectedTrackId, track == null ? null : track.getId());
if (selectedTrackId != null) {
TvTrackInfo selectedTrack = null;
diff --git a/tools/tradefed-host/etc/cts-tradefed b/tools/tradefed-host/etc/cts-tradefed
index f9f43bb..9a643de 100755
--- a/tools/tradefed-host/etc/cts-tradefed
+++ b/tools/tradefed-host/etc/cts-tradefed
@@ -35,7 +35,7 @@
checkPath java
# check java version
-JAVA_VERSION=$(java -version 2>&1 | head -n 1 | grep '[ "]1\.[67][\. "$$]')
+JAVA_VERSION=$(java -version 2>&1 | head -n 2 | grep '[ "]1\.[67][\. "$$]')
if [ "${JAVA_VERSION}" == "" ]; then
echo "Wrong java version. 1.6 or 1.7 is required."
exit
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 27f9135..25431b2 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 = "5.0_r0.5";
+ public static final String CTS_BUILD_VERSION = "5.0_r2";
/**
* {@inheritDoc}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java b/tools/tradefed-host/src/com/android/cts/tradefed/command/CtsConsole.java
index 7333de2..ca4e050 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
@@ -80,7 +80,7 @@
public void run() {
CtsBuildHelper ctsBuild = getCtsBuild();
if (ctsBuild != null) {
- listPackages(ctsBuild, AbiUtils.getAbisSupportedByCts());
+ listPackages(ctsBuild);
}
}
}, LIST_PATTERN, "packages");
@@ -193,8 +193,8 @@
}
}
- private void listPackages(CtsBuildHelper ctsBuild, Set<String> abis) {
- ITestPackageRepo testCaseRepo = new TestPackageRepo(ctsBuild.getTestCasesDir(), abis, false);
+ private void listPackages(CtsBuildHelper ctsBuild) {
+ ITestPackageRepo testCaseRepo = new TestPackageRepo(ctsBuild.getTestCasesDir(), false);
for (String packageName : testCaseRepo.getPackageNames()) {
printLine(packageName);
}
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 08e9a0b..8cb4072 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
@@ -27,10 +27,13 @@
import com.android.tradefed.config.Option;
import com.android.tradefed.config.Option.Importance;
import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.ILogSaver;
+import com.android.tradefed.result.ILogSaverListener;
import com.android.tradefed.result.ITestInvocationListener;
import com.android.tradefed.result.ITestSummaryListener;
import com.android.tradefed.result.InputStreamSource;
import com.android.tradefed.result.LogDataType;
+import com.android.tradefed.result.LogFile;
import com.android.tradefed.result.LogFileSaver;
import com.android.tradefed.result.TestSummary;
import com.android.tradefed.util.FileUtil;
@@ -54,7 +57,9 @@
* <p/>
* Outputs xml in format governed by the cts_result.xsd
*/
-public class CtsXmlResultReporter implements ITestInvocationListener, ITestSummaryListener {
+public class CtsXmlResultReporter
+ implements ITestInvocationListener, ITestSummaryListener, ILogSaverListener {
+
private static final String LOG_TAG = "CtsXmlResultReporter";
static final String TEST_RESULT_FILE_NAME = "testResult.xml";
@@ -89,11 +94,15 @@
@Option(name = "result-server", description = "Server to publish test results.")
private String mResultServer;
+ @Option(name = "include-test-log-tags", description = "Include test log tags in XML report.")
+ private boolean mIncludeTestLogTags = false;
+
protected IBuildInfo mBuildInfo;
private String mStartTime;
private String mDeviceSerial;
private TestResults mResults = new TestResults();
private TestPackageResult mCurrentPkgResult = null;
+ private Test mCurrentTest = null;
private boolean mIsDeviceInfoRun = false;
private ResultReporter mReporter;
private File mLogDir;
@@ -104,6 +113,11 @@
mReportDir = reportDir;
}
+ /** Set whether to include TestLog tags in the XML reports. */
+ public void setIncludeTestLogTags(boolean include) {
+ mIncludeTestLogTags = include;
+ }
+
/**
* {@inheritDoc}
*/
@@ -211,6 +225,20 @@
}
/**
+ * {@inheritDoc}
+ */
+ @Override
+ public void testLogSaved(String dataName, LogDataType dataType, InputStreamSource dataStream,
+ LogFile logFile) {
+ if (mIncludeTestLogTags && mCurrentTest != null) {
+ TestLog log = TestLog.fromDataName(dataName, logFile.getUrl());
+ if (log != null) {
+ mCurrentTest.addTestLog(log);
+ }
+ }
+ }
+
+ /**
* Return the {@link LogFileSaver} to use.
* <p/>
* Exposed for unit testing.
@@ -219,6 +247,10 @@
return new LogFileSaver(mLogDir);
}
+ @Override
+ public void setLogSaver(ILogSaver logSaver) {
+ // Don't need to keep a reference to logSaver, because we don't save extra logs in this class.
+ }
@Override
public void testRunStarted(String id, int numTests) {
@@ -235,7 +267,7 @@
@Override
public void testStarted(TestIdentifier test) {
if (!mIsDeviceInfoRun) {
- mCurrentPkgResult.insertTest(test);
+ mCurrentTest = mCurrentPkgResult.insertTest(test);
}
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java
index 713e8fa..3881c0e 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/PlanCreator.java
@@ -116,8 +116,8 @@
public ITestPlan createDerivedPlan(CtsBuildHelper build, Set<String> abis)
throws ConfigurationException {
checkFields(build);
- ITestPackageRepo pkgDefRepo = new TestPackageRepo(build.getTestCasesDir(),
- abis, mIncludeKnownFailures);
+ ITestPackageRepo pkgDefRepo =
+ new TestPackageRepo(build.getTestCasesDir(), mIncludeKnownFailures);
ITestPlan derivedPlan = new TestPlan(mPlanName, abis);
for (TestPackageResult pkg : mResult.getPackages()) {
Collection<TestIdentifier> filteredTests = pkg.getTestsWithStatus(mResultFilter);
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 023cfcb..12a2b29 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
@@ -16,12 +16,15 @@
package com.android.cts.tradefed.result;
import com.android.ddmlib.Log;
+import com.android.cts.tradefed.result.TestLog.TestLogType;
import org.kxml2.io.KXmlSerializer;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
/**
* Data structure that represents a "Test" result XML element.
@@ -58,6 +61,12 @@
private String mDetails;
/**
+ * Log info for this test like a logcat dump or bugreport.
+ * Use *Locked methods instead of mutating this directly.
+ */
+ private List<TestLog> mTestLogs;
+
+ /**
* Create an empty {@link Test}
*/
public Test() {
@@ -76,6 +85,13 @@
}
/**
+ * Add a test log to this Test.
+ */
+ public void addTestLog(TestLog testLog) {
+ addTestLogLocked(testLog);
+ }
+
+ /**
* Set the name of this {@link Test}
*/
public void setName(String name) {
@@ -157,6 +173,8 @@
serializer.attribute(CtsXmlResultReporter.ns, STARTTIME_ATTR, mStartTime);
serializer.attribute(CtsXmlResultReporter.ns, ENDTIME_ATTR, mEndTime);
+ serializeTestLogsLocked(serializer);
+
if (mMessage != null) {
serializer.startTag(CtsXmlResultReporter.ns, SCENE_TAG);
serializer.attribute(CtsXmlResultReporter.ns, MESSAGE_ATTR, mMessage);
@@ -328,10 +346,38 @@
mMessage = getAttribute(parser, MESSAGE_ATTR);
} else if (eventType == XmlPullParser.START_TAG && parser.getName().equals(STACK_TAG)) {
mStackTrace = parser.nextText();
+ } else if (eventType == XmlPullParser.START_TAG && TestLog.isTag(parser.getName())) {
+ parseTestLog(parser);
} else if (eventType == XmlPullParser.END_TAG && parser.getName().equals(TAG)) {
return;
}
eventType = parser.next();
}
}
+
+ /** Parse a TestLog entry from the parser positioned at a TestLog tag. */
+ private void parseTestLog(XmlPullParser parser) throws XmlPullParserException{
+ TestLog log = TestLog.fromXml(parser);
+ if (log == null) {
+ throw new XmlPullParserException("invalid XML: bad test log tag");
+ }
+ addTestLog(log);
+ }
+
+ /** Add a TestLog to the test in a thread safe manner. */
+ private synchronized void addTestLogLocked(TestLog testLog) {
+ if (mTestLogs == null) {
+ mTestLogs = new ArrayList<>(TestLogType.values().length);
+ }
+ mTestLogs.add(testLog);
+ }
+
+ /** Serialize the TestLogs of this test in a thread safe manner. */
+ private synchronized void serializeTestLogsLocked(KXmlSerializer serializer) throws IOException {
+ if (mTestLogs != null) {
+ for (TestLog log : mTestLogs) {
+ log.serialize(serializer);
+ }
+ }
+ }
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/result/TestLog.java b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestLog.java
new file mode 100644
index 0000000..1210432
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/result/TestLog.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.tradefed.result;
+
+import org.kxml2.io.KXmlSerializer;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.io.IOException;
+
+import javax.annotation.Nullable;
+
+/**
+ * TestLog describes a log for a test. It corresponds to the "TestLog" XML element.
+ */
+class TestLog {
+
+ private static final String TAG = "TestLog";
+ private static final String TYPE_ATTR = "type";
+ private static final String URL_ATTR = "url";
+
+ /** Type of log. */
+ public enum TestLogType {
+ LOGCAT("logcat-"),
+ BUGREPORT("bug-"),
+
+ ;
+
+ // This enum restricts the type of logs reported back to the server,
+ // because we do not intend to support them all. Using an enum somewhat
+ // assures that we will only see these expected types on the server side.
+
+ /**
+ * Returns the TestLogType from an ILogSaver data name or null
+ * if the data name is not supported.
+ */
+ @Nullable
+ static TestLogType fromDataName(String dataName) {
+ if (dataName == null) {
+ return null;
+ }
+
+ for (TestLogType type : values()) {
+ if (dataName.startsWith(type.dataNamePrefix)) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ private final String dataNamePrefix;
+
+ private TestLogType(String dataNamePrefix) {
+ this.dataNamePrefix = dataNamePrefix;
+ }
+
+ String getAttrValue() {
+ return name().toLowerCase();
+ }
+ }
+
+ /** Type of the log like LOGCAT or BUGREPORT. */
+ private final TestLogType mLogType;
+
+ /** Url pointing to the log file. */
+ private final String mUrl;
+
+ /** Create a TestLog from an ILogSaver callback. */
+ @Nullable
+ static TestLog fromDataName(String dataName, String url) {
+ TestLogType logType = TestLogType.fromDataName(dataName);
+ if (logType == null) {
+ return null;
+ }
+
+ if (url == null) {
+ return null;
+ }
+
+ return new TestLog(logType, url);
+ }
+
+ /** Create a TestLog from XML given a XmlPullParser positioned at the TestLog tag. */
+ @Nullable
+ static TestLog fromXml(XmlPullParser parser) {
+ String type = parser.getAttributeValue(null, TYPE_ATTR);
+ if (type == null) {
+ return null;
+ }
+
+ String url = parser.getAttributeValue(null, URL_ATTR);
+ if (url == null) {
+ return null;
+ }
+
+ try {
+ TestLogType logType = TestLogType.valueOf(type.toUpperCase());
+ return new TestLog(logType, url);
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ /** Create a TestLog directly given a log type and url. */
+ public static TestLog of(TestLogType logType, String url) {
+ return new TestLog(logType, url);
+ }
+
+ private TestLog(TestLogType logType, String url) {
+ this.mLogType = logType;
+ this.mUrl = url;
+ }
+
+ /** Returns this TestLog's log type. */
+ TestLogType getLogType() {
+ return mLogType;
+ }
+
+ /** Returns this TestLog's URL. */
+ String getUrl() {
+ return mUrl;
+ }
+
+ /** Serialize the TestLog to XML. */
+ public void serialize(KXmlSerializer serializer) throws IOException {
+ serializer.startTag(CtsXmlResultReporter.ns, TAG);
+ serializer.attribute(CtsXmlResultReporter.ns, TYPE_ATTR, mLogType.getAttrValue());
+ serializer.attribute(CtsXmlResultReporter.ns, URL_ATTR, mUrl);
+ serializer.endTag(CtsXmlResultReporter.ns, TAG);
+ }
+
+ /** Returns true if the tag is a TestLog tag. */
+ public static boolean isTag(String tagName) {
+ return TAG.equals(tagName);
+ }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index a16e1c4..ce48664 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -57,13 +57,13 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Queue;
import java.util.Set;
@@ -87,8 +87,6 @@
public static final String PACKAGE_ABI_METRIC = "packageAbi";
public static final String PACKAGE_DIGEST_METRIC = "packageDigest";
- private ITestDevice mDevice;
-
@Option(name = PLAN_OPTION, description = "the test plan to run.",
importance = Importance.IF_UNSET)
private String mPlanName = null;
@@ -182,19 +180,34 @@
"Collect dEQP logs from the device.")
private boolean mCollectDeqpLogs = false;
- private long mPrevRebootTime; // last reboot time
+ @Option(name = "min-pre-reboot-package-count", description =
+ "The minimum number of packages to require a pre test reboot")
+
+ private int mMinPreRebootPackageCount = 2;
+ private final int mShardAssignment;
+ private final int mTotalShards;
+ private ITestDevice mDevice = null;
+ private CtsBuildHelper mCtsBuild = null;
+ private IBuildInfo mBuildInfo = null;
+ // last reboot time
+ private long mPrevRebootTime;
+ // The list of packages to run. populated in {@code setupTestPackageList}
+ // This is a member variable so that run can be called more than once
+ // and the test run is resumed.
+ private List<TestPackage> mTestPackageList = new ArrayList<>();
+ // The index in the pacakge list of the last test to complete
+ private int mLastTestPackageIndex = 0;
/** data structure for a {@link IRemoteTest} and its known tests */
- class TestPackage {
+ static class TestPackage {
private final IRemoteTest mTestForPackage;
private final ITestPackageDef mPackageDef;
private final Collection<TestIdentifier> mKnownTests;
- TestPackage(ITestPackageDef packageDef, IRemoteTest testForPackage,
- Collection<TestIdentifier> knownTests) {
+ TestPackage(ITestPackageDef packageDef, IRemoteTest testForPackage) {
mPackageDef = packageDef;
mTestForPackage = testForPackage;
- mKnownTests = knownTests;
+ mKnownTests = packageDef.getTests();
}
IRemoteTest getTestForPackage() {
@@ -301,11 +314,28 @@
}
}
- /** list of remaining tests to execute */
- private List<TestPackage> mRemainingTestPkgs = null;
+ /**
+ * Create a new {@link CtsTest} that will run the default list of {@link TestPackage}s.
+ */
+ public CtsTest() {
+ this(0 /*shardAssignment*/, 1 /*totalShards*/);
+ }
- private CtsBuildHelper mCtsBuild = null;
- private IBuildInfo mBuildInfo = null;
+ /**
+ * Create a new {@link CtsTest} that will run the given {@link List} of {@link TestPackage}s.
+ */
+ public CtsTest(int shardAssignment, int totalShards) {
+ if (shardAssignment < 0) {
+ throw new IllegalArgumentException(
+ "shardAssignment cannot be negative. found:" + shardAssignment);
+ }
+ if (totalShards < 1) {
+ throw new IllegalArgumentException(
+ "shardAssignment must be at least 1. found:" + totalShards);
+ }
+ this.mShardAssignment = shardAssignment;
+ this.mTotalShards = totalShards;
+ }
/**
* {@inheritDoc}
@@ -416,8 +446,6 @@
* Set the CTS build container.
* <p/>
* Exposed so unit tests can mock the provided build.
- *
- * @param buildHelper
*/
void setBuildHelper(CtsBuildHelper buildHelper) {
mCtsBuild = buildHelper;
@@ -432,57 +460,62 @@
throw new IllegalArgumentException("missing device");
}
- if (mRemainingTestPkgs == null) {
- checkFields();
- mRemainingTestPkgs = buildTestsToRun();
- }
- if (mBugreport) {
- FailedTestBugreportGenerator bugListener = new FailedTestBugreportGenerator(listener,
- getDevice());
- listener = bugListener;
- }
- if (mScreenshotOnFailures) {
- FailedTestScreenshotGenerator screenListener = new FailedTestScreenshotGenerator(
- listener, getDevice());
- listener = screenListener;
- }
- if (mLogcatOnFailures) {
- FailedTestLogcatGenerator logcatListener = new FailedTestLogcatGenerator(
- listener, getDevice(), mMaxLogcatBytes);
- listener = logcatListener;
- }
-
- // Only run test packages on ABIs which this device supports.
- Set<String> abis = getAbis();
- if (abis == null || abis.isEmpty()) {
+ Set<String> abiSet = getAbis();
+ if (abiSet == null || abiSet.isEmpty()) {
throw new IllegalArgumentException("could not get device's ABIs");
}
- List<TestPackage> packages = filterTestPackagesByAbi(mRemainingTestPkgs, abis);
+ Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "ABIs: " + abiSet);
+
+ checkFields();
+ setupTestPackageList(abiSet);
+ if (mBugreport) {
+ listener = new FailedTestBugreportGenerator(listener, getDevice());
+ }
+ if (mScreenshotOnFailures) {
+ listener = new FailedTestScreenshotGenerator(listener, getDevice());
+ }
+ if (mLogcatOnFailures) {
+ listener = new FailedTestLogcatGenerator(listener, getDevice(), mMaxLogcatBytes);
+ }
+
+ // Setup the a map of Test id to ResultFilter
+ Map<String, ResultFilter> filterMap = new HashMap<>();
+ int totalTestCount = 0;
+ for (TestPackage testPackage : mTestPackageList) {
+ ResultFilter resultFilter = new ResultFilter(listener, testPackage);
+ totalTestCount += resultFilter.getKnownTestCount();
+ filterMap.put(testPackage.getPackageDef().getId(), resultFilter);
+ }
// collect and install the prerequisiteApks first, to save time when multiple test
- // packages are using the same prerequisite apk (I'm looking at you, CtsTestStubs!)
- Collection<String> prerequisiteApks = getPrerequisiteApks(packages);
- Collection<String> uninstallPackages = getPrerequisitePackageNames(packages);
- List<ResultFilter> filters = new ArrayList<ResultFilter>(packages.size());
+ // packages are using the same prerequisite apk
+ Map<String, Set<String>> prerequisiteApks = getPrerequisiteApks(mTestPackageList, abiSet);
+ Collection<String> uninstallPackages = getPrerequisitePackageNames(mTestPackageList);
try {
- installPrerequisiteApks(prerequisiteApks);
-
// always collect the device info, even for resumed runs, since test will likely be
// running on a different device
collectDeviceInfo(getDevice(), mCtsBuild, listener);
- if (packages.size() > 1 && !mDisableReboot) {
- Log.i(LOG_TAG, "Initial reboot for multiple packages");
- rebootDevice();
- }
+ preRebootIfNecessary(mTestPackageList);
+
mPrevRebootTime = System.currentTimeMillis();
+ int remainingPackageCount = mTestPackageList.size();
+ Log.logAndDisplay(LogLevel.INFO, LOG_TAG,
+ String.format("Start test run of %,d packages, containing %,d tests",
+ remainingPackageCount, totalTestCount));
+ IAbi currentAbi = null;
- while (!packages.isEmpty()) {
- TestPackage knownTests = packages.get(0);
- ResultFilter filter = new ResultFilter(listener, knownTests);
- filters.add(filter);
+ for (int i = mLastTestPackageIndex; i < mTestPackageList.size(); i++) {
+ TestPackage testPackage = mTestPackageList.get(i);
- IRemoteTest test = knownTests.getTestForPackage();
+ if (currentAbi == null ||
+ !currentAbi.getName().equals(testPackage.getAbi().getName())) {
+ currentAbi = testPackage.getAbi();
+ installPrerequisiteApks(
+ prerequisiteApks.get(currentAbi.getName()), currentAbi);
+ }
+
+ IRemoteTest test = testPackage.getTestForPackage();
if (test instanceof IBuildReceiver) {
((IBuildReceiver) test).setBuild(mBuildInfo);
}
@@ -493,15 +526,15 @@
((DeqpTestRunner)test).setCollectLogs(mCollectDeqpLogs);
}
- forwardPackageDetails(knownTests.getPackageDef(), listener);
- test.run(filter);
- packages.remove(0);
- if (packages.size() > 0) {
- rebootIfNecessary(knownTests, packages.get(0));
- // remove artifacts like status bar from the previous test.
- // But this cannot dismiss dialog popped-up.
+ forwardPackageDetails(testPackage.getPackageDef(), listener);
+ test.run(filterMap.get(testPackage.getPackageDef().getId()));
+ if (i < mTestPackageList.size() - 1) {
+ TestPackage nextPackage = mTestPackageList.get(i + 1);
+ rebootIfNecessary(testPackage, nextPackage);
changeToHomeScreen();
}
+ // Track of the last complete test package index for resume
+ mLastTestPackageIndex = i;
}
if (mScreenshot) {
@@ -522,26 +555,52 @@
CLog.e(e);
throw e;
} finally {
- for (ResultFilter filter : filters) {
+ for (ResultFilter filter : filterMap.values()) {
filter.reportUnexecutedTests();
}
}
}
/**
- * @param packages The package list to filter
- * @param abis The ABIs to test on
- * @return A list of {@link TestPackage} which test one of the given ABIs
+ * @param allTestPackageDefList The package list to filter
+ * @param deviceAbiSet The ABIs supported by the device being tested
+ * @return A {@link List} of {@link ITestPackageDef}s that should be tested
*/
- private static List<TestPackage> filterTestPackagesByAbi(
- List<TestPackage> packages, Set<String> abis){
- List<TestPackage> testPackages = new LinkedList<>();
- for (TestPackage test : packages) {
- if (abis.contains(test.getAbi().getName())) {
- testPackages.add(test);
+ private static List<ITestPackageDef> filterByAbi(
+ List<ITestPackageDef> allTestPackageDefList, Set<String> deviceAbiSet) {
+ List<ITestPackageDef> filteredTestPackageDefList = new LinkedList<>();
+ for (ITestPackageDef testPackageDef : allTestPackageDefList) {
+ if (deviceAbiSet.contains(testPackageDef.getAbi().getName())) {
+ // We only need test packages that are not empty and of matching ABIs
+ filteredTestPackageDefList.add(testPackageDef);
}
}
- return testPackages;
+ return filteredTestPackageDefList;
+ }
+
+ /** Reboot then the device iff the list of packages exceeds the minimum */
+ private void preRebootIfNecessary(List<TestPackage> testPackageList)
+ throws DeviceNotAvailableException {
+ if (mDisableReboot) {
+ return;
+ }
+
+ Set<String> packageNameSet = new HashSet<>();
+ for (TestPackage testPackage : testPackageList) {
+ // Parse the package name
+ packageNameSet.add(AbiUtils.parseTestName(testPackage.getPackageDef().getId()));
+ }
+ if (packageNameSet.size() < mMinPreRebootPackageCount) {
+ // There is actually only one unique package name. No need to reboot.
+ return;
+ }
+
+ // Reboot is needed
+ Log.logAndDisplay(LogLevel.INFO, LOG_TAG,
+ String.format("Pre-test reboot (%,d packages). Use --disable-reboot to skip",
+ packageNameSet.size()));
+
+ rebootDevice();
}
private void rebootIfNecessary(TestPackage testFinished, TestPackage testToRun)
@@ -598,6 +657,10 @@
}
}
+ /**
+ * Remove artifacts like status bar from the previous test.
+ * But this cannot dismiss dialog popped-up.
+ */
private void changeToHomeScreen() throws DeviceNotAvailableException {
final String homeCmd = "input keyevent 3";
@@ -608,84 +671,94 @@
//ignore
}
}
+
/**
- * Build the list of test packages to run
+ * Set {@code mTestPackageList} to the list of test packages to run filtered by ABI.
*/
- private List<TestPackage> buildTestsToRun() {
- List<TestPackage> testPkgList = new LinkedList<TestPackage>();
+ private void setupTestPackageList(Set<String> abis) throws DeviceNotAvailableException {
+ if (!mTestPackageList.isEmpty()) {
+ Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Resume tests using existing package list");
+ return;
+ }
try {
+ // Collect ALL tests
ITestPackageRepo testRepo = createTestCaseRepo();
- Collection<ITestPackageDef> testPkgDefs = getTestPackagesToRun(testRepo);
- for (ITestPackageDef testPkgDef : testPkgDefs) {
- addTestPackage(testPkgList, testPkgDef);
+ List<ITestPackageDef> testPkgDefs = new ArrayList<>(getAvailableTestPackages(testRepo));
+ testPkgDefs = filterByAbi(testPkgDefs, abis);
+ // Note: run() relies on the fact that the list is reliably sorted for sharding purposes
+ Collections.sort(testPkgDefs);
+ // Create test package list.
+ List<TestPackage> testPackageList = new ArrayList<>();
+ for (ITestPackageDef testPackageDef : testPkgDefs) {
+ // Note: createTest filters the test list inside of testPackageDef by exclusion list
+ IRemoteTest testForPackage = testPackageDef.createTest(mCtsBuild.getTestCasesDir());
+ if (testPackageDef.getTests().size() > 0) {
+ testPackageList.add(new TestPackage(testPackageDef, testForPackage));
+ }
}
- if (testPkgList.isEmpty()) {
- Log.logAndDisplay(LogLevel.WARN, LOG_TAG, "No tests to run");
+
+ // Filter by shard
+ int numTestPackages = testPackageList.size();
+ int totalShards = Math.min(mTotalShards, numTestPackages);
+
+ List<TestPackage> shardTestPackageList = new ArrayList<>();
+ for (int i = mShardAssignment; i < numTestPackages; i += totalShards) {
+ shardTestPackageList.add(testPackageList.get(i));
}
+ mTestPackageList.addAll(shardTestPackageList);
} catch (FileNotFoundException e) {
- throw new IllegalArgumentException("failed to find CTS plan file", e);
+ throw new IllegalArgumentException("failed to find XTS plan file", e);
} catch (ParseException e) {
- throw new IllegalArgumentException("failed to parse CTS plan file", e);
+ throw new IllegalArgumentException("failed to parse XTS plan file", e);
} catch (ConfigurationException e) {
throw new IllegalArgumentException("failed to process arguments", e);
}
- return testPkgList;
}
/**
- * Adds a test package to the list of packages to test
+ * Return the {@link Set} of {@link ITestPackageDef}s to run unfiltered by ABI
*
- * @param testList
- * @param testPkgDef
- */
- private void addTestPackage(List<TestPackage> testList, ITestPackageDef testPkgDef) {
- IRemoteTest testForPackage = testPkgDef.createTest(mCtsBuild.getTestCasesDir());
- if (testForPackage != null) {
- Collection<TestIdentifier> knownTests = testPkgDef.getTests();
- testList.add(new TestPackage(testPkgDef, testForPackage, knownTests));
- }
- }
-
- /**
- * Return the list of test package defs to run
- *
- * @return the list of test package defs to run
+ * @return the {@link Set} of {@link ITestPackageDef}s to run
* @throws ParseException
* @throws FileNotFoundException
* @throws ConfigurationException
*/
- private Collection<ITestPackageDef> getTestPackagesToRun(ITestPackageRepo testRepo)
- throws ParseException, FileNotFoundException, ConfigurationException {
+ private Set<ITestPackageDef> getAvailableTestPackages(ITestPackageRepo testRepo)
+ throws ParseException, FileNotFoundException, ConfigurationException {
// use LinkedHashSet to have predictable iteration order
- Set<ITestPackageDef> testPkgDefs = new LinkedHashSet<ITestPackageDef>();
+ Set<ITestPackageDef> testPkgDefs = new LinkedHashSet<>();
if (mPlanName != null) {
Log.i(LOG_TAG, String.format("Executing CTS test plan %s", mPlanName));
File ctsPlanFile = mCtsBuild.getTestPlanFile(mPlanName);
ITestPlan plan = createPlan(mPlanName);
plan.parse(createXmlStream(ctsPlanFile));
- for (String id : plan.getTestIds()) {
- if (!mExcludedPackageNames.contains(AbiUtils.parseId(id)[1])) {
- ITestPackageDef testPackageDef = testRepo.getTestPackage(id);
- if (testPackageDef != null) {
- testPackageDef.setTestFilter(plan.getTestFilter(id));
- testPkgDefs.add(testPackageDef);
- } else {
- CLog.e("Could not find test package id %s referenced in plan %s", id,
- mPlanName);
- }
+
+ for (String testId : plan.getTestIds()) {
+ if (mExcludedPackageNames.contains(AbiUtils.parseTestName(testId))) {
+ continue;
}
+ ITestPackageDef testPackageDef = testRepo.getTestPackage(testId);
+ if (testPackageDef == null) {
+ CLog.e("Could not find test id %s referenced in plan %s", testId, mPlanName);
+ continue;
+ }
+
+ testPackageDef.setTestFilter(plan.getTestFilter(testId));
+ testPkgDefs.add(testPackageDef);
}
} else if (mPackageNames.size() > 0){
- Log.i(LOG_TAG, String.format("Executing CTS test packages %s", mPackageNames));
+ Log.i(LOG_TAG, String.format("Executing XTS test packages %s", mPackageNames));
+
+ Map<String, List<ITestPackageDef>> testPackageDefMap =
+ testRepo.getTestPackageDefsByName();
+
for (String name : mPackageNames) {
- Set<ITestPackageDef> testPackages = testRepo.getTestPackages(name);
- if (!testPackages.isEmpty()) {
- testPkgDefs.addAll(testPackages);
- } else {
+ if (!testPackageDefMap.containsKey(name)) {
throw new IllegalArgumentException(String.format(
"Could not find test package %s. " +
- "Use 'list packages' to see available packages." , name));
+ "Use 'list packages' to see available packages.", name));
}
+ testPkgDefs.addAll(testPackageDefMap.get(name));
}
} else if (mClassName != null) {
Log.i(LOG_TAG, String.format("Executing CTS test class %s", mClassName));
@@ -708,14 +781,18 @@
PlanCreator planCreator = new PlanCreator(uniquePlanName, mContinueSessionId,
CtsTestStatus.NOT_EXECUTED);
ITestPlan plan = createPlan(planCreator);
- for (String id : plan.getTestIds()) {
- if (!mExcludedPackageNames.contains(AbiUtils.parseId(id)[1])) {
- ITestPackageDef testPackageDef = testRepo.getTestPackage(id);
- if (testPackageDef != null) {
- testPackageDef.setTestFilter(plan.getTestFilter(id));
- testPkgDefs.add(testPackageDef);
- }
+ for (String testId : plan.getTestIds()) {
+ if (mExcludedPackageNames.contains(AbiUtils.parseTestName(testId))) {
+ continue;
}
+ ITestPackageDef testPackageDef = testRepo.getTestPackage(testId);
+ if (testPackageDef == null) {
+ CLog.e("Could not find test id %s referenced in plan %s", testId, mPlanName);
+ continue;
+ }
+
+ testPackageDef.setTestFilter(plan.getTestFilter(testId));
+ testPkgDefs.add(testPackageDef);
}
} else {
// should never get here - was checkFields() not called?
@@ -726,10 +803,11 @@
/**
* Return the list of unique prerequisite Android package names
- * @param testPackages
+ *
+ * @param testPackages The {@link TestPackage}s that contain prerequisites
*/
private Collection<String> getPrerequisitePackageNames(List<TestPackage> testPackages) {
- Set<String> pkgNames = new HashSet<String>();
+ Set<String> pkgNames = new HashSet<>();
for (TestPackage testPkg : testPackages) {
String pkgName = testPkg.mPackageDef.getTargetPackageName();
if (pkgName != null) {
@@ -740,12 +818,12 @@
}
/**
- * @return a {@link Set} containing {@ITestPackageDef}s pertaining to the given
+ * @return a {@link Set} containing {@link ITestPackageDef}s pertaining to the given
* {@code className} and {@code methodName}.
*/
private static Set<ITestPackageDef> buildTestPackageDefSet(
ITestPackageRepo testRepo, String className, String methodName) {
- Set<ITestPackageDef> testPkgDefs = new LinkedHashSet<ITestPackageDef>();
+ Set<ITestPackageDef> testPkgDefs = new LinkedHashSet<>();
// try to find packages to run from class name
List<String> packageIds = testRepo.findPackageIdsForTest(className);
if (packageIds.isEmpty()) {
@@ -763,18 +841,33 @@
}
/**
- * Return the list of unique prerequisite apks to install
- * @param testPackages
+ * Return the list (by abi) of unique prerequisite apks to install
+ *
+ * @param testPackages The {@link List} of {@link TestPackage} that contain prerequisite APKs
*/
- private Collection<String> getPrerequisiteApks(List<TestPackage> testPackages) {
- Set<String> apkNames = new HashSet<String>();
+ private Map<String, Set<String>> getPrerequisiteApks(
+ List<TestPackage> testPackages, Set<String> abiSet) {
+ Map<String, Set<String>> abiToApkMap = new HashMap<>();
for (TestPackage testPkg : testPackages) {
- String apkName = testPkg.mPackageDef.getTargetApkName();
- if (apkName != null) {
- apkNames.add(apkName);
+ if (testPkg.getKnownTests().size() == 0) {
+ // No tests, no point in installing pre-reqs
+ continue;
}
+ String apkName = testPkg.mPackageDef.getTargetApkName();
+ if (apkName == null) {
+ continue;
+ }
+ String abiName = testPkg.getAbi().getName();
+ if (!abiSet.contains(abiName)) {
+ continue;
+ }
+
+ if (!abiToApkMap.containsKey(abiName)) {
+ abiToApkMap.put(abiName, new HashSet<String>());
+ }
+ abiToApkMap.get(abiName).add(apkName);
}
- return apkNames;
+ return abiToApkMap;
}
/**
@@ -783,31 +876,22 @@
*
* Install the collection of test apk file names
*
- * @param prerequisiteApks
+ * @param prerequisiteApks The APKs that must be installed
* @throws DeviceNotAvailableException
*/
- private void installPrerequisiteApks(Collection<String> prerequisiteApks)
+ private void installPrerequisiteApks(Collection<String> prerequisiteApks, IAbi abi)
throws DeviceNotAvailableException {
+ if (prerequisiteApks == null) {
+ return;
+ }
Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Installing prerequisites");
- Set<String> supportedAbiSet = getAbis();
for (String apkName : prerequisiteApks) {
try {
File apkFile = mCtsBuild.getTestApp(apkName);
- // As a workaround for multi arch support, try to install the APK
- // for all device supported ABIs. This will generate warning messages
- // until the above FIXME is resolved.
- int installFailCount = 0;
- for (String abi : supportedAbiSet) {
- String[] options = {AbiUtils.createAbiFlag(abi)};
- String errorCode = getDevice().installPackage(apkFile, true, options);
- if (errorCode != null) {
- installFailCount++;
- CLog.w("Failed to install %s. Reason: %s", apkName, errorCode);
- }
-
- }
- if (installFailCount >= supportedAbiSet.size()) {
- CLog.e("Failed to install %s. See warning messages.", apkName);
+ String[] options = {AbiUtils.createAbiFlag(abi.getName())};
+ String errorCode = getDevice().installPackage(apkFile, true, options);
+ if (errorCode != null) {
+ CLog.e("Failed to install %s. Reason: %s", apkName, errorCode);
}
} catch (FileNotFoundException e) {
CLog.e("Could not find test apk %s", apkName);
@@ -818,7 +902,7 @@
/**
* Uninstalls the collection of android package names from device.
*
- * @param uninstallPackages
+ * @param uninstallPackages The packages that must be uninstalled
*/
private void uninstallPrequisiteApks(Collection<String> uninstallPackages)
throws DeviceNotAvailableException {
@@ -836,29 +920,17 @@
return null;
}
checkFields();
- List<TestPackage> allTests = buildTestsToRun();
- if (allTests == null || allTests.size() <= 1) {
- Log.w(LOG_TAG, "no tests to shard!");
- return null;
+ List<IRemoteTest> shardQueue = new LinkedList<>();
+ for (int shardAssignment = 0; shardAssignment < mShards; shardAssignment++) {
+ CtsTest ctsTest = new CtsTest(shardAssignment, mShards /* totalShards */);
+ OptionCopier.copyOptionsNoThrow(this, ctsTest);
+ // Set the shard count because the copy option on the previous line copies
+ // over the mShard value
+ ctsTest.mShards = 0;
+ shardQueue.add(ctsTest);
}
- // treat shardQueue as a circular queue, to sequentially distribute tests among shards
- Queue<IRemoteTest> shardQueue = new LinkedList<IRemoteTest>();
- // don't create more shards than the number of tests we have!
- for (int i = 0; i < mShards && i < allTests.size(); i++) {
- CtsTest shard = new CtsTest();
- OptionCopier.copyOptionsNoThrow(this, shard);
- shard.mShards = 0;
- shard.mRemainingTestPkgs = new LinkedList<TestPackage>();
- shardQueue.add(shard);
- }
- while (!allTests.isEmpty()) {
- TestPackage testPair = allTests.remove(0);
- CtsTest shard = (CtsTest)shardQueue.poll();
- shard.mRemainingTestPkgs.add(testPair);
- shardQueue.add(shard);
- }
return shardQueue;
}
@@ -884,8 +956,7 @@
* Exposed for unit testing
*/
ITestPackageRepo createTestCaseRepo() {
- return new TestPackageRepo(mCtsBuild.getTestCasesDir(), AbiUtils.getAbisSupportedByCts(),
- mIncludeKnownFailures);
+ return new TestPackageRepo(mCtsBuild.getTestCasesDir(), mIncludeKnownFailures);
}
/**
@@ -906,13 +977,12 @@
*/
Set<String> getAbis() throws DeviceNotAvailableException {
String bitness = (mForceAbi == null) ? "" : mForceAbi;
- Set<String> abis = new HashSet<String>();
+ Set<String> abis = new HashSet<>();
for (String abi : AbiFormatter.getSupportedAbis(mDevice, bitness)) {
if (AbiUtils.isAbiSupportedByCts(abi)) {
abis.add(abi);
}
}
- Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "ABIs: " + abis);
return abis;
}
@@ -964,7 +1034,7 @@
* @return <code>true</code> if one and only one of <var>args</code> is <code>true</code>.
* Otherwise return <code>false</code>.
*/
- private boolean xor(boolean... args) {
+ private static boolean xor(boolean... args) {
boolean currentVal = args[0];
for (int i=1; i < args.length; i++) {
if (currentVal && args[i]) {
@@ -978,10 +1048,10 @@
/**
* Forward the digest and package name to the listener as a metric
*
- * @param listener
+ * @param listener Handles test results
*/
- private void forwardPackageDetails(ITestPackageDef def, ITestInvocationListener listener) {
- Map<String, String> metrics = new HashMap<String, String>(3);
+ private static void forwardPackageDetails(ITestPackageDef def, ITestInvocationListener listener) {
+ Map<String, String> metrics = new HashMap<>(3);
metrics.put(PACKAGE_NAME_METRIC, def.getName());
metrics.put(PACKAGE_ABI_METRIC, def.getAbi().getName());
metrics.put(PACKAGE_DIGEST_METRIC, def.getDigest());
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
index ea01535..8a5c822 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
@@ -28,7 +28,7 @@
* <p/>
* Knows how to translate this info into a runnable {@link IRemoteTest}.
*/
-public interface ITestPackageDef {
+public interface ITestPackageDef extends Comparable<ITestPackageDef> {
/**
* Get the id of the test package.
@@ -37,12 +37,6 @@
public String getId();
/**
- * Get the appPackageName of the test package.
- * @return the {@link String} appPackageName
- */
- public String getAppPackageName();
-
- /**
* Creates a runnable {@link IRemoteTest} from info stored in this definition.
*
* @param testCaseDir {@link File} representing directory of test case data
@@ -52,22 +46,6 @@
public IRemoteTest createTest(File testCaseDir);
/**
- * Determine if given test is defined in this package.
- *
- * @param testDef the {@link TestIdentifier}
- * @return <code>true</code> if test is defined
- */
- public boolean isKnownTest(TestIdentifier testDef);
-
- /**
- * Determine if given test class is defined in this package.
- *
- * @param testClassName the fully qualified test class name
- * @return <code>true</code> if test class is defined
- */
- public boolean isKnownTestClass(String testClassName);
-
- /**
* Get the collection of tests in this test package.
*/
public Collection<TestIdentifier> getTests();
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java
index d1d4111..234f437 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageRepo.java
@@ -19,7 +19,7 @@
import com.android.cts.util.AbiUtils;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
/**
* Interface for accessing tests from the CTS repository.
@@ -36,12 +36,19 @@
public ITestPackageDef getTestPackage(String id);
/**
- * Get a {@link Set} of {@link TestPackageDef} given a name
- *
- * @param name the string package name
- * @return a {@link Set} of {@link TestPackageDef}
+ * @return a sorted {@link List} of all package ids found in repo.
*/
- public Set<ITestPackageDef> getTestPackages(String name);
+ public List<String> getPackageIds();
+
+ /**
+ * @return a sorted {@link List} of test package names
+ */
+ public List<String> getPackageNames();
+
+ /**
+ * @return A {@link Map} of test package name to a {@link List} of {@link ITestPackageDef}s.
+ */
+ public Map<String, List<ITestPackageDef>> getTestPackageDefsByName();
/**
* Attempt to find the package ids for a given test class name
@@ -50,15 +57,4 @@
* @return a {@link List} of package ids.
*/
public List<String> findPackageIdsForTest(String testClassName);
-
- /**
- * @return a sorted {@link List} of all package ids found in repo.
- */
- public List<String> getPackageIds();
-
- /**
- * @return a sorted {@link List} of all package names found in repo.
- */
- public List<String> getPackageNames();
-
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPlan.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPlan.java
index 21b2d0a..2d5f4a7 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPlan.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPlan.java
@@ -23,6 +23,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
+import java.util.List;
/**
* Interface for accessing test plan data.
@@ -42,6 +43,11 @@
public Collection<String> getTestIds();
/**
+ * Gets a sorted {@link List} of test names contained in this plan.
+ */
+ public List<String> getTestNames();
+
+ /**
* Gets the {@link TestFilter} that should be used to filter tests from given package.
*/
public TestFilter getTestFilter(String id);
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ResultFilter.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ResultFilter.java
index 7931660..f4f2f5d 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ResultFilter.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ResultFilter.java
@@ -24,9 +24,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -135,4 +133,9 @@
}
super.testRunEnded(0, new HashMap<String, String>());
}
+
+ /** @return the number of known tests */
+ public int getKnownTestCount() {
+ return mKnownTests.size();
+ }
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index 2eccb50..9ef6257 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -112,11 +112,7 @@
mAppPackageName = appPackageName;
}
- /**
- * {@inheritDoc}
- */
- @Override
- public String getAppPackageName() {
+ String getAppPackageName() {
return mAppPackageName;
}
@@ -124,10 +120,6 @@
mRunTimeArgs = runTimeArgs;
}
- String getRunTimeArgs() {
- return mRunTimeArgs;
- }
-
void setAppNameSpace(String appNameSpace) {
mAppNameSpace = appNameSpace;
}
@@ -374,19 +366,7 @@
return mTestFilter.filter(mTests);
}
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isKnownTest(TestIdentifier testDef) {
- return mTests.contains(testDef);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isKnownTestClass(String className) {
+ boolean isKnownTestClass(String className) {
return mTestClasses.contains(className);
}
@@ -471,10 +451,15 @@
* @return The hex encoded string.
*/
private String toHexString(byte[] arr) {
- StringBuffer buf = new StringBuffer(arr.length * 2);
+ StringBuilder buf = new StringBuilder(arr.length * 2);
for (byte b : arr) {
buf.append(String.format("%02x", b & 0xFF));
}
return buf.toString();
}
+
+ @Override
+ public int compareTo(ITestPackageDef testPackageDef) {
+ return getId().compareTo(testPackageDef.getId());
+ }
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java
index c1f168d..aea6613 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageRepo.java
@@ -40,31 +40,21 @@
private static final String LOG_TAG = "TestCaseRepo";
- private final File mTestCaseDir;
-
/** mapping of ABI to a mapping of appPackageName to test definition */
private final Map<String, Map<String, TestPackageDef>> mTestMap;
- /** set of ABIs */
- private final Set<String> mAbis;
private final boolean mIncludeKnownFailures;
/**
* Creates a {@link TestPackageRepo}, initialized from provided repo files
*
* @param testCaseDir directory containing all test case definition xml and build files
- * @param abis Holds the ABIs which the test must be run against. This must be a subset of the
* ABIs supported by the device under test.
* @param includeKnownFailures Whether to run tests which are known to fail.
*/
- public TestPackageRepo(File testCaseDir, Set<String> abis, boolean includeKnownFailures) {
- mTestCaseDir = testCaseDir;
- mTestMap = new HashMap<String, Map<String, TestPackageDef>>();
- mAbis = abis;
- for (String abi : abis) {
- mTestMap.put(abi, new HashMap<String, TestPackageDef>());
- }
+ public TestPackageRepo(File testCaseDir, boolean includeKnownFailures) {
+ mTestMap = new HashMap<>();
mIncludeKnownFailures = includeKnownFailures;
- parse(mTestCaseDir);
+ parse(testCaseDir);
}
/**
@@ -78,25 +68,22 @@
}
private void parseTestFromXml(File xmlFile) {
- TestPackageXmlParser parser = new TestPackageXmlParser(mAbis, mIncludeKnownFailures);
+ TestPackageXmlParser parser = new TestPackageXmlParser(mIncludeKnownFailures);
try {
parser.parse(createStreamFromFile(xmlFile));
Set<TestPackageDef> defs = parser.getTestPackageDefs();
- if (!defs.isEmpty()) {
- for (TestPackageDef def : defs) {
- String name = def.getAppPackageName();
- String abi = def.getAbi().getName();
- if (def.getTests().size() > 0) {
- mTestMap.get(abi).put(name, def);
- } else {
- Log.d(LOG_TAG, String.format("No tests in %s for %s, skipping",
- name, abi));
- }
- }
- } else {
+ if (defs.isEmpty()) {
Log.w(LOG_TAG, String.format("Could not find test package info in xml file %s",
xmlFile.getAbsolutePath()));
}
+ for (TestPackageDef def : defs) {
+ String name = def.getAppPackageName();
+ String abi = def.getAbi().getName();
+ if (!mTestMap.containsKey(abi)) {
+ mTestMap.put(abi, new HashMap<String, TestPackageDef>());
+ }
+ mTestMap.get(abi).put(name, def);
+ }
} catch (FileNotFoundException e) {
Log.e(LOG_TAG, String.format("Could not find test case xml file %s",
xmlFile.getAbsolutePath()));
@@ -113,7 +100,7 @@
* <p/>
* Exposed for unit testing
*
- * @param xmlFile
+ * @param xmlFile The file containing the xml description of the package
* @return stream to read data
*
*/
@@ -150,14 +137,54 @@
* {@inheritDoc}
*/
@Override
- public Set<ITestPackageDef> getTestPackages(String appPackageName) {
- Set<ITestPackageDef> defs = new HashSet<ITestPackageDef>();
- for (String abi : mAbis) {
- if (mTestMap.get(abi).containsKey(appPackageName)) {
- defs.add(mTestMap.get(abi).get(appPackageName));
+ public List<String> getPackageIds() {
+ Set<String> ids = new HashSet<>();
+ for (String abi : mTestMap.keySet()) {
+ Map<String, TestPackageDef> testNameMap = mTestMap.get(abi);
+ for (TestPackageDef testPackageDef : testNameMap.values()) {
+ ids.add(testPackageDef.getId());
}
}
- return defs;
+ List<String> idList = new ArrayList<>(ids);
+ Collections.sort(idList);
+ return idList;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<String> getPackageNames() {
+ Set<String> nameSet = new HashSet<String>();
+ for (String abi : mTestMap.keySet()) {
+ Map<String, TestPackageDef> testNameMap = mTestMap.get(abi);
+ for (TestPackageDef testPackageDef : testNameMap.values()) {
+ nameSet.add(AbiUtils.parseTestName(testPackageDef.getId()));
+ }
+ }
+ List<String> nameList = new ArrayList<>(nameSet);
+ Collections.sort(nameList);
+ return nameList;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map<String, List<ITestPackageDef>> getTestPackageDefsByName() {
+ Map<String, List<ITestPackageDef>> packageDefMap =
+ new HashMap<String, List<ITestPackageDef>>();
+
+ for (String abi : mTestMap.keySet()) {
+ Map<String, TestPackageDef> testNameMap = mTestMap.get(abi);
+ for (String packageName : testNameMap.keySet()) {
+ if (!packageDefMap.containsKey(packageName)) {
+ packageDefMap.put(packageName, new ArrayList<ITestPackageDef>());
+ }
+ packageDefMap.get(packageName).add(testNameMap.get(packageName));
+ }
+ }
+ return packageDefMap;
}
/**
@@ -177,34 +204,4 @@
Collections.sort(idList);
return idList;
}
-
- /**
- * {@inheritDoc}
- */
- @Override
- public List<String> getPackageIds() {
- Set<String> ids = new HashSet<String>();
- for (String abi : mAbis) {
- for (String name : mTestMap.get(abi).keySet()) {
- ids.add(AbiUtils.createId(abi, name));
- }
- }
- List<String> idList = new ArrayList<String>(ids);
- Collections.sort(idList);
- return idList;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public List<String> getPackageNames() {
- Set<String> names = new HashSet<String>();
- for (String abi : mAbis) {
- names.addAll(mTestMap.get(abi).keySet());
- }
- List<String> packageNames = new ArrayList<String>(names);
- Collections.sort(packageNames);
- return packageNames;
- }
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
index 8f4f1b0..baceb8b 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
@@ -40,18 +40,14 @@
private static final String LOG_TAG = "TestPackageXmlParser";
- private final Set<String> mAbis;
private final boolean mIncludeKnownFailures;
private Map<String, TestPackageDef> mPackageDefs = new HashMap<String, TestPackageDef>();
/**
- * @param abis Holds the ABIs which the test must be run against. This must be a subset of the
- * ABIs supported by the device under test.
* @param includeKnownFailures Whether to run tests which are known to fail.
*/
- public TestPackageXmlParser(Set<String> abis, boolean includeKnownFailures) {
- mAbis = abis;
+ public TestPackageXmlParser(boolean includeKnownFailures) {
mIncludeKnownFailures = includeKnownFailures;
}
@@ -88,7 +84,7 @@
final String runTimeArgs = attributes.getValue("runtimeArgs");
final String testType = getTestType(attributes);
- for (String abiName : mAbis) {
+ for (String abiName : AbiUtils.getAbisSupportedByCts()) {
Abi abi = new Abi(abiName, AbiUtils.getBitness(abiName));
TestPackageDef packageDef = new TestPackageDef();
packageDef.setAppPackageName(appPackageName);
@@ -154,13 +150,11 @@
Set<String> abis = new HashSet<String>();
if (abiList == null) {
// If no specification, add all supported abis
- abis.addAll(mAbis);
+ abis.addAll(AbiUtils.getAbisSupportedByCts());
} else {
- for (String abi : abiList.split(", ")) {
- if (mAbis.contains(abi)) {
- // Else only add the abi which are supported
- abis.add(abi);
- }
+ for (String abi : abiList.split(",")) {
+ // Else only add the abi which are supported
+ abis.add(abi.trim());
}
}
for (String abi : abis) {
@@ -206,9 +200,9 @@
}
/**
- * @returns the set of {@link TestPackageDef} containing data parsed from xml
+ * @return the set of {@link TestPackageDef} containing data parsed from xml
*/
public Set<TestPackageDef> getTestPackageDefs() {
- return new HashSet<TestPackageDef>(mPackageDefs.values());
+ return new HashSet<>(mPackageDefs.values());
}
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPlan.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPlan.java
index 8737db6..2419784 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPlan.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPlan.java
@@ -35,6 +35,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeSet;
/**
* Implementation of {@link TestPlan}.
@@ -150,6 +151,18 @@
* {@inheritDoc}
*/
@Override
+ public List<String> getTestNames() {
+ TreeSet<String> testNameSet = new TreeSet<>();
+ for (String id : mIdFilterMap.keySet()) {
+ testNameSet.add(AbiUtils.parseTestName(id));
+ }
+ return new ArrayList<>(testNameSet);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public TestFilter getTestFilter(String id) {
return mIdFilterMap.get(id);
}
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java
index 22dd6d9..ad1430e 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java
@@ -21,6 +21,7 @@
import com.android.cts.tradefed.result.TestResultsTest;
import com.android.cts.tradefed.result.TestSummaryXmlTest;
import com.android.cts.tradefed.result.TestTest;
+import com.android.cts.tradefed.result.TestLogTest;
import com.android.cts.tradefed.testtype.Abi;
import com.android.cts.tradefed.testtype.CtsTestTest;
import com.android.cts.tradefed.testtype.DeqpTestRunnerTest;
@@ -55,6 +56,7 @@
addTestSuite(TestResultsTest.class);
addTestSuite(TestSummaryXmlTest.class);
addTestSuite(TestTest.class);
+ addTestSuite(TestLogTest.class);
// testtype package
addTestSuite(CtsTestTest.class);
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
index b74e26c..ae4a41e 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/CtsXmlResultReporterTest.java
@@ -22,6 +22,8 @@
import com.android.ddmlib.testrunner.TestIdentifier;
import com.android.tradefed.build.IFolderBuildInfo;
import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.LogDataType;
+import com.android.tradefed.result.LogFile;
import com.android.tradefed.result.TestSummary;
import com.android.tradefed.result.XmlResultReporter;
import com.android.tradefed.util.FileUtil;
@@ -162,6 +164,8 @@
mResultReporter.testFailed(testId, trace);
mResultReporter.testEnded(testId, emptyMap);
mResultReporter.testRunEnded(3, emptyMap);
+ mResultReporter.testLogSaved("logcat-foo-bar", LogDataType.TEXT, null,
+ new LogFile("path", "url"));
mResultReporter.invocationEnded(1);
String output = getOutput();
// TODO: consider doing xml based compare
@@ -171,6 +175,37 @@
"<FailedScene message=\"this is a trace more trace\"> " +
"<StackTrace>this is a tracemore traceyet more trace</StackTrace>";
assertTrue(output.contains(failureTag));
+
+ // Check that no TestLog tags were added, because the flag wasn't enabled.
+ final String testLogTag = String.format("<TestLog type=\"logcat\" url=\"url\" />");
+ assertFalse(output, output.contains(testLogTag));
+ }
+
+ /**
+ * Test that flips the include-test-log-tags flag and checks that logs are written to the XML.
+ */
+ public void testIncludeTestLogTags() {
+ Map<String, String> emptyMap = Collections.emptyMap();
+ final TestIdentifier testId = new TestIdentifier("FooTest", "testFoo");
+ final String trace = "this is a trace\nmore trace\nyet more trace";
+
+ // Include TestLogTags in the XML.
+ mResultReporter.setIncludeTestLogTags(true);
+
+ mResultReporter.invocationStarted(mMockBuild);
+ mResultReporter.testRunStarted(AbiUtils.createId(UnitTests.ABI.getName(), "run"), 1);
+ mResultReporter.testStarted(testId);
+ mResultReporter.testFailed(testId, trace);
+ mResultReporter.testEnded(testId, emptyMap);
+ mResultReporter.testRunEnded(3, emptyMap);
+ mResultReporter.testLogSaved("logcat-foo-bar", LogDataType.TEXT, null,
+ new LogFile("path", "url"));
+ mResultReporter.invocationEnded(1);
+
+ // Check for TestLog tags because the flag was enabled via setIncludeTestLogTags.
+ final String output = getOutput();
+ final String testLogTag = String.format("<TestLog type=\"logcat\" url=\"url\" />");
+ assertTrue(output, output.contains(testLogTag));
}
public void testDeviceSetup() {
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/TestLogTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/TestLogTest.java
new file mode 100644
index 0000000..55c3071
--- /dev/null
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/result/TestLogTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.tradefed.result;
+
+import com.android.cts.tradefed.result.TestLog.TestLogType;
+
+import org.kxml2.io.KXmlSerializer;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import junit.framework.TestCase;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+/** Tests for {@link TestLog}. */
+public class TestLogTest extends TestCase {
+
+ public void testTestLogType_fromDataName() {
+ assertNull(TestLogType.fromDataName(null));
+ assertNull(TestLogType.fromDataName(""));
+ assertNull(TestLogType.fromDataName("kmsg-foo_bar_test"));
+
+ assertEquals(TestLogType.LOGCAT,
+ TestLogType.fromDataName("logcat-foo_bar_test"));
+ assertEquals(TestLogType.BUGREPORT,
+ TestLogType.fromDataName("bug-foo_bar_test"));
+ }
+
+ public void testTestLogType_getAttrValue() {
+ assertEquals("logcat", TestLogType.LOGCAT.getAttrValue());
+ assertEquals("bugreport", TestLogType.BUGREPORT.getAttrValue());
+ }
+
+ public void testFromDataName() {
+ TestLog log = TestLog.fromDataName("logcat-baz_test", "http://logs/baz_test");
+ assertEquals(TestLogType.LOGCAT, log.getLogType());
+ assertEquals("http://logs/baz_test", log.getUrl());
+ }
+
+ public void testFromDataName_unrecognizedDataName() {
+ assertNull(TestLog.fromDataName("kmsg-baz_test", null));
+ }
+
+ public void testFromDataName_nullDataName() {
+ assertNull(TestLog.fromDataName(null, "http://logs/baz_test"));
+ }
+
+ public void testFromDataName_nullUrl() {
+ assertNull(TestLog.fromDataName("logcat-bar_test", null));
+ }
+
+ public void testFromDataName_allNull() {
+ assertNull(TestLog.fromDataName(null, null));
+ }
+
+ public void testFromXml() throws Exception {
+ TestLog log = TestLog.fromXml(newXml("<TestLog type=\"logcat\" url=\"http://logs/baz_test\">"));
+ assertEquals(TestLogType.LOGCAT, log.getLogType());
+ assertEquals("http://logs/baz_test", log.getUrl());
+ }
+
+ public void testFromXml_unrecognizedType() throws Exception {
+ assertNull(TestLog.fromXml(newXml("<TestLog type=\"kmsg\" url=\"http://logs/baz_test\">")));
+ }
+
+ public void testFromXml_noTypeAttribute() throws Exception {
+ assertNull(TestLog.fromXml(newXml("<TestLog url=\"http://logs/baz_test\">")));
+ }
+
+ public void testFromXml_noUrlAttribute() throws Exception {
+ assertNull(TestLog.fromXml(newXml("<TestLog type=\"bugreport\">")));
+ }
+
+ public void testFromXml_allNull() throws Exception {
+ assertNull(TestLog.fromXml(newXml("<TestLog>")));
+ }
+
+ public void testSerialize() throws Exception {
+ KXmlSerializer serializer = new KXmlSerializer();
+ StringWriter writer = new StringWriter();
+ serializer.setOutput(writer);
+
+ TestLog log = TestLog.of(TestLogType.LOGCAT, "http://logs/foo/bar");
+ log.serialize(serializer);
+ assertEquals("<TestLog type=\"logcat\" url=\"http://logs/foo/bar\" />", writer.toString());
+ }
+
+ public void testIsTag() {
+ assertTrue(TestLog.isTag("TestLog"));
+ assertFalse(TestLog.isTag("TestResult"));
+ }
+
+ private XmlPullParser newXml(String xml) throws Exception {
+ XmlPullParserFactory factory = org.xmlpull.v1.XmlPullParserFactory.newInstance();
+ XmlPullParser parser = factory.newPullParser();
+ parser.setInput(new StringReader(xml));
+
+ // Move the parser from the START_DOCUMENT stage to the START_TAG of the data.
+ parser.next();
+
+ return parser;
+ }
+}
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java
index 9915309..30e2ba8 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/CtsTestTest.java
@@ -35,8 +35,10 @@
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
/**
@@ -47,11 +49,16 @@
private static final String PLAN_NAME = "CTS";
private static final String PACKAGE_NAME = "test-name";
private static final String ID = AbiUtils.createId(UnitTests.ABI.getName(), PACKAGE_NAME);
+ private static final TestIdentifier TEST_IDENTIFIER =
+ new TestIdentifier("CLASS_NAME", "TEST_NAME");
private static final List<String> NAMES = new ArrayList<>();
private static final List<String> IDS = new ArrayList<>();
+ private static final List<TestIdentifier> TEST_IDENTIFIER_LIST = new ArrayList<>();
+
static {
NAMES.add(PACKAGE_NAME);
IDS.add(ID);
+ TEST_IDENTIFIER_LIST.add(TEST_IDENTIFIER);
}
/** the test fixture under test, with all external dependencies mocked out */
@@ -76,7 +83,7 @@
mMockDevice = EasyMock.createMock(ITestDevice.class);
mMockListener = EasyMock.createNiceMock(ITestInvocationListener.class);
mStubBuildHelper = new StubCtsBuildHelper();
- mMockPackageDefs = new HashSet<ITestPackageDef>();
+ mMockPackageDefs = new HashSet<>();
mMockPackageDef = EasyMock.createMock(ITestPackageDef.class);
mMockPackageDefs.add(mMockPackageDef);
EasyMock.expect(mMockPackageDef.getTargetApkName()).andStubReturn(null);
@@ -110,8 +117,8 @@
// turn off device collection for simplicity
mCtsTest.setSkipDeviceInfo(true);
// only run tests on one ABI
- EasyMock.expect(mMockDevice.getProperty("ro.product.cpu.abilist")).andReturn(
- UnitTests.ABI.getName()).anyTimes();
+ EasyMock.expect(mMockDevice.getProperty("ro.product.cpu.abilist"))
+ .andReturn(UnitTests.ABI.getName()).anyTimes();
}
/**
@@ -119,7 +126,7 @@
*/
@SuppressWarnings("unchecked")
public void testRun_plan() throws DeviceNotAvailableException, ParseException {
- setParsePlanExceptations();
+ setParsePlanExpectations();
setCreateAndRunTestExpectations();
@@ -134,6 +141,12 @@
@SuppressWarnings("unchecked")
public void testRun_package() throws DeviceNotAvailableException {
mCtsTest.addPackageName(PACKAGE_NAME);
+ Map<String, List<ITestPackageDef>> nameMap = new HashMap<>();
+ List<ITestPackageDef> testPackageDefList = new ArrayList<>();
+ testPackageDefList.add(mMockPackageDef);
+ nameMap.put(PACKAGE_NAME, testPackageDefList);
+
+ EasyMock.expect(mMockRepo.getTestPackageDefsByName()).andReturn(nameMap);
setCreateAndRunTestExpectations();
@@ -148,7 +161,12 @@
@SuppressWarnings("unchecked")
public void testRun_resume() throws DeviceNotAvailableException {
mCtsTest.addPackageName(PACKAGE_NAME);
+ Map<String, List<ITestPackageDef>> nameMap = new HashMap<>();
+ List<ITestPackageDef> testPackageDefList = new ArrayList<>();
+ testPackageDefList.add(mMockPackageDef);
+ nameMap.put(PACKAGE_NAME, testPackageDefList);
+ EasyMock.expect(mMockRepo.getTestPackageDefsByName()).andReturn(nameMap);
setCreateAndRunTestExpectations();
// abort the first run
EasyMock.expectLastCall().andThrow(new DeviceNotAvailableException());
@@ -245,7 +263,7 @@
/**
* Set EasyMock expectations for parsing {@link #PLAN_NAME}
*/
- private void setParsePlanExceptations() throws ParseException {
+ private void setParsePlanExpectations() throws ParseException {
mCtsTest.setPlanName(PLAN_NAME);
mMockPlan.parse((InputStream) EasyMock.anyObject());
EasyMock.expect(mMockPlan.getTestIds()).andReturn(IDS);
@@ -260,10 +278,9 @@
private void setCreateAndRunTestExpectations() throws DeviceNotAvailableException {
EasyMock.expect(mMockRepo.getPackageNames()).andReturn(NAMES).anyTimes();
EasyMock.expect(mMockRepo.getPackageIds()).andReturn(IDS).anyTimes();
- EasyMock.expect(mMockRepo.getTestPackages(PACKAGE_NAME)).andReturn(mMockPackageDefs).anyTimes();
EasyMock.expect(mMockRepo.getTestPackage(ID)).andReturn(mMockPackageDef).anyTimes();
EasyMock.expect(mMockPackageDef.createTest((File) EasyMock.anyObject())).andReturn(mMockTest);
- EasyMock.expect(mMockPackageDef.getTests()).andReturn(new ArrayList<TestIdentifier>());
+ EasyMock.expect(mMockPackageDef.getTests()).andReturn(TEST_IDENTIFIER_LIST).times(2);
EasyMock.expect(mMockPackageDef.getName()).andReturn(PACKAGE_NAME).atLeastOnce();
EasyMock.expect(mMockPackageDef.getAbi()).andReturn(UnitTests.ABI).atLeastOnce();
EasyMock.expect(mMockPackageDef.getId()).andReturn(ID).atLeastOnce();
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
index 5591b65..6d87a61 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/TestPackageXmlParserTest.java
@@ -16,29 +16,28 @@
package com.android.cts.tradefed.testtype;
-import com.android.cts.tradefed.command.CtsConsole;
import com.android.cts.util.AbiUtils;
import com.android.ddmlib.testrunner.TestIdentifier;
import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
+import junit.framework.TestCase;
+
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Iterator;
-import junit.framework.TestCase;
-
/**
* Unit tests for {@link TestPackageXmlParser}.
*/
public class TestPackageXmlParserTest extends TestCase {
- private static String INSTR_TEST_DATA =
+ private static final String INSTR_TEST_DATA =
"<TestPackage AndroidFramework=\"Android 1.0\" appNameSpace=\"com.example\" " +
"appPackageName=\"android.example\" name=\"CtsExampleTestCases\" " +
"runner=\"android.test.InstrumentationTestRunner\" version=\"1.0\">" +
"</TestPackage>";
- private static String HOST_TEST_DATA =
+ private static final String HOST_TEST_DATA =
"<TestPackage hostSideOnly=\"true\" >\n" +
" <TestSuite name=\"com\" >\n" +
" <TestSuite name=\"example\" >\n" +
@@ -55,23 +54,22 @@
" </TestSuite>\n" +
"</TestPackage>";
- private static String BAD_HOST_TEST_DATA =
+ private static final String BAD_HOST_TEST_DATA =
"<TestPackage hostSideOnly=\"blah\" >" +
"</TestPackage>";
- private static String VM_HOST_TEST_XML = "<TestPackage vmHostTest=\"true\"></TestPackage>";
+ private static final String VM_HOST_TEST_XML =
+ "<TestPackage vmHostTest=\"true\"></TestPackage>";
- private static String NATIVE_TEST_XML = "<TestPackage testType=\"native\"></TestPackage>";
+ private static final String NATIVE_TEST_XML = "<TestPackage testType=\"native\"></TestPackage>";
- private static String NO_TEST_DATA =
- "<invalid />";
+ private static final String NO_TEST_DATA = "<invalid />";
/**
* Test parsing test case xml containing an instrumentation test definition.
*/
public void testParse_instrPackage() throws ParseException {
- TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
- true);
+ TestPackageXmlParser parser = new TestPackageXmlParser(true);
parser.parse(getStringAsStream(INSTR_TEST_DATA));
for (TestPackageDef def : parser.getTestPackageDefs()) {
assertEquals("com.example", def.getAppNameSpace());
@@ -85,8 +83,7 @@
* Test parsing test case xml containing an host test attribute and test data.
*/
public void testParse_hostTest() throws ParseException {
- TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
- true);
+ TestPackageXmlParser parser = new TestPackageXmlParser(true);
parser.parse(getStringAsStream(HOST_TEST_DATA));
for (TestPackageDef def : parser.getTestPackageDefs()) {
assertEquals(TestPackageDef.HOST_SIDE_ONLY_TEST, def.getTestType());
@@ -110,8 +107,7 @@
}
public void testParse_hostTest_noKnownFailures() throws ParseException {
- TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
- false);
+ TestPackageXmlParser parser = new TestPackageXmlParser(false);
parser.parse(getStringAsStream(HOST_TEST_DATA));
for (TestPackageDef def : parser.getTestPackageDefs()) {
assertEquals(TestPackageDef.HOST_SIDE_ONLY_TEST, def.getTestType());
@@ -134,8 +130,7 @@
* Test parsing test case xml containing an invalid host test attribute.
*/
public void testParse_badHostTest() throws ParseException {
- TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
- true);
+ TestPackageXmlParser parser = new TestPackageXmlParser(true);
parser.parse(getStringAsStream(BAD_HOST_TEST_DATA));
for (TestPackageDef def : parser.getTestPackageDefs()) {
assertFalse(TestPackageDef.HOST_SIDE_ONLY_TEST.equals(def.getTestType()));
@@ -151,8 +146,7 @@
}
private void assertTestType(String expectedType, String xml) throws ParseException {
- TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
- true);
+ TestPackageXmlParser parser = new TestPackageXmlParser(true);
parser.parse(getStringAsStream(xml));
for (TestPackageDef def : parser.getTestPackageDefs()) {
assertEquals(expectedType, def.getTestType());
@@ -163,8 +157,7 @@
* Test parsing a test case xml with no test package data.
*/
public void testParse_noData() throws ParseException {
- TestPackageXmlParser parser = new TestPackageXmlParser(AbiUtils.getAbisSupportedByCts(),
- true);
+ TestPackageXmlParser parser = new TestPackageXmlParser(true);
parser.parse(getStringAsStream(NO_TEST_DATA));
assertTrue(parser.getTestPackageDefs().isEmpty());
}
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 9d0a5ff..4d04e1a 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -252,18 +252,6 @@
plan = tools.TestPlan(packages)
plan.Exclude('.*')
- plan.Include(r'android\.core\.tests\.libcore\.')
- plan.Include(r'android\.jdwp')
- for package, test_list in small_tests.iteritems():
- plan.Exclude(package+'$')
- for package, test_list in medium_tests.iteritems():
- plan.Exclude(package+'$')
- for package, tests_list in new_test_packages.iteritems():
- plan.Exclude(package+'$')
- self.__WritePlan(plan, 'CTS-ART')
-
- plan = tools.TestPlan(packages)
- plan.Exclude('.*')
plan.Include(r'com\.drawelements\.')
self.__WritePlan(plan, 'CTS-DEQP')
@@ -357,6 +345,7 @@
def BuildCtsVettedNewPackagesList():
""" Construct a defaultdict that maps package names that is vetted for L. """
return {
+ 'android.JobScheduler' : [],
'android.core.tests.libcore.package.harmony_annotation' : [],
'android.core.tests.libcore.package.harmony_beans' : [],
'android.core.tests.libcore.package.harmony_java_io' : [],
@@ -383,6 +372,7 @@
'android.uiautomation' : [],
'android.uirendering' : [],
'android.webgl' : [],
+ 'com.drawelements.deqp.gles3' : [],
'com.drawelements.deqp.gles31' : []}
def BuildCtsFlakyTestList():